Python运维(六)--系统监控psutil、数据报scapy、扫描nmap
生活随笔
收集整理的這篇文章主要介紹了
Python运维(六)--系统监控psutil、数据报scapy、扫描nmap
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 一、系統監控psutil
- 1.1 cpu監控
- 1.2 內存
- 1.3 磁盤
- 1.4 進程
- 1.4.1 進程查詢
- 1.4.2 進程修改
- 二、網絡嗅探器scapy
- 2.1 命令行操作
- 2.2 數據報構造簡介
- 2.2.1 按層構建數據報
- 2.2.2 發送數據報
- 2.3 ARP掃描網段存活主機
- 三、使用python-nmap
- 3.1 nmap命令
- 3.2 python-nmap
一、系統監控psutil
- 安裝:pip3 install psutil
1.1 cpu監控
- 代碼示例In [1]: import psutil # 獲取cpu邏輯個數 In [2]: psutil.cpu_count() Out[2]: 2 # 獲取cpu物理個數 In [3]: psutil.cpu_count(logical=False) Out[3]: 2 # cpu使用百分比 In [4]: psutil.cpu_percent() Out[4]: 11.7
1.2 內存
- 代碼示例# 獲取內存的所有信息 In [1]: psutil.virtual_memory() Out[1]: svmem(total=1927233536, available=1256218624, percent=34.8, used=403361792, free=166739968, active=699125760, inactive=532242432, buffers=2154496, cached=1354977280, shared=75677696, slab=409309184) # 獲取交換內存 In [2]: psutil.swap_memory() Out[2]: sswap(total=2147479552, used=532480, free=2146947072, percent=0.0, sin=0, sout=434176) # 獲取內存使用率 In [3]: psutil.virtual_memory().percent Out[3]: 34.8
1.3 磁盤
- 代碼示例# 獲取磁盤分區及掛載點 In [1]: psutil.disk_partitions() Out[1]: [sdiskpart(device='/dev/mapper/centos-root', mountpoint='/', fstype='xfs', opts='rw,relatime,attr2,inode64,noquota', maxfile=255, maxpath=4096),... ] # 通過掛載點查看磁盤使用情況:單位字節 In [2]: psutil.disk_usage("/") Out[2]: sdiskusage(total=53660876800, used=4668542976, free=48992333824, percent=8.7) # 通過掛載點查看磁盤使用率 In [3]: psutil.disk_usage("/").percent Out[3]: 8.7
1.4 進程
1.4.1 進程查詢
-
查詢列表
功能寫法功能寫法 所有進程的PID列表 psutil.pids() 進程生成器(見下演示) psutil.process_iter() 進程名 p.name() 進程的可執行絕對路徑 p.exe() 進程當前的工作目錄 p.cwd() 調用此進程的命令行 p.cmdline() 進程PID p.pid 進程的父PID p.ppid() 進程的子進程 p.children() 進程的父進程(對象) p.parent() 進程的父進程(列表) p.parents() 進程的狀態 p.status() 擁有該進程的用戶 p.username() 進程創建的時間 p.create_time() 進程累計的時間 p.cpu_times() 進程的CPU占用率 p.cpu_percent() 進程的CPU親和性 p.cpu_affinity() 進程的內存信息 p.memory_info() 進程的內存占用率 p.memory_percent() 進程映射的內存區域 p.memory_maps() 進程的I/O信息 p.io_counters() 進程打開的文件信息 p.open_files() 進程打開的套接字連接 p.connections() 進程使用的線程數 p.num_threads() 進程打開的線程 p.threads() 進程執行的上下文切換數量 p.num_ctx_switches() 進程的優先級(帶參可設優先級) p.nice() 進程的I/O優先級(帶參可設優先級) p.ionice() 進程的環境變量 p.environ() 進程信息(字典) p.as_dict() 進程是否正在運行 p.is_running() -
效果演示
In [1]: import psutilIn [2]: pid_list = psutil.pids() In [3]: print("所有進程的PID列表:",pid_list) 所有進程的PID列表:[1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, .....]In [4]: p = psutil.Process(18449)In [5]: print(p) psutil.Process(pid=18449, name='top', status='sleeping', started='09:24:28')In [6]: print("進程名:", p.name()) 進程名: topIn [7]: print("進程的可執行絕對路徑:", p.exe()) 進程的可執行絕對路徑: /usr/bin/topIn [8]: print("進程當前的工作目錄:", p.cwd()) 進程當前的工作目錄: /rootIn [9]: print("調用此進程的命令行:", p.cmdline()) 調用此進程的命令行: ['top']In [10]: print("進程PID:", p.pid) 進程PID: 18449In [11]: print("進程的父PID:", p.ppid()) 進程的父PID: 18272In [12]: print("進程的子進程:", p.children()) 進程的子進程: []In [13]: print("進程的父進程(對象):", p.parent()) 進程的父進程(對象): psutil.Process(pid=18272, name='bash', status='sleeping', started='09:24:26')In [14]: print("進程的父進程(列表):", p.parents()) 進程的父進程(列表): [psutil.Process(pid=18272, name='bash', status='sleeping', started='09:24:26'), ...]In [15]: print("進程的狀態:", p.status()) 進程的狀態: sleepingIn [16]: print("擁有該進程的用戶:", p.username()) 擁有該進程的用戶: rootIn [17]: print("進程創建的時間:", p.create_time()) 進程創建的時間: 1655342668.64In [18]: print("進程進駐cpu累計的時間:", p.cpu_times()) 進程進駐cpu累計的時間: pcputimes(user=0.73, system=1.29, children_user=0.0, children_system=0.0, iowait=0.0)In [19]: print("進程的CPU占用率:", p.cpu_percent()) 進程的CPU占用率: 0.0In [20]: print("進程的CPU親和性:", p.cpu_affinity()) 進程的CPU親和性: [0, 1]In [21]: print("進程的內存信息:", p.memory_info()) 進程的內存信息: pmem(rss=3133440, vms=166739968, shared=1622016, text=98304, lib=0, data=1937408, dirty=0)In [22]: print("進程的內存占用率:", p.memory_percent()) 進程的內存占用率: 0.1625874571746763In [23]: print("進程映射的內存區域:", p.memory_maps()) 進程映射的內存區域: [pmmap_grouped(path='/usr/bin/top', rss=94208, size=110592, pss=94208, shared_clean=0, shared_dirty=0, private_clean=81920, private_dirty=12288, referenced=94208, anonymous=12288, swap=0), ...]In [24]: print("進程的I/O信息:", p.io_counters()) 進程的I/O信息: pio(read_count=54669, write_count=2169, read_bytes=0, write_bytes=0, read_chars=7752773, write_chars=4272652)In [25]: print("進程打開的文件信息:", p.open_files()) 進程打開的文件信息: [popenfile(path='/proc/stat', fd=4, position=1250, mode='r', flags=32768), ...]In [26]: print("進程打開的套接字連接:", p.connections()) 進程打開的套接字連接: []In [27]: print("進程使用的線程數:", p.num_threads()) 進程使用的線程數: 1In [28]: print("進程打開的線程:", p.threads()) 進程打開的線程: [pthread(id=18449, user_time=0.74, system_time=1.31)]In [29]: print("進程執行的上下文切換數量:", p.num_ctx_switches()) 進程執行的上下文切換數量: pctxsw(voluntary=706, involuntary=676)In [30]: print("進程的優先級(帶參數則可設置優先級):", p.nice()) 進程的優先級(帶參數則可設置優先級): 0In [31]: print("進程的I/O優先級(帶參數則可設置優先級):", p.ionice()) 進程的I/O優先級(帶參數則可設置優先級): pionice(ioclass= <IOPriority.IOPRIO_CLASS_NONE: 0>, value=4)In [32]: print("進程的環境變量:", p.environ()) 進程的環境變量: {'XDG_SESSION_ID': '1348', 'HOSTNAME': 'localhost.localdomain', 'TERM': 'xterm', 'SHELL': '/bin/bash', 'HISTSIZE': '1000', 'SSH_CLIENT': '10.10.10.13 9858 22', 'SSH_TTY': '/dev/pts/1', 'LC_ALL': 'en_US', 'QT_GRAPHICSSYSTEM_CHECKED': '1', 'USER': 'root', ...}In [33]: print("進程信息(字典):", p.as_dict()) 進程信息(字典): {'memory_percent': 0.1625874571746763, 'cpu_times': pcputimes(user=0.74, system=1.31, children_user=0.0, children_system=0.0, iowait=0.0), ...}In [34]: print("進程是否正在運行:", p.is_running()) 進程是否正在運行: True -
迭代查找指定屬性進程
# 方法一:指定屬性格式 In [35]: for p in psutil.process_iter(attrs=['pid', 'name']):...: if 'top' in p.info['name']:...: print(p.info)...: {'name': 'top', 'pid': 18449}# 方法二:萬金流方法 In [36]: for p in psutil.process_iter(): ...: if 'top' == p.name(): ...: print(p.pid) ...: 18449
1.4.2 進程修改
- 操作# 暫停掛起進程 p.suspend() # 恢復進程 p.resume()# 結束進程:正常結束并退出進程,包括依次結束子進程等 p.terminate() # 強制結束進程:暴力結束進程,不管子進程 p.kill()
二、網絡嗅探器scapy
- 概述:使用scary可以發送、嗅探、剖析和偽造網絡數據報,直接操作網絡二三四層數據報
- 安裝:pip3 install scapy
2.1 命令行操作
- 顯示scapy命令及配置[root@localhost ~]# scapy # 顯示支持的協議 >>> ls() # 顯示支持的命令 >>> lsc() # 顯示所有配置信息 >>> conf # 顯示命令的幫助信息 >>> help(sniff) # 查看協議包含的參數 >>> ls(TCP) sport : ShortEnumField = ('20') dport : ShortEnumField = ('80') seq : IntField = ('0') ack : IntField = ('0') dataofs : BitField (4 bits) = ('None') reserved : BitField (3 bits) = ('0') flags : FlagsField = ('<Flag 2 (S)>') window : ShortField = ('8192') chksum : XShortField = ('None') urgptr : ShortField = ('0') options : TCPOptionsField = ("b''")
- 查詢網卡信息>>> show_interfaces() Source Index Name MAC IPv4 IPv6 sys 1 lo 00:00:00:00:00:00 127.0.0.1 ::1 sys 2 eth0 02:11:31:20:b7:70 192.168.1.110 fe80::3381:a2a6:492f:5757 sys 3 zttftqv4vg 8e:b2:2b:5b:34:4c 10.10.10.10 fe80::8cb2:3bff:fe2b:344c sys 4 br-4913d28cc615 02:42:c2:38:a8:2b 172.19.0.1 sys 5 br-4c5033b4000b 02:42:21:a8:68:1b 172.18.0.1 sys 6 docker0 02:42:22:22:ce:d3 172.17.0.1
- 獲取路由表# scapy內本機路由表(centos通過命令route -n查看) >>> conf.route Network Netmask Gateway Iface Output IP Metric 0.0.0.0 0.0.0.0 192.168.1.1 eth0 192.168.1.120 100 127.0.0.0 255.0.0.0 0.0.0.0 lo 127.0.0.1 1 192.168.1.0 255.255.255.0 0.0.0.0 eth0 192.168.1.120 100 # 增加路由(不會修改主機路由表,退出scapy也恢復主機路由表) >>> conf.route.add(net="192.168.2.0/24",gw="192.168.1.2") >>> conf.route Network Netmask Gateway Iface Output IP Metric 0.0.0.0 0.0.0.0 192.168.1.1 eth0 192.168.1.120 100 127.0.0.0 255.0.0.0 0.0.0.0 lo 127.0.0.1 1 192.168.1.0 255.255.255.0 0.0.0.0 eth0 192.168.1.120 100 192.168.2.0 255.255.255.0 192.168.1.2 eth0 192.168.1.120 1 # 刪除路由:恢復原狀(不會修改主機路由表) >>> conf.route.delt(net="192.168.2.0/24",gw="192.168.1.2")
2.2 數據報構造簡介
2.2.1 按層構建數據報
- 代碼示例# 網絡二層:鏈路層 >>> l2 = Ether() # 網絡三層:網絡層 IP協議 >>> l3 = IP(dst='192.168.1.1/30') # 網絡四層:傳輸層 TCP協議,半開掃描(SYN)的辦法,標識‘S’ >>> l4 = TCP(dport=22, flags = 'S') # 組合數據報:各層從下向上用/組合數據報,未寫scapy自動補充 >>> packet = l2/l3/l4# 顯示 層數據報 的報頭信息 >>> l2.show() ###[ Ethernet ]### dst = ff:ff:ff:ff:ff:ffsrc = 02:11:32:20:b7:70type = LOOP>>> l3.show() ###[ IP ]### version = 4ihl = Nonetos = 0x0len = Noneid = 1flags = frag = 0ttl = 64proto = hopoptchksum = Nonesrc = 192.168.1.120dst = Net("192.168.1.1/30")\options \>>> l4.show() ###[ TCP ]### sport = ftp_datadport = sshseq = 0ack = 0dataofs = Nonereserved = 0flags = Swindow = 8192chksum = Noneurgptr = 0options = ''
2.2.2 發送數據報
- send發送(第三層網絡層發送,不接收響應)# 從第三層網絡層發送一個數據報:若192.168.1.1/24,則每個ip發一個數據報
# 目標地址本機,發送一個icmp包,不接收響應數據包
# 每個點為一個數據報
>>> send(IP(dst="127.0.0.1")/ICMP())
.
Sent 1 packets.
---------------------------------------------------------------
# 目標地址本機80端口,發送10個tcp包,不接收響應數據包
>>> send(IP(dst='127.0.0.1')/TCP(dport=80, flags='S'), count=10)
..........
Sent 10 packets.
---------------------------------------------------------------
# 目標地址本機80端口,循環發送tcp包,不接收響應數據包,知道Ctrl+C退出
>>> send(IP(dst='127.0.0.1')/TCP(dport=80, flags='S'), loop=1)
.......................^C
Sent 22 packets.
功能:網絡攻擊用的,只負責發,不關心響應,目的為耗盡靶機網絡資源
- sendp發送(第二層鏈路層發送,不接收響應)# 用法同send():唯一區別在于從第二層鏈路層發送數據報 # TTL是IP數據包在計算機網絡中可以轉發的最大跳數,此處元組代表5,6,7 # iface:網卡名稱 # inter:數據報發送間隔0.2秒 >>> sendp(Ether()/IP(dst="8.8.8.8",ttl=(5,7)), iface="eth0", inter=0.2) ... Sent 3 packets.
- sr發送(第三層網絡層發送,接收響應)# 第三層網絡層發送數據包并接收響應 # sr函數返回:響應列表ans,未響應列表unans >>> ans,unans = sr(IP(dst="159.75.78.150")/TCP(dport=[21,22,23])) Begin emission: Finished sending 3 packets. .....*............^C Received 54 packets, got 1 answers, remaining 2 packets # 顯示數據包簡短的摘要 >>> ans.summary()IP / TCP 192.168.1.120:ftp_data > 159.75.78.150:ssh S ==> IP / TCP 159.75.78.150:ssh > 192.168.1.120:ftp_data SA / Padding>>> unans.summary()IP / TCP 192.168.1.120:ftp_data > 159.75.78.150:ftp SIP / TCP 192.168.1.120:ftp_data > 159.75.78.150:telnet S
- sr1發送(第三層網絡層發送,接收且僅接收第一個響應)>>> p=sr1(IP(dst="www.baidu.com")/ICMP()) Begin emission: Finished sending 1 packets. ...* Received 4 packets, got 1 answers, remaining 0 packets >>> p.summary() 'IP / ICMP 183.232.231.174 > 192.168.1.120 echo-reply 0 / Padding'
- srloop發送(循環發送,隨發隨顯)>>> srloop(IP(dst='192.168.1.102')/ICMP()) RECV 1: IP / ICMP 192.168.1.102 > 192.168.1.120 echo-reply 0 / Padding RECV 1: IP / ICMP 192.168.1.102 > 192.168.1.120 echo-reply 0 / Padding ^C Sent 10 packets, received 10 packets. 100.0% hits. (<Results: TCP:0 UDP:0 ICMP:10 Other:0>, <PacketList: TCP:0 UDP:0 ICMP:0 Other:0>)
2.3 ARP掃描網段存活主機
- scan_pc.py#!/usr/bin/python3 # -*- coding=utf-8 -*-# 局域網主機掃描器 使用ARP掃描 from scapy.all import * from scapy.layers.l2 import Ether, ARPdef arp_scan(ifname, network):# 構造數據包:Ether()層可以省略構造內容,此為默認值,可寫上加快速度p = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=network) / "text"# srp()用于第二層鏈路層發送和接收數據包:arp# 數據包發送后:ans有響應主機,unans沒有響應主機,五秒后統計結果ans, unans = srp(p, iface=ifname, timeout=5, verbose=False)print("共掃描{}個主機,{}個主機響應".format(len(unans), len(ans)))result = []# ans是元組的形式,可以測試ans[0],發現結果是元組的形式for s, r in ans:# 把目標的IP以及MAC地址加入到新的列表result.append([r[ARP].psrc, r[ARP].hwsrc]) result.sort() # 對列表進行排序# 遍歷列表,打印ip以及對應的mac地址for ip, mac in result:print("{}--->{}".format(ip, mac))if __name__ == '__main__':print(show_interfaces())print("若報錯OSError,請從上面選擇相應網段的網卡名回填程序eth_name變量")eth_name = "Realtek PCIe GbE Family Controller"arp_scan(eth_name, '192.168.1.0/24')
- 運行:python3 scan_pc.py
測試指定PC是否存活: python3 main.py | grep 192.168.1.134
- 返回Source Index Name MAC IPv4 libpcap 16 Realtek PCIe GbE Family Controller 1c:2b:0d:3d:48:52 192.168.1.102 若報錯OSError,請從上面選擇相應網段的網卡名回填程序eth_name變量 共掃描171個主機,85個主機響應 192.168.1.1--->f2:2c:23:bf:02:82 192.168.1.102--->1c:1b:1d:1d:18:12 192.168.1.107--->3c:3d:3b:38:3a:38
三、使用python-nmap
3.1 nmap命令
- 概述:主要用于掃描,安裝yum install nmap,以下在centos下測試
- 掃描1000個常用端口# SYN掃描,使用最頻繁,安全,快 >>> nmap -sS 192.168.1.102 # 掃描指定端口:nmap -sS 192.168.1.102 -p 80,443Starting Nmap 6.40 ( http://nmap.org ) at 2022-06-17 10:05 CST Nmap scan report for 192.168.1.102 Host is up (0.00032s latency). Not shown: 995 closed ports PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 1026/tcp open LSA-or-nterm 2179/tcp open vmrdp MAC Address: 1C:1B:0D:3D:88:11 (Unknown)Nmap done: 1 IP address (1 host up) scanned in 1.69 seconds
- ping方式檢測局域網主機# 不進行端口掃描:會發送四種報文確定目標是否存活 >>> nmap -sn 192.168.1.0/24Starting Nmap 6.40 ( http://nmap.org ) at 2022-06-17 10:10 CST Nmap scan report for 192.168.1.1 Host is up (0.00049s latency). MAC Address: F8:8C:21:BF:01:81 (Unknown) Nmap scan report for 192.168.1.6 Host is up (0.00054s latency). MAC Address: F4:B5:20:14:45:1F (Unknown) Nmap scan report for 192.168.1.7 Host is up (0.00081s latency). MAC Address: 48:4D:7E:C1:62:A0 (Unknown) ... Nmap done: 256 IP addresses (93 hosts up) scanned in 7.67 seconds
3.2 python-nmap
- 概述:封裝nmap命令,安裝pip3 install python-nmap(需先安裝nmap命令)
- 單語句結果測試In [1]: import nmap # 構造PortScanner對象 In [2]: nm = nmap.PortScanner() # scan( host , port , args ) 方法:以指定方式掃描指定主機或網段的指定端口 # 返回結果字典匯總信息: # ip寫法:192.168.1.1-50 或 192.168.1.1/24,默認127.0.0.1 # 端口寫法:22,80,443 或 22-80 或 22-80,443,默認None # arguments:默認-sV,其他同nmap # 其余參數:sudo=False, timeout=0 In [3]: nm.scan('192.168.1.120', '1-1000') Out[3]: {'nmap': {'command_line': 'nmap -oX - -p 1-1000 -sV 192.168.1.120','scaninfo': {'tcp': {'method': 'syn', 'services': '1-1000'}},'scanstats': {'timestr': 'Fri Jun 17 10:20:26 2022','elapsed': '89.73','uphosts': '1','downhosts': '1','totalhosts': '2'}},'scan': {'192.168.1.120': {'hostnames': [{'name': '', 'type': ''}],'addresses': {'ipv4': '192.168.1.120'},'vendor': {},'status': {'state': 'up', 'reason': 'localhost-response'},'tcp': {22: {'state': 'open','reason': 'syn-ack','name': 'ssh','product': 'OpenSSH','version': '7.4','extrainfo': 'protocol 2.0','conf': '10','cpe': 'cpe:/a:openbsd:openssh:7.4'},80: {'state': 'filtered','reason': 'no-response','name': 'http','product': '','version': '','extrainfo': '','conf': '3','cpe': ''},111: {'state': 'open','reason': 'syn-ack','name': 'rpcbind','product': '','version': '2-4','extrainfo': 'RPC #100000','conf': '10','cpe': ''}}}}}# 返回scan語句翻譯成nmap命令的寫法 In [4]: nm.command_line() Out[4]: 'nmap -oX - -p 1-1000 -sV 192.168.1.120,110'# 返回nmap掃描參數信息:格式為字典類型 In [5]: nm.scaninfo() Out[5]: {'tcp': {'method': 'syn', 'services': '1-1000'}}# 獲取存活主機列表 In [6]: nm.all_hosts() Out[6]: ['192.168.1.120']# 返回被掃描主機狀態:判斷是否存活 In [7]: nm['192.168.1.120'].state() Out[7]: 'up'# 返回被掃描主機所有打開端口支持的協議列表 In [8]: nm['192.168.1.120'].all_protocols() Out[8]: ['tcp']# 返回被掃描主機tcp協議字典里的鍵 In [9]: nm['192.168.1.120']['tcp'].keys() Out[9]: dict_keys([22, 80, 111])# 返回被掃描主機tcp協議打開的端口80的詳細信息 In [10]: nm['192.168.1.120']['tcp'][80] Out[10]: {'state': 'filtered','reason': 'no-response','name': 'http','product': '','version': '','extrainfo': '','conf': '3','cpe': ''}# 復雜nmap參數寫法:參照nmap命令 In [11]: nm.scan(hosts='192.168.1.0/24', arguments='-n -sP -PE -PA21,23,80,3389') '192.168.1.38': {'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4': '192.168.1.38', 'mac': '08:00:37:FB:76:49'}, 'vendor': {'08:00:37:FB:76:49': 'Fuji-xerox CO.'}, 'status': {'state': 'up', 'reason': 'arp-response'}},
- 掃描局域網存活主機import nmapnm = nmap.PortScanner() nm.scan(hosts = '192.168.1.0/24', arguments='-n -sP -PE') up_hosts = nm.all_hosts() for i in up_hosts:print(up_hosts)# 打印輸出 >>> 192.168.1.80 >>> 192.168.1.81
- 掃描單個主機打開端口import nmapnm = nmap.PortScanner()
nm.scan('127.0.0.1', '22-80,443')# 獲取所有tcp協議的端口
ports_tcp = nm['127.0.0.1'].all_tcp()
print(ports_tcp )
# 打印輸出
>>> [22, 80]
# 按協議輸出:協議名nm['127.0.0.1'].all_protocols()獲取
for i in nm['127.0.0.1']['tcp'].keys():print(i)
# 打印輸出
>>> 22
>>> 80
其他信息參見本節:單語句結果測試
回到總目錄
總結
以上是生活随笔為你收集整理的Python运维(六)--系统监控psutil、数据报scapy、扫描nmap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬取一条新闻内容_一个爬取近
- 下一篇: Python中Scapy使用方法,模块中