Python項目-----CMDB自動化資產掃描

一、項目介紹

1.項目介紹
本項目基於Django實現後臺管理,nmap 識別網絡上的主機、使用telnet命令探測主機SSH端口存活掃描、使用paramiko對遠程服務器進行命令或文件操作。最終實現Web形式的自動化資產掃描系統,可以通過IP來掃描到所對應主機的詳細信息。項目基於HTTP實現自動化任務接受和響應接口設計,基於MySQL用作的關係型數據存取。本次項目實戰就是用最短的時間、手把手地完成運維開發系統的開發實戰。

二、項目環境搭建

  • 創建Django項目devops,查看本地django版本,遠程服務器的虛擬環境django版本也需要爲2.2
    在這裏插入圖片描述

連接並配置遠程服務器

  • 連接並配置遠程服務器 [Tools] -> [Deployment]
    在這裏插入圖片描述
  • 配置本地目錄和遠程服務器目錄的映射(Mapping), 上述操作完成, 本地文件修改, 遠程服務器文件也同時修改.
    ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200525192533956.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0MjQxODYx,size_16,color_FFFFFF,t_70

遠程服務器虛擬環境的配置

  • 連接遠程服務器命令行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 = [’*’]
  1. 中文漢字時區的設置: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工程多配置文件

在這裏插入圖片描述

  1. base.py文件: 基本的配置文件,將原先seetings.py文件的內容拷貝進來
  2. development.py文件: 開發環境的配置文件
    from .base import *
    DEBUG = True
  3. production.py文件: 生產環境的配置文件
    from .base import *
    # 開發環境一定要關閉調試模式
    DEBUG = False
    # 允許所有主機訪問
    ALLOWED_HOSTS = [’*’]
  4. 修改manage.py文件, 默認尋找的設置文件是當前項目中的settings文件, 如果是開發環境, 修改如下:
    def main():
    os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
    'devops.settings.development’)
    #…此處省略代碼
    if name == ‘main’:
    main()
  5. 如果項目將來需要上線, 修改啓動項目訪問的配置文件爲生產環境的配置文件即可, 如下:
    def main():
    os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
    devops.settings.production’)
    # …此處省略代碼
    if name == ‘main’:
    main()
  6. 啓動項目的後臺展示
    在這裏插入圖片描述

五、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瀏覽器頁面無法訪問原因:
  1. 目前8000端口只和127.0.0.1這個IP綁定,只能通過127.0.0.1:8000在瀏覽器訪問,用其他的ip:8000訪問是失敗的,因爲其他ip與8000端口沒有關聯起來;因此用公網IP:port訪問瀏覽器不可能成功
  2. 而0.0.0.0:8000的意思:如果希望通過任意一個IP訪問8000端口,每一臺主機都會有多個IP,讓8000端口和當前主機的任意一個IP(0.0.0.0)綁定在一起, 包含公網IP,因此公網IP:8000纔可以從瀏覽器訪問。
  3. 本機測試不指定 生產環境需要指定爲0.0.0.0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章