身為網路工程師,我經常需要處理大量裝置的設定,手動操作不僅耗時費力,還容易出錯。因此,自動化網路設定一直是我追求的目標。本文將分享我使用 Python 自動化設定 Cisco 裝置 SNMPv3 的經驗,並結合連線狀態檢查,提升設定效率和可靠性。
SSH 連線與裝置時間同步
在開始設定 SNMPv3 之前,確認裝置連線和時間同步至關重要。我使用 Paramiko 函式庫撰寫了以下程式碼,實作 SSH 連線並取得裝置時間:
import paramiko
def get_device_time(ip, username, password):
"""透過 SSH 連線到裝置並取得目前時間。"""
try:
with paramiko.SSHClient() as ssh:
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, username=username, password=password)
_, stdout, _ = ssh.exec_command('show clock')
time_output = stdout.read().decode().strip()
return time_output
except Exception as e:
print(f"SSH 連線至 {ip} 失敗: {e}")
return None
# ... 後續程式碼會使用這個函式 ...
這個函式使用 paramiko
建立 SSH 連線,執行 show clock
命令取得裝置時間,並妥善處理例外狀況,確保程式穩定性。使用 with
陳述式能自動關閉 SSH 連線,避免資源洩漏。
網路連線預檢查工具
為了避免在裝置離線時進行設定,我設計了一個根據 ICMP ping 的預檢查工具:
import subprocess
def check_connectivity(ip_address):
"""使用 ICMP ping 檢查裝置連線狀態。"""
try:
subprocess.check_output(['ping', '-c', '3', ip_address])
return True
except subprocess.CalledProcessError:
return False
# ... 後續程式碼會使用這個函式 ...
這個函式使用 subprocess.check_output
執行 ping 命令,並根據回傳值判斷裝置是否可達。簡潔的程式碼提高了可讀性和維護性。
自動化設定 SNMPv3
接下來,我使用 Netmiko 函式庫實作 SNMPv3 的自動化設定:
from netmiko import ConnectHandler
def configure_snmpv3(device, engine_id, snmp_user, auth_password, priv_password):
"""設定 Cisco 裝置的 SNMPv3。"""
config_commands = [
f"snmp-server engineID local {engine_id}",
"snmp-server group GROUP1 v3 priv",
f"snmp-server user {snmp_user} GROUP1 v3 auth sha {auth_password} priv aes 128 {priv_password}",
]
try:
with ConnectHandler(**device) as conn:
conn.send_config_set(config_commands)
print(f"成功設定 {device['ip']} 的 SNMPv3")
except Exception as e:
print(f"設定 {device['ip']} 的 SNMPv3 失敗: {e}")
# ... 後續程式碼會使用這個函式 ...
這個函式利用 Netmiko 的 send_config_set
方法,將設定指令傳送到裝置。我將設定指令儲存在列表中,方便管理和修改。同樣地,try...except
區塊確保程式碼的穩固性。
整合與執行
最後,我將所有程式碼片段整合起來,並加入使用者輸入和迴圈處理多個裝置:
# ... (get_device_time 和 check_connectivity 函式) ...
if __name__ == "__main__":
username = input("輸入使用者名稱: ")
password = input("輸入密碼: ")
snmp_user = input("輸入 SNMP 使用者名稱: ")
auth_password = input("輸入 SNMP 驗證密碼: ")
priv_password = input("輸入 SNMP 加密密碼: ")
ip_addresses = ["192.168.1.1", "192.168.1.2"] # 替換成你的 IP 位址列表
for ip in ip_addresses:
if check_connectivity(ip):
device = {
'device_type': 'cisco_ios',
'ip': ip,
'username': username,
'password': password,
}
engine_id = ip.replace(".", "") # 使用 IP 位址作為 Engine ID
configure_snmpv3(device, engine_id, snmp_user, auth_password, priv_password)
time_output = get_device_time(ip, username, password)
if time_output:
print(f"{ip} 的時間: {time_output}")
else:
print(f"{ip} 無法連線")
程式執行流程
graph LR B[B] C[C] A[輸入憑證] --> B{迴圈處理 IP 位址} B --> C{連線檢查} C -- 成功 --> D[設定 SNMPv3] D --> E[取得裝置時間] E --> B C -- 失敗 --> F[輸出錯誤訊息] F --> B
SNMPv3 架構
graph LR C[C] Engine[Engine] ID[ID] Trap[Trap] A[管理系統] -- Get/Set/Trap --> B(SNMPv3 代理) B -- Engine ID --> C{使用者設定} C -- 安全模型 --> D[驗證] D -- 驗證演算法 --> E(SHA/MD5) D -- 加密演算法 --> F(AES/DES)
透過以上方法,我成功地實作了 Cisco 裝置 SNMPv3 的自動化設定,並結合連線檢查,大幅提升了工作效率和準確性。希望這篇文章能幫助到各位網路工程師。
在現今複雜的網路環境中,自動化管理網路裝置已成為提升效率和安全性的關鍵。SNMP(簡易網路管理協定)是實作此目標的核心技術,而 SNMPv3 更以其增強的安全性,成為現代網路管理的首選。本文將以實戰角度,示範如何結合 Python 和 SNMPv3,實作網路裝置的自動化組態和資訊提取。
使用 Python 設定 SNMPv3
以下 Python 程式碼示範如何自動登入網路裝置,並設定 SNMPv3 使用者和相關引數:
import netmiko
def configure_snmpv3(device, username, password, snmp_user, auth_pass, priv_pass):
try:
connection = netmiko.ConnectHandler(**device)
connection.enable()
config_commands = [
f"snmp-server engineID local {device['ip'].replace('.', '')}",
f"snmp-server group GROUP1 v3 priv",
f"snmp-server user {snmp_user} GROUP1 v3 auth sha {auth_pass} priv aes 128 {priv_pass}"
]
connection.send_config_set(config_commands)
connection.save_config()
print(f"已成功設定 {device['ip']} 並斷開連線。")
connection.disconnect()
except Exception as e:
print(f"設定裝置 {device['ip']} 時發生錯誤: {e}")
# 裝置資訊
device = {
'device_type': 'cisco_ios',
'ip': '192.168.1.1', # 使用虛擬 IP 位址
'username': 'admin', # 使用虛擬帳號
'password': 'password' # 使用虛擬密碼
}
# SNMPv3 引數
snmp_user = 'SNMPUser1'
auth_pass = 'AUTHPass1'
priv_pass = 'PRIVPass1'
configure_snmpv3(device, device['username'], device['password'], snmp_user, auth_pass, priv_pass)
這段程式碼利用 netmiko
函式庫與網路裝置進行互動。首先,建立與裝置的 SSH 連線,接著使用 send_config_set
方法傳送 SNMPv3 的設定指令。這些指令包含設定 engineID
、建立使用者群組,以及新增 SNMPv3 使用者,並指定驗證 (SHA
) 和加密 (AES128
) 演算法及密碼。最後,使用 save_config
儲存設定,並斷開連線。我特意將 IP 位址、帳號和密碼改為虛擬值,確保安全性。
驗證 SNMPv3 設定
設定完成後,可以使用 show snmp user
指令驗證設定是否成功:
R1#show snmp user
User name: SNMPUser1
Engine ID: 19216811
storage-type: nonvolatile active
Authentication Protocol: SHA
Privacy Protocol: AES128
Group-name: GROUP1
show snmp user
指令顯示 SNMP 使用者的設定資訊,包含使用者名稱、Engine ID、驗證協定、加密協定和群組名稱。確認這些資訊與設定相符,即表示 SNMPv3 設定成功。
使用 SNMPwalk 提取資訊
設定完成後,可以使用 snmpwalk
工具從網路裝置提取資訊。以下範例示範如何提取裝置的系統描述:
snmpwalk -v3 -l authPriv -u SNMPUser1 -a SHA -A "AUTHPass1" -x AES -X "PRIVPass1" 192.168.1.1 sysDescr
snmpwalk
命令搭配 -v3
引數指定使用 SNMPv3 版本。-l authPriv
表示使用驗證和加密。-u
, -a
, -A
, -x
, -X
引數分別指定使用者名稱、驗證協定、驗證密碼、加密協定和加密密碼。最後指定目標裝置的 IP 位址和 sysDescr
OID 來取得系統描述。
SNMPv3 架構
graph LR A[SNMP 管理伺服器] -->|SNMPv3 請求| B(網路裝置) B -->|SNMPv3 回應| A subgraph "SNMPv3 安全性層級" C[驗證] --> D[加密] end
**圖表説明:**此圖表展示 SNMP 管理伺服器與網路裝置之間的 SNMPv3 通訊流程,以及 SNMPv3 的安全性層級,包含驗證和加密。
資訊提取流程
sequenceDiagram participant 管理伺服器 participant 網路裝置 管理伺服器->>網路裝置: SNMPv3 請求 (例如:sysDescr) activate 網路裝置 網路裝置-->>管理伺服器: SNMPv3 回應 (系統描述資訊) deactivate 網路裝置
**圖表説明:**此序列圖詳細説明瞭 SNMP 管理伺服器如何傳送 SNMPv3 請求到網路裝置,並接收包含系統描述資訊的回應。
Python 自動化儲存設定 (強化版)
以下 Python 程式碼示範如何使用 Python 自動登入多台裝置,並儲存目前的執行組態,並加入錯誤處理機制:
import netmiko
import getpass
def save_config_on_devices(devices, username, password):
for device in devices:
try:
connection = netmiko.ConnectHandler(device_type=device['device_type'], ip=device['ip'], username=username, password=password)
connection.enable()
connection.send_command("write memory")
print(f"成功登入 {device['ip']}。裝置時間:")
output = connection.send_command("show clock")
print(output)
print("正在建立組態...")
print("[完成]")
connection.disconnect()
except netmiko.ssh_exception.NetMikoTimeoutException:
print(f"連線 {device['ip']} 超時。")
except netmiko.ssh_exception.NetMikoAuthenticationException:
print(f"驗證 {device['ip']} 失敗。")
except Exception as e:
print(f"在裝置 {device['ip']} 上儲存設定時發生錯誤: {e}")
# 裝置資訊 (使用虛擬 IP)
devices = [
{'device_type': 'cisco_ios', 'ip': '192.168.1.2'},
{'device_type': 'cisco_ios', 'ip': '192.168.1.3'},
]
username = input("請輸入使用者名稱: ")
password = getpass.getpass("請輸入密碼: ")
save_config_on_devices(devices, username, password)
這段程式碼迭代 devices
列表中的每個裝置,建立 SSH 連線,執行 write memory
指令儲存設定,並顯示裝置時間和執行結果。使用 getpass
模組安全地取得密碼,避免在終端機顯示。我強化了錯誤處理機制,可以捕捉連線超時和驗證失敗等常見錯誤,並提供更明確的錯誤訊息。
透過以上步驟,我們可以利用 Python 和 SNMPv3 實作網路裝置的自動化管理,提升管理效率和安全性。這個方法有效地結合了 Python 的自動化能力和 SNMPv3 的安全性,為現代網路管理提供了強大的工具。透過自動化指令碼,可以簡化繁瑣的設定流程,並確保設定的一致性,減少人為錯誤。同時,SNMPv3 的安全性機制保障了網路裝置資訊的安全,防止未經授權的存取和修改。
藉由理解程式碼的運作原理和「內容解密」提供的深入分析,讀者可以根據自身需求修改和擴充套件這些程式碼,構建更複雜的網路自動化解決方案。例如,可以結合其他 Python 函式庫,實作更豐富的功能,例如自動備份設定、監控網路狀態等等。持續學習和探索新的技術,才能在不斷變化的網路世界中保持競爭力。
我已根據您的要求修改了內容,並增加了額外的 圖表和更詳細的程式碼説明。此外,我還將所有簡體中文轉換為繁體中文,並使用了台灣慣用的技術術語。所有程式碼中的 IP 位址、帳號和密碼都已改為虛擬值,以確保安全性。
在網路自動化的世界裡,SNMP(簡易網路管理協定)扮演著不可或缺的角色。我經常在專案中使用 SNMP 來監控和管理網路裝置,而 SNMPv3 以其強大的安全性,成為我的首選。本文將引領您探索 SNMPv3 的奧秘,並示範如何使用 Python 程式碼與網路裝置進行互動。我將分享個人在實際專案中使用 SNMPv3 的經驗和技巧,幫助您更好地理解和應用這項技術。
首先,我們先來瞭解一下 SNMPv3 的安全模型。不同於 SNMPv1 和 v2c 使用社群字串進行身份驗證,SNMPv3 採用了使用者名稱、驗證密碼和加密密碼,提供更安全的通訊環境。這對於保護網路裝置的資訊安全至關重要。
接下來,我們將使用 Python 的 pysnmp
函式庫來與網路裝置進行互動。pysnmp
是一個功能強大的函式庫,它提供了高階 API,可以簡化 SNMP 操作。以下是一個使用 pysnmp
取得裝置名稱的範例程式碼:
from pysnmp.hlapi import *
def get_snmp_data(target, oids, credentials, port=161):
"""
從 SNMP Agent 取得資料。
此函式封裝了 PySNMP 函式庫的 getCmd 函式,用於向 SNMP Agent 傳送 GET 請求並接收回應。
它簡化了與 SNMP Agent 的互動,並將結果轉換為易於處理的字典格式。
主要步驟包括:
1. 使用 getCmd 構建 SNMP GET 命令。
2. 使用 fetch 函式取得 SNMP 回應資料。
3. 將回應資料轉換為字典格式。
此函式適用於 SNMPv1, v2c, 和 v3,具體由 credentials 引數決定。
Args:
target (str): SNMP Agent 的 IP 位址或主機名稱。
oids (list): 要查詢的 OID 列表。
credentials (object): SNMP 憑證,例如 CommunityData 或 UsmUserData。
port (int, optional): SNMP Agent 的埠號。預設為 161。
Returns:
dict: 包含 OID 及其對應值的字典。如果發生錯誤,則傳回 None。
"""
engine = SnmpEngine()
handler = getCmd(
engine,
credentials,
UdpTransportTarget((target, port)),
ContextData(),
*[ObjectType(ObjectIdentity(oid)) for oid in oids]
)
try:
result = fetch_snmp_response(handler, 1)[0]
return result
except (RuntimeError, IndexError): # 處理 SNMP 錯誤和空結果
return None
def fetch_snmp_response(handler, count):
"""從 SNMP 回應中提取資料。
此函式迭代處理 SNMP 回應,將每個 varBind 的值轉換為 Python 內建型別 (int, float, str)。
它處理了 SNMP 錯誤和 StopIteration 例外,確保資料提取的完整性和穩定性。
Args:
handler (object): SNMP 命令處理器。
count (int): 要提取的回應數量。
Returns:
list: 包含回應資料的列表,每個元素是一個字典。
"""
result = []
for _ in range(count):
try:
error_indication, error_status, error_index, var_binds = next(handler)
if error_indication or error_status:
raise RuntimeError(f'SNMP 錯誤:{error_indication}')
items = {str(vb[0]): cast_snmp_value(vb[1]) for vb in var_binds}
result.append(items)
except StopIteration:
break
return result
def cast_snmp_value(value):
"""將 SNMP 值轉換為 Python 內建型別。
此函式嘗試將 SNMP 值轉換為 int、float 或 str 型別。如果轉換失敗,則傳回原始值。
這確保了 SNMP 資料在 Python 中的正確處理和使用。
Args:
value (object): SNMP 值。
Returns:
int/float/str/object: 轉換後的 Python 值或原始值。
"""
for type_ in (int, float, str):
try:
return type_(value)
except (ValueError, TypeError):
pass
return value
# SNMPv3 憑證
snmp_v3_credentials = UsmUserData(
'SNMPUser1', # 使用者名稱
authKey='AUTHPass1', # 驗證金鑰
privKey='PRIVPass1', # 加密金鑰
authProtocol=usmHMACSHAAuthProtocol, # 驗證協定
privProtocol=usmAesCfb128Protocol # 加密協定
)
# 取得裝置名稱 (OID: 1.3.6.1.2.1.1.5.0)
device_name_oid = '1.3.6.1.2.1.1.5.0'
device_name_result = get_snmp_data('192.168.127.3', [device_name_oid], snmp_v3_credentials)
if device_name_result:
device_name = device_name_result.get(device_name_oid)
print(f"裝置名稱:{device_name}")
else:
print("無法取得裝置名稱")
# 以下為示範如何取得多個 OID 資料的範例
oids = [
'1.3.6.1.2.1.1.1.0', # sysDescr
'1.3.6.1.2.1.1.5.0' # sysName
]
data = get_snmp_data('192.168.127.3', oids, snmp_v3_credentials)
if data:
for oid, value in data.items():
print(f"{oid}: {value}")
else:
print("無法取得 SNMP 資料")
這段程式碼定義了幾個函式來取得 SNMP 資料。get_snmp_data
函式是主要的入口點,它接收目標裝置的 IP 位址、OID 列表和 SNMPv3 憑證。fetch_snmp_response
函式處理 SNMP 回應,並將其轉換為 Python 字典。cast_snmp_value
函式將 SNMP 值轉換為 Python 內建型別。程式碼中也示範瞭如何使用 SNMPv3 憑證和如何查詢多個 OID。
graph LR B[B] C[C] D[D] E[E] G[G] A[開始] --> B{初始化 SNMP 引擎}; B --> C{構建 SNMP GET 命令}; C --> D{傳送 SNMP 請求}; D --> E{接收 SNMP 回應}; E -- 錯誤 --> F[處理錯誤]; E -- 成功 --> G{解析 SNMP 資料}; G --> H[傳回資料]; F --> I[結束]; H --> I;
**圖表説明:**這個流程圖描述了使用 get_snmp_data
函式取得 SNMP 資料的流程,包含初始化、構建命令、傳送請求、接收回應、錯誤處理和資料解析等步驟。
透過以上程式碼和説明,我們可以更有效率地使用 Python 和 SNMPv3 進行網路自動化管理。在我的經驗中,善用 SNMPv3 的安全性以及 Python 的靈活性,可以大幅提升網路管理的效率和安全性。
sequenceDiagram participant Client participant Agent Client->>Agent: SNMP GET Request (OID) activate Agent Agent->>MIB: 查詢 OID activate MIB MIB-->>Agent: OID 值 deactivate MIB Agent-->>Client: SNMP Response (OID 值) deactivate Agent
**圖表説明:**此序列圖展示了 SNMP Client 與 Agent 之間的訊息交換流程,包含 Client 傳送 GET 請求、Agent 查詢 MIB 資料函式庫、以及 Agent 回傳 OID 值給 Client。
在未來的文章中,我將會分享更多關於 SNMPv3 的進階應用,例如設定 Trap 接收器和使用 SNMP 進行裝置設定。敬請期待!