網路自動化技術的應用日益普及,其中ACL組態和封包操控是重要的組成部分。透過Nornir框架結合Jinja2範本引擎,可以有效地管理和佈署網路裝置的ACL規則。YAML檔案儲存結構化資料,Jinja2範本實作組態的動態生成,Nornir則負責將組態應用到目標裝置。此外,Scapy提供了強大的封包操控能力,可用於網路掃描、裝置發現和安全測試。結合Crontab定時任務,可以定期收集網路裝置的CPU使用率等關鍵指標,實作網路監控和預警。這些技術的整合應用,能大幅提升網路管理效率和安全性。
網路自動化中的ACL組態與封包操控
使用Nornir與Jinja2組態ACL規則
在網路自動化領域,存取控制列表(ACL)的組態是一項常見任務。利用Nornir框架和Jinja2範本引擎,我們可以實作動態生成ACL組態的功能。首先,我們需要建立一個YAML檔案來儲存組態引數。
info.yaml
acl_number: 100
access_lists:
- sequence: 10
permission: deny
protocol: ip
source_ip: 10.11.2.0 0.0.255.255
dest_ip: 192.32.1.0 0.0.255.255
- sequence: 20
permission: deny
protocol: ip
source_ip: 15.12.2.0 0.0.255.255
dest_ip: 192.12.1.0 0.0.255.255
- sequence: 30
permission: permit
protocol: ip
source_ip: 120.1.2.0 0.0.255.255
dest_ip: 192.168.1.0 0.0.255.255
- sequence: 40
permission: permit
protocol: tcp
source_ip: 10.1.1.0 0.0.0.255
dest_ip: 172.16.1.0 0.0.0.255
eq: telnet
- sequence: 50
permission: permit
protocol: ip
source_ip: 140.1.2.0 0.0.255.255
dest_ip: 192.168.1.0 0.0.255.255
- sequence: 90
permission: deny
protocol: pim
source_ip: any
dest_ip: any
dscp: cs1
- sequence: 100
permission: deny
protocol: ip
source_ip: any
dest_ip: any
commands.txt
ip access-list extended {{acl_number}}
{% for acl in access_lists %}
{{acl["sequence"]}} {{acl["permission"]}} {{acl["protocol"]}} {{acl["source_ip"]}} {{acl["dest_ip"]}} {% if acl['eq'] %}eq {{acl["eq"]}}{% endif %} {% if acl['dscp'] %}dscp {{acl["dscp"]}}{% endif %}
{% endfor %}
do show access-lists {{acl_number}}
Python指令碼(Example 9.3)
from nornir import InitNornir
from nornir_utils.plugins.functions import print_result
from nornir_netmiko import netmiko_send_config
from jinja2 import Environment, FileSystemLoader
from yaml import safe_load
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("commands.txt")
with open("info.yaml") as r:
data = safe_load(r)
config = template.render(data).split("\n")
connect = InitNornir()
result = connect.run(task=netmiko_send_config, config_commands=config)
print_result(result)
程式碼解析:
- 讀取YAML檔案:使用
safe_load函式讀取info.yaml檔案,將其內容轉換為Python字典。 - 渲染Jinja2範本:利用
commands.txt中的Jinja2範本和YAML資料,生成最終的ACL組態命令。 - 執行組態命令:透過Nornir框架的
netmiko_send_config任務,將生成的組態命令推播到網路裝置。 - 顯示結果:列印出組態命令的執行結果。
使用Scapy進行封包操控
Scapy是一個強大的Python模組,用於網路封包的捕捉、分析和偽造。以下是一些基本的Scapy功能:
- ARP:建立ARP封包,用於網路掃描和裝置發現。
- Ether:建立乙太網封包。
- Srp:在第二層傳送和接收封包,用於網路掃描。
- Summary 和 Show:顯示封包的基本資訊和詳細內容。
示例程式碼(Example 9.4)
from scapy.all import *
# 傳送ICMP封包到Google DNS IP地址8.8.8.8
packet = IP(dst="8.8.8.8")/ICMP()
response = sr1(packet, timeout=2, verbose=0)
if response:
print("收到回應:", response.summary())
else:
print("無回應")
程式碼解析:
- 匯入Scapy模組:使用
from scapy.all import *匯入Scapy的所有功能。 - 建立ICMP封包:利用
IP()和ICMP()函式建立一個ICMP封包,並指定目標IP為8.8.8.8。 - 傳送封包並接收回應:使用
sr1()函式傳送封包並等待回應,設定超時時間為2秒。 - 處理回應:如果收到回應,則列印出回應的摘要資訊;否則,顯示無回應。
使用Scapy傳送ICMP封包與網路掃描
在網路安全與管理的領域中,瞭解如何使用工具來傳送網路封包以及掃描網路裝置是至關重要的。Scapy是一個強大的Python函式庫,能夠讓使用者輕鬆地建構、傳送和解析網路封包。本文將介紹如何使用Scapy來傳送ICMP封包以及進行網路掃描。
傳送ICMP封包
ICMP(Internet Control Message Protocol)是一種用於錯誤報告和診斷的網路層協定。我們可以使用Scapy來傳送ICMP請求封包,以檢查目標主機是否可達。
範例程式碼
from scapy.all import *
# 設定目標IP位址
ip_address = IP(dst="8.8.8.8")
# 設定ICMP序列號
icmp_sequence = ICMP(seq=1111)
# 堆積疊IP和ICMP層
pckt = ip_address / icmp_sequence
# 傳送封包
send(pckt)
內容解密:
- 匯入Scapy的所有功能:使用
from scapy.all import *來匯入Scapy的所有模組和函式,以便於後續的操作。 - 設定目標IP位址:使用
IP(dst="8.8.8.8")來建立一個目標IP位址為8.8.8.8的IP層。 - 設定ICMP序列號:使用
ICMP(seq=1111)來建立一個序列號為1111的ICMP請求封包。 - 堆積疊IP和ICMP層:使用
/運算子來堆積疊IP和ICMP層,形成完整的封包。 - 傳送封包:使用
send(pckt)函式來傳送建構好的封包。
當執行此指令碼時,它將向目標IP位址8.8.8.8傳送一個ICMP請求封包。如果目標主機可達,它將傳回一個具有相同序列號的ICMP回應封包。
使用Wireshark觀察ICMP封包
為了觀察傳送的ICMP請求和回應封包,我們需要使用Wireshark這個網路封包分析工具。
- 下載並安裝Wireshark:從其官方網站下載並安裝Wireshark。
- 選擇介面卡:開啟Wireshark後,選擇正確的網路介面卡。
- 執行指令碼並觀察結果:執行上述的Scapy指令碼,並在Wireshark中觀察ICMP請求和回應封包。
網路掃描
除了傳送ICMP封包外,Scapy還可以用於進行網路掃描,以發現網路中的裝置。
範例程式碼
from scapy.all import *
# 建立ARP請求
arp = ARP(pdst="192.168.1.0/24")
# 建立乙太網幀
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# 堆積疊乙太網幀和ARP請求
broadcast = ether / arp
# 傳送並接收封包
hosts = srp(broadcast, timeout=1)[0]
# 解析結果
for device in hosts:
print(f"IP: {device[1].psrc} MAC: {device[1].hwsrc}")
內容解密:
- 建立ARP請求:使用
ARP(pdst="192.168.1.0/24")來建立一個針對指定網段的ARP請求。 - 建立乙太網幀:使用
Ether(dst="ff:ff:ff:ff:ff:ff")來建立一個廣播幀。 - 堆積疊乙太網幀和ARP請求:使用
/運算子來堆積疊乙太網幀和ARP請求。 - 傳送並接收封包:使用
srp()函式來傳送並接收第二層(資料鏈路層)的封包。 - 解析結果:遍歷傳回的結果,列印預出每個裝置的IP位址和MAC位址。
定期檢查CPU使用率
為了確保網路裝置的安全運作,我們可以定期檢查其CPU使用率。這可以透過在Linux系統上使用crontab服務來定時執行Python指令碼實作。
設定crontab
- 切換到root使用者:使用
sudo su命令切換到root使用者。 - 安裝必要的Python模組:在指令碼所在的目錄下,使用
pip install netmiko安裝必要的Python模組。 - 建立Python指令碼:建立一個用於收集CPU使用率的Python指令碼。
- 組態crontab:使用
crontab -e命令編輯crontab設定檔,新增定時任務以執行Python指令碼。
透過本文的介紹,我們瞭解瞭如何使用Scapy來傳送ICMP封包、進行網路掃描,以及如何定期檢查網路裝置的CPU使用率。這些技術對於網路管理和安全監控具有重要的意義。
使用Crontab定期收集網路裝置CPU使用率
在Linux系統中,我們可以使用Crontab任務排程器來定期執行任務。在這個例子中,我們將使用Crontab來執行一個Python指令碼,該指令碼會收集網路裝置的CPU使用率。
步驟1:建立Python指令碼
首先,我們需要在Linux系統上建立一個Python指令碼。我們可以使用touch命令來建立一個新的檔案。
root@Server-1:/home/ubuntu/Desktop# touch cpu_levels_periodically.py
使用ls -l命令可以檢視新建立的檔案。
root@Server-1:/home/ubuntu/Desktop# ls -l
total 20
-rw-r--r-- 1 root root 1294 Eyl 13 13:52 cpu_levels_periodically.py
步驟2:瞭解Crontab任務排程器
Crontab任務排程器允許我們在特定的時間間隔內執行任務。要執行Python指令碼,我們需要使用Python3工具。通常,我們可以直接使用python3 FILE_NAME.py來執行Python指令碼。但是,在Crontab中,我們需要指定Python3的完整路徑。我們可以使用which python3命令來找到Python3的完整路徑。
root@Server-1:/home/ubuntu/Desktop# which python3
/usr/bin/python3
步驟3:設定Crontab任務排程器
要設定Crontab任務排程器,我們需要使用crontab -e命令。如果是第一次使用Crontab,它會要求我們選擇一個文字編輯器。我們可以選擇預設的nano編輯器。
root@Server-1:/home/ubuntu/Desktop# crontab -e
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <
---
- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]: 1
在nano編輯器中,我們可以設定任務的執行時間和執行的命令。Crontab的時間格式包括五個部分:分鐘、小時、日、月、星期。我們可以使用*來表示任何值,使用*/n來表示每n個單位時間。
Crontab時間格式範例:
- 每分鐘執行一次 */3 * * * * - 每3分鐘執行一次
- */5 * * * - 每5小時執行一次 0 15 * * * - 每天15:00執行一次
- 1 - 每個星期一的每分鐘執行一次
更多Crontab時間格式的詳細資訊,可以參考https://crontab.guru/。
步驟4:新增Crontab任務
在這個例子中,我們希望每分鐘收集一次網路裝置的CPU使用率。因此,我們設定Crontab的時間為* * * * *。然後,我們需要執行Python指令碼。完整的Crontab任務如下:
* * * * * cd /home/ubuntu/Desktop && /usr/bin/python3 cpu_levels_periodically.py
儲存並離開nano編輯器後,Crontab任務就會自動開始執行。
Python指令碼範例
以下是用於收集網路裝置CPU使用率的Python指令碼範例(Example 9.6):
from netmiko import Netmiko
from re import findall
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
host = ["10.10.10.1", "10.10.10.2", "10.10.10.3"]
def collect_cpu(ip):
device = {"host": ip, "username": "admin", "password": "cisco", "device_type": "cisco_ios"}
command = "show processes cpu"
print(f"\n
---
Try to Login:{ip}
---
\n")
net_connect = Netmiko(**device)
output = net_connect.send_command(command)
cpu_5s = findall("five seconds: (\d+)", output)
time = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
if int(cpu_5s[0]) > 90:
cpu_risk = "Fatal CPU Level"
with open(f"high_cpu_risk_devices.txt", "a") as w:
w.write(f"
---
Time:{time}--- \nIP: {ip} \nCPU:{cpu_5s[0]} \nStatus:{cpu_risk}\n\n")
elif 70 < int(cpu_5s[0]) < 90:
cpu_risk = "High CPU Level"
with open(f"high_cpu_risk_devices.txt", "a") as w:
w.write(f"
---
Time:{time}--- \nIP: {ip} \nCPU:{cpu_5s[0]} \nStatus:{cpu_risk}\n\n")
else:
cpu_risk = "No Risk"
with open(f"{ip}_cpu_levels.txt", "a") as w:
w.write(f"
---
Time:{time}--- \nIP: {ip} \nCPU:{cpu_5s[0]} \nStatus:{cpu_risk}\n\n")
with ThreadPoolExecutor(max_workers=50) as executor:
result = executor.map(collect_cpu, host)
程式碼解析:
- 匯入必要的函式庫:指令碼首先匯入了必要的函式庫,包括
Netmiko用於連線網路裝置,findall用於從命令輸出中提取CPU使用率,datetime用於取得當前時間,以及ThreadPoolExecutor用於平行處理多個裝置的連線。 - 定義裝置列表:定義了一個包含裝置IP位址的列表
host。 - 定義收集CPU使用率的函式:函式
collect_cpu(ip)負責連線到指定的裝置,執行命令show processes cpu,並從輸出中提取5秒內的CPU使用率。 - 根據CPU使用率進行風險評估:根據提取的CPU使用率,將其與預設的閾值進行比較,並將結果寫入不同的檔案中。如果CPU使用率超過90%,則視為“Fatal CPU Level”;如果在70%到90%之間,則視為“High CPU Level”;否則視為“No Risk”。
- 使用多執行緒平行收集多個裝置的CPU使用率:透過
ThreadPoolExecutor,指令碼可以平行地對多個裝置執行collect_cpu函式,大大提高了收集效率。
檢視結果
執行Crontab任務後,可以在相同目錄下檢視新建立的檔案。使用cat命令可以檢視檔案內容。
root@Server-1:/home/ubuntu/Desktop# cat 10.10.10.1_cpu_levels.txt
---
Time:13.09.2022 15:08:04
---
IP: 10.10.10.1
CPU:15
Status:No Risk
---
Time:13.09.2022 15:09:03
---
IP: 10.10.10.1
CPU:11
Status:No Risk
...
也可以使用tail -f命令即時監控檔案內容的更新。
root@Server-1:/home/ubuntu/Desktop# tail -f 10.10.10.1_cpu_levels.txt