網路管理仰賴即時資訊掌握,SNMP 協定扮演關鍵角色。本文以 Python 和 pysnmp 模組為例,示範如何從網路裝置收集資訊,並透過 Gmail 傳送通知。首先,說明 SNMP 的基本概念,包含 OID 和 MIB 檔案的應用。接著,示範使用 pysnmp 模組進行資訊收集,包含單個和多個 OID 的查詢方式。此外,也提供 MIB 檔案的使用說明,讓讀者能更彈性地運用 MIB 物件名稱查詢資訊。最後,結合 smtplib 和 email 模組,示範如何設定 Gmail 並傳送郵件通知,讓管理員能即時掌握裝置狀態。
利用SNMP收集網路裝置資訊
SNMP(Simple Network Management Protocol)是網路管理中不可或缺的協定,用於裝置之間的資訊分享。網路管理系統(NMS)工具透過SNMP從裝置取得資料並顯示在工具中。目前SNMP有三個版本:v1、v2和v3。其中,SNMPv1的安全性較差,SNMPv2的安全性有所提升,但最安全的版本是SNMPv3,它具備資料加密和身份驗證功能,以防止未授權的連線。
SNMP的工作原理
透過SNMP,可以收集裝置的CPU和記憶體使用率、裝置執行時間、OSPF鄰居狀態以及介面狀態等資訊。裝置中儲存著一個稱為MIB(Management Information Base)的資料函式庫,用於儲存本地裝置的資訊。MIB是一個檔案,儲存了從裝置收集到的資訊。SNMP管理器利用MIB檔案從任何裝置取得資料。
MIB中包含了多個物件,這些物件透過OID(Object Identifier)來識別。NMS透過OID向代理請求物件的值。OID是一個數值地址,用於識別MIB層次結構中的物件。例如,OID 1.3.6.1.2.1.25.1.1.0用於取得裝置執行時間。當NMS或監控工具向裝置傳送這個OID時,裝置會將執行時間資訊回傳給代理。透過不同的OID,工具可以從網路裝置取得各種資料並建立資料函式庫。
利用Python的pysnmp模組收集SNMP資料
Python中有一個成熟的SNMP模組——pysnmp,用於透過SNMP協定與網路和系統裝置進行通訊。首先,需要透過pip install pysnmp命令安裝pysnmp模組。
要使用Python指令碼透過SNMP從網路裝置收集資料,需要在裝置上啟用SNMP功能,並組態共同體值(如public),以及選擇只讀或讀寫引數。以下是在Cisco裝置上組態SNMP的範例:
Router-1#configure terminal
Router-1(config)#snmp-server community public ro
蒐集Cisco裝置的記憶體資料
範例7.3展示瞭如何使用pysnmp模組從Cisco裝置收集空閒記憶體資料。首先,匯入pysnmp模組中的hlapi函式:
from pysnmp.hlapi import *
定義主機IP、SNMP共同體值和用於取得空閒記憶體的OID:
host = "10.10.10.1"
snmp_community = "public"
snmp_oid = "1.3.6.1.4.1.9.2.1.8.0"
使用getCmd函式和相關類別例項(如SnmpEngine、CommunityData、UdpTransportTarget、ContextData和ObjectType)來傳送SNMP請求並取得資料:
errorIndication, errorStatus, errorIndex, varBinds = next(
getCmd(SnmpEngine(),
CommunityData(snmp_community, mpModel=1),
UdpTransportTarget((host, 161)),
ContextData(),
ObjectType(ObjectIdentity(snmp_oid)), )
)
內容解密:
getCmd函式用於傳送SNMP GET請求。SnmpEngine是SNMP引擎的例項,用於管理SNMP操作。CommunityData用於設定SNMP共同體值,這裡使用的是public,並指定使用SNMPv2c(mpModel=1)。UdpTransportTarget定義了目標裝置的UDP地址和埠(161是SNMP的預設埠)。ContextData用於指定SNMP上下文,這裡為空,表示使用預設上下文。ObjectType(ObjectIdentity(snmp_oid))指定了要查詢的OID。
最後,遍歷varBinds以列印OID和對應的值:
for oid, val in varBinds:
print(oid.prettyPrint(), " - ", val.prettyPrint())
蒐集多個OID的資料
範例7.4展示瞭如何收集多個OID的資料,例如介面狀態。首先,定義多個OID:
snmp_oid = ["1.3.6.1.4.1.9.2.2.1.1.20.1", "1.3.6.1.4.1.9.2.2.1.1.20.2"]
然後,使用迴圈遍歷這些OID,並為每個OID傳送SNMP請求:
for id in snmp_oid:
errorIndication, errorStatus, errorIndex, varBinds = next(
getCmd(SnmpEngine(),
CommunityData(snmp_community, mpModel=1),
UdpTransportTarget((host, 161)),
ContextData(),
ObjectType(ObjectIdentity(id)),
)
)
for oid, val in varBinds:
print(oid.prettyPrint(), " - ", val.prettyPrint())
輸出結果將顯示每個介面的狀態,例如:
SNMPv2-SMI::enterprises.9.2.2.1.1.20.1 - up
SNMPv2-SMI::enterprises.9.2.2.1.1.20.2 - administratively down
這與透過CLI命令show ip int br獲得的結果一致:
Router-1#show ip int br
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 10.10.10.1 YES NVRAM up up
網路裝置監控與郵件通知實務
在現代網路管理中,及時取得網路裝置的狀態資訊以及傳送報警資訊至管理員信箱,是確保網路穩定執行的關鍵。本文將介紹如何使用Python與SNMP(簡單網路管理協定)取得網路裝置資訊,並透過Gmail傳送郵件通知。
使用SNMP取得網路裝置資訊
SNMP是一種廣泛使用的網路管理協定,能夠讓管理員收集和修改網路裝置上的資訊。利用Python的pysnmp模組,我們可以輕鬆地與支援SNMP的裝置進行互動。
OID與MIB檔案
在SNMP中,OID(Object Identifier)用於標識被管理的物件。例如,OID "1.3.6.1.4.1.9.2.1.3.0" 可用於取得裝置的主機名資訊。除了使用OID,我們還可以使用MIB(Management Information Base)檔案中的物件名稱。
from pysnmp.hlapi import getCmd, SnmpEngine, CommunityData, UdpTransportTarget, ContextData, ObjectType, ObjectIdentity
# 設定SNMP連線引數
snmp_engine = SnmpEngine()
community_data = CommunityData('public')
udp_transport_target = UdpTransportTarget(('裝置IP', 161))
context_data = ContextData()
# 使用OID取得主機名
oid = ObjectType(ObjectIdentity('1.3.6.1.4.1.9.2.1.3.0'))
result = getCmd(snmp_engine, community_data, udp_transport_target, context_data, oid)
# 處理結果
for response in result:
for (error_indication, error_status, error_index, var_binds) in response:
if error_indication:
print(error_indication)
else:
print(var_binds)
內容解密:
- 設定SNMP連線引數:首先,我們需要設定SNMP引擎、
CommunityData(共同體字串)、UdpTransportTarget(目標裝置的IP和埠)以及ContextData。 - 使用OID取得資訊:利用
ObjectType和ObjectIdentity,我們可以指定要查詢的OID。在此例中,我們查詢的是主機名。 - 處理結果:查詢結果會被迭代處理。如果出現錯誤,則列印錯誤指示;否則,列印查詢結果。
使用MIB檔案
有些時候,直接使用MIB檔案中的物件名稱會更加方便。pysnmp支援使用MIB檔案,但需要先將MIB檔案轉換為Python檔案。
轉換MIB檔案
可以透過mibdump.py工具或安裝libsmi2pysnmp套件來轉換MIB檔案。轉換後的檔案應放置於venv\Lib\site-packages\pysnmp\smi\mibs目錄下。
使用MIB物件名稱
from pysnmp.hlapi import getCmd, SnmpEngine, CommunityData, UdpTransportTarget, ContextData, ObjectType, ObjectIdentity
# 使用MIB物件名稱取得主機名
oid = ObjectType(ObjectIdentity("SNMPv2-MIB", "sysName", 0))
result = getCmd(snmp_engine, community_data, udp_transport_target, context_data, oid)
# 處理結果
for response in result:
for (error_indication, error_status, error_index, var_binds) in response:
if error_indication:
print(error_indication)
else:
print(var_binds)
內容解密:
- 使用MIB物件名稱:我們可以直接使用MIB中的物件名稱,如
"sysName",來取得主機名。 - 查詢結果處理:與使用OID相同,查詢結果會被迭代處理,並列印預出結果或錯誤指示。
透過Gmail傳送郵件通知
在取得到網路裝置的資訊後,我們可能需要將這些資訊或報警資訊傳送給管理員。Python的smtplib和email模組可以幫助我們實作這一點。
取得Gmail的16位密碼
- 登入Google帳戶管理頁面。
- 啟用兩步驗證。
- 建立應用程式密碼,並選擇郵件應用程式。
傳送郵件程式碼範例
import smtplib
from email.message import EmailMessage
# 設定郵件引數
mail_from = "你的Gmail地址"
mail_password = "16位密碼"
mail_to = "收件人信箱"
# 建立郵件內容
msg = EmailMessage()
msg.set_content("這是一封測試郵件")
msg['Subject'] = '測試郵件'
msg['From'] = mail_from
msg['To'] = mail_to
# 傳送郵件
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(mail_from, mail_password)
smtp.send_message(msg)
內容解密:
- 設定郵件引數:包括發件人、密碼和收件人。
- 建立郵件內容:使用
EmailMessage類別建立郵件內容、主題、發件人和收件人。 - 傳送郵件:利用
smtplib.SMTP_SSL連線到Gmail的SMTP伺服器,並登入傳送郵件。
自動化網路裝置組態收集與郵件通知
在現代網路管理中,自動化已成為提升效率和降低錯誤率的關鍵技術。本文將探討如何利用Python指令碼自動收集Cisco路由器的組態,並透過電子郵件傳送這些組態檔案。同時,我們還會介紹如何進行網路裝置的連通性測試。
使用Python自動收集Cisco路由器組態
首先,我們需要使用netmiko模組來連線Cisco路由器並收集其組態。以下是一個簡單的Python函式,用於收集指定路由器的組態並儲存到本地檔案中。
from netmiko import Netmiko
def collect_configuration(ip, username, password):
device = {
"host": ip,
"username": username,
"password": password,
"device_type": "cisco_ios"
}
net_connect = Netmiko(**device)
output = net_connect.send_command("show run")
with open(f"{ip}_config.txt", "w") as f:
f.write(output)
net_connect.disconnect()
# 使用範例
ips = ["10.10.10.1", "10.10.10.2", "10.10.10.3"]
for ip in ips:
collect_configuration(ip, "admin", "cisco")
內容解密:
- 匯入必要的模組:使用
from netmiko import Netmiko匯入Netmiko類別,這是用於連線網路裝置的關鍵類別。 - 定義函式:
collect_configuration函式接受IP地址、使用者名稱和密碼作為引數,用於建立與路由器的連線。 - 建立連線:使用
Netmiko類別建立與路由器的SSH連線,傳入包含連線詳細資訊的字典。 - 傳送命令:使用
send_command方法傳送show run命令來取得路由器的當前組態。 - 儲存組態:將取得的組態儲存到以IP地址命名的檔案中。
- 斷開連線:完成後斷開與路由器的連線。
自動傳送組態檔案至指定郵件
收集到路由器組態後,下一步是透過電子郵件將這些組態檔案傳送給指定的收件人。我們可以使用smtplib和email模組來實作這一步驟。
import smtplib
from email.message import EmailMessage
import mimetypes
def send_email(mail_from, mail_password, mail_to, subject, content, filenames):
msg = EmailMessage()
msg.add_header("From", mail_from)
msg.add_header("To", mail_to)
msg.add_header("Subject", subject)
msg.set_content(content)
for filename in filenames:
with open(filename, "rb") as f:
attached_file = f.read()
mime_type, _ = mimetypes.guess_type(filename)
maintype, subtype = mime_type.split("/")
msg.add_attachment(attached_file, maintype=maintype, subtype=subtype, filename=filename)
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp:
smtp.login(mail_from, mail_password)
smtp.sendmail(mail_from, mail_to, msg.as_string())
# 使用範例
filenames = [f"{ip}_config.txt" for ip in ["10.10.10.1", "10.10.10.2", "10.10.10.3"]]
send_email("example@gmail.com", "16-DIGIT-PASSWORD", "example@gmail.com", "Router Configurations", "Please find the configurations in the attachments.", filenames)
內容解密:
- 建立郵件訊息:使用
EmailMessage類別建立郵件訊息物件,並設定發件人、收件人、主題和正文。 - 新增附件:遍歷檔名列表,開啟每個檔案,讀取其內容,並使用
add_attachment方法將其作為附件新增到郵件中。 - 傳送郵件:使用
smtplib.SMTP_SSL建立與Gmail SMTP伺服器的安全連線,登入後傳送郵件。
網路裝置連通性測試
除了收集組態和傳送郵件,網路管理中另一個基本任務是測試網路裝置的連通性。我們可以使用Python的subprocess模組來執行ping命令,測試目標IP的可達性。
import subprocess
def ping_test(ip, count=3):
output = subprocess.Popen(f"ping {ip} -n {count}", stdout=subprocess.PIPE, encoding="utf-8")
result = ""
for line in output.stdout:
result += line.rstrip('\n') + "\n"
return result
# 使用範例
print(ping_test("10.10.10.1"))
內容解密:
- 執行ping命令:使用
subprocess.Popen執行ping命令,指定目標IP和ping次數。 - 捕捉輸出:讀取ping命令的輸出結果,並將其儲存在字串中傳回。
這些範例展示瞭如何使用Python自動化網路管理任務,包括收集路由器組態、傳送電子郵件通知以及測試網路連通性。透過這些自動化指令碼,可以大幅提高網路管理的效率和準確性。