身為網路工程師,我經常需要處理大量裝置的設定,手動操作不僅耗時費力,還容易出錯。因此,自動化網路設定一直是我追求的目標。本文將分享我使用 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 進行裝置設定。敬請期待!