文章目錄
一、項目介紹
1.項目介紹
本項目基於Django實現後臺管理,nmap 識別網絡上的主機、使用telnet命令探測主機SSH端口存活掃描、使用paramiko對遠程服務器進行命令或文件操作。最終實現Web形式的自動化資產掃描系統,可以通過IP來掃描到所對應主機的詳細信息。項目基於HTTP實現自動化任務接受和響應接口設計,基於MySQL用作的關係型數據存取。本次項目實戰就是用最短的時間、手把手地完成運維開發系統的開發實戰。
二、項目環境搭建
- 創建Django項目devops,查看本地django版本,遠程服務器的虛擬環境django版本也需要爲2.2
連接並配置遠程服務器
- 連接並配置遠程服務器 [Tools] -> [Deployment]
- 配置本地目錄和遠程服務器目錄的映射(Mapping), 上述操作完成, 本地文件修改, 遠程服務器文件也同時修改.
遠程服務器虛擬環境的配置
- 連接遠程服務器命令行bash
- 創建虛擬環境並激活虛擬環境
- `cd /data/www/devops
- virtualenv -p /usr/bin/python3 env
遇到的問題:換了一個雲服務器後,虛擬環境沒有安裝,因此需要先pip3 install virtualenv- source env/bin/active
- pip install django==2.2 -i https://pypi.douban.com/simple` 安裝虛擬環境需要的django
遠程服務器解釋器和目錄映射的配置
- 項目在遠程創建,因此本地虛擬環境應該修改爲遠程python虛擬環境 settings中設置
- 虛擬環境使用項目下的虛擬環境
- 上傳項目:把本地項目和遠程服務器關聯
三、MySQL數據庫配置
- 遠程服務器虛擬環境下安裝數據庫:
- 用戶授權:讓任意主機的指定用戶可以訪問
- ` create database if not exists devopsProject default charset utf8;
- MariaDB [(none)]> create user devops@’%’ identified by ‘123’;
- MariaDB [(none)]> grant all on devpsProject.* to devops@’%’;
- 測試:mysql -udevops -p123`
- 測試用戶授權是否成功
- 遇到的問題:阿里雲 數據庫無法登錄
- 報錯信息:Access denied for user ‘root’@‘localhost’ (using password: YES)
- 1)修改密碼 mysql–> use mysql; --> update user set authentication_string=password(‘新密碼’) where user=‘root’;—>flush privilage;(不建議使用)
- 2)阿里雲安全組對於mysql端口3306的設置
- 3) 終端關閉防火牆
- 經過分析最終解決方法:
解決方法:本次的問題呢,mysql 可以登錄,但是mysql -uroot -p123不能登錄 說明是一開始安裝mysql設置密碼的問題,默認情況下-h不指定是連接本機的數據庫,如果連接遠程主機數據庫要通過-hIP指定;
mysql設置密碼:mysql_secure_installation來初始化設置密碼。修改密碼才能進入mysql數據庫中設置。
Django數據庫配置
- 修改配置文件的信息:Settings 數據庫設置爲mysql 、中文漢字時區的設置
注意:settings中allowhost中必須加入外網ip 47.92.233.236,或者直接ALLOWED_HOSTS = [’*’]
- 中文漢字時區的設置:
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'
- 生成數據庫表
操作中遇到的問題:django2.2/mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
報錯環境 python=3.6,django=2.2,PyMySQL=0.9.3原因分析: Django連接MySQL時默認使用MySQLdb驅動,但MySQLdb不支持Python3,因此這裏將MySQL驅動設置爲pymysql,:django2.2和pymysql版本不匹配。使用 pip install pymysql 進行安裝,然後在工程文件__init__.py添加以下代碼即可。
具體做法:
#init.py
import pymysql
pymysql.install_as_MySQLdb()
django降到2.1.4版本就OK了
- 測試數據表是否創建?數據信息是否寫入?
連接mariadb數據庫> 配置數據庫信息
- 訪問數據庫表和數據內容
初次運行項目:查看後臺管理頁面
django後臺創建超級用戶
python manage.py createsuperuser
一切都設置好後,運行項目進入django後臺:
-
python manage.py runserver 0.0.0.0:8000
問題:網頁輸入外網ip:8000無法訪問是因爲公網ip的安全組端口沒有設置8000
頁面展示:
四、Django工程多配置文件
- base.py文件: 基本的配置文件,將原先seetings.py文件的內容拷貝進來
- development.py文件: 開發環境的配置文件
from .base import *
DEBUG = True- production.py文件: 生產環境的配置文件
from .base import *
# 開發環境一定要關閉調試模式
DEBUG = False
# 允許所有主機訪問
ALLOWED_HOSTS = [’*’]- 修改manage.py文件, 默認尋找的設置文件是當前項目中的settings文件, 如果是開發環境, 修改如下:
def main():
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
'devops.settings.development’)
#…此處省略代碼
if name == ‘main’:
main()- 如果項目將來需要上線, 修改啓動項目訪問的配置文件爲生產環境的配置文件即可, 如下:
def main():
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
‘devops.settings.production’)
# …此處省略代碼
if name == ‘main’:
main()- 啓動項目的後臺展示
五、Django工程應用與模塊加載
爲了方便在一個大的Django項目中,管理實現不同的業務功能, 我們會在項目中創建多個APP實現功能。爲了更加方便管理APP, 項目結構更加清晰。可以專門創建apps目錄存儲項目應用, 專門創建extra_apps存儲項目第三方APP, 項目結構如下所示:
- 但項目運行時, 不會自動尋找apps和extra_apps子目錄中創建的APP, 創建子應用方法如下:
遠程服務器創建好後download到本地
鼠標先選擇要從遠程服務器下載的文件,tools的development中選擇download from devops 就可以啦
- 子應用的加載
base下:
六、主機存活探測模塊和工具
Nmap探測工具
Nmap,也就是Network Mapper,最早是Linux下的網絡掃描和嗅探工具包。是一款用於網絡發現和安全審計的網絡安全工具。
功能:
- 主機發現 - 識別網絡上的主機。例如,列出響應TCP和/或ICMP請求或打開特定端口的主機。
nmap -n -sP 172.25.254.197 掃描某一個IP是否存活
nmap -n -sP 172.25.254.0/24 掃描某一個局域網下哪些主機存活
- 端口掃描 - 枚舉目標主機上的開放端口。(不常用)
$ nmap -n -p 172.25.254.197
#具體指定要掃描的端口爲50-80
$ nmap -n -p50-80 172.25.254.197
#具體指定要掃描的端口爲22和80
$ nmap -n -p22,80 172.25.254.197
- OS檢測 - 確定網絡設備的操作系統和硬件特性。
# -O是檢測操作系統交換機
$ nmap -O 172.25.254.197
Nmap的Python操作接口: python-nmap
python-nmap是一個使用nmap進行端口掃描的python庫,它可以很輕易的生成nmap掃描報告,並且可以幫助系統管理員進行自動化掃描任務和生成報告。同時,它也支持nmap腳本輸出。
- 具體的代碼調用如下:
import nmap
# 實例化對象, portScanner()類用於實現對指定主機進行端口掃描
nm = nmap.PortScanner()
# 以指定方式掃描指定主機或網段的指定端口
result = nm.scan(hosts='172.25.254.0/24', arguments='-n -sP')
print("掃描結果: ", result)
# 返回的掃描具體的nmap命令行
print("nmap命令行: ", nm.command_line())
# 返回nmap掃描的主機清單,格式爲列表類型
print("主機清單: ", nm.all_hosts())
# 查看指定主機信息
print('172.25.254.197的主機信息: ', nm['172.25.254.197'])
代碼執行效果如下圖所示:
掃描結果:
{'nmap': {'command_line': 'nmap -oX - -n -sP 172.25.254.0/24', 'scaninfo': {},
'scanstats': {'timestr': 'Wed Dec 25 16:14:47 2019', 'elapsed': '6.06',
'uphosts': '2', 'downhosts': '254', 'totalhosts': '256'}}, 'scan':
{'172.25.254.197': {'hostnames': [{'name': '', 'type': ''}], 'addresses':
{'ipv4': '172.25.254.197'}, 'vendor': {}, 'status': {'state': 'up', 'reason':
'syn-ack'}}, '172.25.254.250': {'hostnames': [{'name': '', 'type': ''}],
'addresses': {'ipv4': '172.25.254.250'}, 'vendor': {}, 'status': {'state': 'up',
'reason': 'syn-ack'}}}}
nmap命令行: nmap -oX - -n -sP 172.25.254.0/24
主機清單: ['172.25.254.197', '172.25.254.250']
172.25.254.197的主機信息:
{'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4':
'172.25.254.197'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'syn-ack'}}
操作中的報錯總結:
一、
- 雲服務器虛擬環境下:pip install python-nmap 報錯:
- 報錯信息: pip: command not found…
- 解決方法:
$ wget https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py
二、
雲服務器虛擬環境下:pip install python-nmap
之後pycharm文件中import nmap
無法導入時:查看解釋器環境是否正確
七、SSH端口存活掃描
使用telnet命令探測主機列表是否屬於Linux服務器。
- telnetlib模塊探測 telnetlib模塊提供的Telnet類實現了Telnet協議。
telnetlib模塊提供的Telnet類實現了Telnet協議。
import telnetlib
import re
# 實例化對象
tn = telnetlib.Telnet(host='172.25.254.197', port=22, timeout=5)
# read_until讀取直到遇到了換行符或超時秒數。默認返回bytes類型,通過decode方法解碼爲字符
串。
tn_result = tn.read_until(b"\n", timeout=5).decode('utf-8')
# 通過正則匹配且忽略大小寫, 尋找是否ssh服務開啓。
ssh_result = re.search(pattern=r'ssh', string=tn_result, flags=re.I)
# 如果能匹配到內容, 說明ssh服務開啓, 是Linux服務器.
if ssh_result:
print("Linux服務器存活")
else:
print("其他服務器存活")
代碼執行結果如下:
Linux服務器存活
掃描探測小結
八、Python的SSH登錄模塊paramiko
-
什麼是主機登錄探測?
用一系列的驗證方式循環進行SSH登錄, 得到爭取的登錄方式。 -
主機SSH登錄驗證方式
SSH常用來遠程登錄到遠程機器,有兩種常用的方法:
第一種便是賬號密碼登錄。
第二種就是公鑰私鑰無密碼登錄。(如何實現無密碼登錄?) -
什麼是paramiko?
paramiko是一個用於做遠程控制的模塊,使用該模塊可以對遠程服務器進行命令或文件操作,paramiko是用python語言寫的一個模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的連接。 -
如何安裝paramiko?
# 使用豆瓣的鏡像源, 安裝paramiko模塊並指定安裝版本爲2.6.0.
$ pip install -i https://pypi.douban.com/simple paramiko==2.6.0
-
paramiko核心組件
paramiko包含兩個核心組件:SSHClient和SFTPClient。
SSHClient的作用類似於Linux的ssh命令,是對SSH會話的封裝,該類封裝了傳輸(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用於執行遠程命令。
SFTPClient的作用類似與Linux的sftp命令,是對SFTP客戶端的封裝,用以實現遠程文件操作,如文件上傳、下載、修改文件權限等操作。 -
項目代碼: 基於paramiko實現ssh客戶端密鑰遠程登錄
- 客戶端連接服務端公鑰私鑰:
- 測試之前生成公鑰和私鑰進行測試 :
- 本次測試將公鑰分發給本機的root用戶,
ssh-copy-id -i ~/.ssh/id_rsa.pub root@localhost
分發公鑰時需要輸入密碼,此密碼爲root用戶可以登錄本機的密碼,也就是root可以登錄47.92.233.236的密碼;- 測試:
[root@docker .ssh]# ssh root@localhost
可以實現無密碼登錄
pyhon代碼實現公鑰和私鑰的無密碼連接 :
def login_ssh_key( hostname='172.25.254.197', keyfile='./id_rsa',
username='root', port=22, command='df -h'):
"""
基於paramiko實現ssh的自動化密鑰管理
"""
# 配置私人密鑰文件位置
private = paramiko.RSAKey.from_private_key_file(keyfile)
# 實例化SSHClient
with paramiko.SSHClient() as client:
# 自動添加策略,保存服務器的主機名和密鑰信息,如果不添加,那麼不再本地
know_hosts文件中記錄的主機將無法連接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接SSH服務端,以用戶名和密碼進行認證
client.connect(hostname=hostname, port=port, username=username,
pkey=private)
# 打開一個Channel並執行命令。 stdout 爲正確輸出,stderr爲錯誤輸出,同時是有1
個變量有值
stdin, stdout, stderr = client.exec_command(command)
# 打印執行結果
print(stdout.read().decode('utf-8'))
if __name__ == '__main__':
# login_ssh_passwd(hostname='127.0.0.1', command='hostname')
login_ssh_key(hostname='127.0.0.1', command='hostname')
運行結果:foundation0.ilt.example.com
九、系統信息獲取
- 通過系統獲取哪些信息
- 獲取信息的Linux命令介紹
獲取主機名的命令(選擇通用方式): hostname、uname -a、cat /etc/sysconfig/network(主 要針對Centos)
獲取系統版本: cat /etc/issue(可能爲空)、cat /etc/redhat-release、uname、 lsb_release
獲取MAC地址: cat /sys/class/net/ [^vtlsb] */address、ifconfig ens33
獲取服務器硬件機型: dmidecode -s system-manufacturer、dmidecode -s systemproduct-name
十、項目的大體規劃
前面說了這麼多,現在就真正進入佈局階段了,Django數據庫模型設計、配置文件設置、視圖函數、路由配置、後臺admin管理請看代碼鏈接:Django_CMDB_code
- 最後的測試階段:運行項目
python manage.py runserver 0.0.0.0:8000
- 訪問網址http://ip:port/scan 查看掃描結果
- 訪問網址http://ip:port/admin 查看後臺管理
- 測試遇到的疑惑:
- 在雲服務器下的虛擬環境中輸入 python manage.py runserver 0.0.0.0:8000可以訪問,只輸入python manage.py runserver瀏覽器頁面無法訪問原因:
- 目前8000端口只和127.0.0.1這個IP綁定,只能通過127.0.0.1:8000在瀏覽器訪問,用其他的ip:8000訪問是失敗的,因爲其他ip與8000端口沒有關聯起來;因此用公網IP:port訪問瀏覽器不可能成功
- 而0.0.0.0:8000的意思:如果希望通過任意一個IP訪問8000端口,每一臺主機都會有多個IP,讓8000端口和當前主機的任意一個IP(0.0.0.0)綁定在一起, 包含公網IP,因此公網IP:8000纔可以從瀏覽器訪問。
- 本機測試不指定 生產環境需要指定爲0.0.0.0