網路自動化已成為現代網路管理的關鍵,有效降低人為錯誤並提升效率。本文將探討如何使用 Python 中的 Paramiko 和 Netmiko 函式庫,搭配 GNS3 等網路模擬器,實作對多台網路裝置的自動化管理,包含 SSH 和 Telnet 連線建立、命令執行、資訊收集以及多執行緒應用,讓繁瑣的網路管理任務更有效率且不易出錯。

第四章 日誌收集與監控

本章重點在於連線模組與指令碼範例,將使用netmiko、paramiko和telnetlib模組,透過SSH(安全殼層)和telnet協定登入網路和系統裝置。將使用這些模組從多台裝置收集資料,並在登入後進行修改。同時,將建立自定義的IP地址驗證工具和子網路計算器。

本章結構

本章將涵蓋以下主題:

  • 連線模組
  • SSH連線
  • Telnet連線
  • 收集日誌
  • 收集版本和裝置資訊
  • 收集CPU使用率
  • 查詢重複的IP地址
  • 使用多執行緒收集日誌
  • 工具和計算器
  • IP地址驗證器
  • 子網路計算器

目標

為了實作自動化,必須透過SSH和telnet協定登入網路和系統裝置。通常使用paramiko、netmiko和telnetlib模組來連線這些協定的裝置。可以使用for迴圈連線一台或多台裝置,並在一個指令碼中執行多個命令。同時,也可以建立自定義指令碼來從裝置收集資料,或建立像子網路計算器這樣的自定義工具。此外,可以利用Python的多執行緒模組的平行處理功能,同時登入多台裝置。

連線模組

為了模擬本文後續部分的連線指令碼,可以使用真實裝置和像GNS3這樣的網路模擬器。GNS3是一個免費工具,建議使用測試裝置或模擬器來測試指令碼。真實的網路裝置有流量,因此在學習自動化的初期可能會存在風險。對於Cisco或Juniper裝置等眾多廠商,GNS3可以正常執行,也可以使用eNSP模擬器進行Huawei的模擬。

GNS3與VM Tool的安裝步驟

  1. 從GNS3的官方網站下載免費的GNS3工具。需要建立一個免費帳戶才能下載該工具,並可在Windows、MAC或Linux上安裝。
  2. 下載並在PC上安裝該工具後,需要從以下連結下載GNS3 VM。需要選擇特定的VM來使用。在本文中,使用VMware Workstation Player,免費供非商業使用。因此,下載GNS3 VM供VMware Workstation和Fusion使用。
  3. 最後,必須從其官方網站下載並安裝VMware Player工具。
  4. 所有安裝完成後,必須開啟VMware Player並從PC匯入GNS3 VM,如圖4.1所示,點選開啟虛擬機器。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 網路裝置自動化管理技術

package "Python 應用架構" {
    package "應用層" {
        component [主程式] as main
        component [模組/套件] as modules
        component [設定檔] as config
    }

    package "框架層" {
        component [Web 框架] as web
        component [ORM] as orm
        component [非同步處理] as async
    }

    package "資料層" {
        database [資料庫] as db
        component [快取] as cache
        component [檔案系統] as fs
    }
}

main --> modules : 匯入模組
main --> config : 載入設定
modules --> web : HTTP 處理
web --> orm : 資料操作
orm --> db : 持久化
web --> cache : 快取查詢
web --> async : 背景任務
async --> fs : 檔案處理

note right of web
  Flask / FastAPI / Django
end note

@enduml

此圖示顯示了GNS3與VMware Player的安裝流程。

內容解密:

上述步驟描述了安裝GNS3和VMware Player的過程。首先,從官方網站下載GNS3並安裝。接著,下載適合的GNS3 VM版本,並安裝VMware Player。最後,在VMware Player中匯入GNS3 VM,完成虛擬環境的設定。

SSH連線

SSH是登入網路和系統裝置最常用的協定之一。

使用Python進行SSH連線

import paramiko

def ssh_connection(ip, username, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, username=username, password=password)
    stdin, stdout, stderr = ssh.exec_command('show version')
    print(stdout.read().decode())
    ssh.close()

# 使用範例
ssh_connection('192.168.1.1', 'admin', 'password')

內容解密:

此程式碼片段展示瞭如何使用paramiko模組建立SSH連線。首先,建立一個SSHClient物件,並設定主機金鑰策略。然後,使用提供的IP地址、使用者名稱和密碼進行連線。連線建立後,執行show version命令,並列印輸出結果。最後,關閉SSH連線。

本章節僅擷取部分內容進行重寫,後續內容將依照指引繼續進行。

使用Paramiko模組透過SSH連線網路裝置

SSH(Secure Shell)是一種安全的連線協定,具有多種加密選項和協定版本,如版本1和版本2。相較於Telnet協定,SSH更加安全。在Python中,我們通常使用Paramiko和Netmiko模組透過SSH協定登入裝置。

Paramiko模組介紹

Paramiko模組允許我們與網路或系統裝置建立SSH和SFTP(Secure File Transfer Protocol)連線,但不支援Telnet和FTP(File Transfer Protocol)連線。我們可以使用使用者名稱、密碼和埠號登入裝置,並執行顯示或組態命令來監控網路裝置和收集日誌。

安裝Paramiko模組

由於Paramiko是第三方模組,我們需要使用pip install paramiko命令進行安裝。安裝完成後,在程式碼中匯入Paramiko模組:

import paramiko

建立SSH連線

我們需要呼叫Paramiko模組中的SSHClient函式來建立SSH連線。這個函式代表了與SSH伺服器的一個會話。將這個函式指定給client變數:

client = paramiko.SSHClient()

設定主機金鑰策略

首次登入裝置時,SSH客戶端會詢問是否信任該裝置。我們可以使用set_missing_host_key_policy函式並設定為AutoAddPolicy來自動新增主機金鑰:

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

連線裝置

使用connect函式提供裝置的IP位址、埠號、使用者名稱和密碼:

client.connect("10.10.10.1", 22, "admin", "cisco")

請求互動式Shell會話

使用invoke_shell函式請求一個互動式的Shell會話,並將其指定給commands變數:

commands = client.invoke_shell()

傳送命令

使用send函式傳送命令到裝置。需要注意的是,傳送命令後需要加上\n來模擬按下Enter鍵:

commands.send("show version \n")

接收輸出

使用recv函式接收裝置的輸出。輸出的資料格式為位元組,需要使用decode函式轉換為UTF-8格式:

output = commands.recv(1000000)
output = output.decode("utf-8")

範例:使用Paramiko連線Cisco裝置並收集版本資訊

以下是完整的範例程式碼:

import paramiko
import time

# 建立SSH客戶端
client = paramiko.SSHClient()

# 設定主機金鑰策略
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 連線裝置
client.connect("10.10.10.1", 22, "admin", "cisco")

# 請求互動式Shell會話
commands = client.invoke_shell()

# 傳送命令
commands.send("show version \n")

# 等待命令執行完成
time.sleep(2)

# 接收輸出
output = commands.recv(1000000)
output = output.decode("utf-8")

# 列印輸出結果
print(output)

內容解密:

  1. 匯入必要的模組:首先,我們匯入了Paramiko和Time模組。Paramiko用於建立SSH連線,而Time模組用於在程式碼中建立延遲。
  2. 建立SSH客戶端:呼叫SSHClient函式來建立一個SSH客戶端。
  3. 設定主機金鑰策略:使用set_missing_host_key_policy函式設定主機金鑰策略為自動新增,以避免首次登入時的信任提示。
  4. 連線裝置:提供裝置的IP位址、埠號、使用者名稱和密碼,使用connect函式建立連線。
  5. 請求互動式Shell會話:使用invoke_shell函式請求一個互動式的Shell會話。
  6. 傳送命令:使用send函式傳送命令到裝置,並在命令後加上\n來模擬按下Enter鍵。
  7. 接收輸出:使用recv函式接收裝置的輸出,並使用decode函式將輸出轉換為UTF-8格式。

這個範例展示瞭如何使用Paramiko模組透過SSH連線網路裝置,並執行命令來收集資訊。透過這個例子,可以瞭解到如何使用Paramiko進行網路自動化的基本操作。

使用 Paramiko 進行網路裝置自動化管理

透過 Paramiko 登入單一裝置並執行命令

Paramiko 是一個 Python 函式庫,能夠實作 SSHv2 協定,用於遠端管理網路裝置。以下範例展示如何使用 Paramiko 登入單一網路裝置並執行命令。

範例 4.1:使用 Paramiko 連線單一裝置

import paramiko
import time

# 建立 SSH 使用者端
client = paramiko.SSHClient()
# 自動新增主機金鑰
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連線到裝置
client.connect("10.10.10.1", 22, "admin", "cisco")
# 呼叫互動式 shell
commands = client.invoke_shell()
# 傳送命令
commands.send("show version \n")
# 等待 1 秒以確保輸出完整
time.sleep(1)
# 接收輸出
output = commands.recv(1000000)
# 解碼輸出為 UTF-8 格式
output = output.decode("utf-8")
# 列印輸出
print(output)

內容解密:

  1. 建立 SSH 使用者端:使用 paramiko.SSHClient() 建立一個 SSH 使用者端物件。
  2. 自動新增主機金鑰:使用 set_missing_host_key_policy(paramiko.AutoAddPolicy()) 自動新增主機金鑰,以避免因未知主機金鑰而導致的連線失敗。
  3. 連線到裝置:使用 connect() 方法連線到目標裝置,引數包括 IP 地址、埠號、使用者名稱和密碼。
  4. 呼叫互動式 shell:使用 invoke_shell() 方法啟動一個互動式的 shell 會話,以便能夠連續傳送多個命令。
  5. 傳送命令:使用 send() 方法傳送命令到裝置,命令後面加上 \n 以模擬按下 Enter 鍵。
  6. 等待輸出:使用 time.sleep(1) 等待 1 秒,以確保裝置有足夠時間輸出結果。
  7. 接收輸出:使用 recv(1000000) 接收裝置的輸出,接收緩衝區大小為 1000000 位元組。
  8. 解碼輸出:使用 decode("utf-8") 將輸出的位元組解碼為 UTF-8 編碼的字串,以便於閱讀和處理。

使用 Paramiko 執行組態命令

除了執行 show 命令外,我們還可以使用 Paramiko 執行組態命令。

範例 4.2:在單一裝置上執行組態命令

import paramiko
import time

# 建立 SSH 使用者端並連線到裝置(與範例 4.1 相同)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("10.10.10.1", 22, "admin", "cisco")
commands = client.invoke_shell()

# 傳送組態命令
commands.send("configure terminal \n")
commands.send("interface gigabitethernet 0/1 \n")
commands.send("description TEST\n")
commands.send("do show run interface gigabitethernet 0/1 \n")

# 等待輸出
time.sleep(1)
output = commands.recv(1000000)
output = output.decode("utf-8")
print(output)

內容解密:

  1. 進入組態模式:使用 configure terminal 命令進入全域組態模式。
  2. 進入介面組態模式:使用 interface gigabitethernet 0/1 命令進入指定介面的組態模式。
  3. 設定介面描述:使用 description TEST 命令設定介面的描述資訊。
  4. 檢視介面組態:使用 do show run interface gigabitethernet 0/1 命令檢視介面的當前組態。
  5. 接收和列印輸出:與範例 4.1 中的步驟相同,接收輸出並列印。

連線多台裝置

在實際的網路管理工作中,我們往往需要同時管理多台裝置。手動逐一登入每台裝置並執行相同命令是非常耗時且低效的。利用 Python 的迴圈結構,我們可以輕鬆實作對多台裝置的批次管理。

使用迴圈連線多台裝置

import paramiko
import time

# 定義裝置列表
devices = [
    {"ip": "10.10.10.1", "username": "admin", "password": "cisco"},
    {"ip": "10.10.10.2", "username": "admin", "password": "cisco"},
    # 新增更多裝置...
]

for device in devices:
    try:
        # 建立 SSH 連線
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(device["ip"], 22, device["username"], device["password"])
        
        # 傳送命令
        commands = client.invoke_shell()
        commands.send("show version \n")
        time.sleep(1)
        output = commands.recv(1000000)
        output = output.decode("utf-8")
        print(f"Output from {device['ip']}:\n{output}")
        
    except Exception as e:
        print(f"Failed to connect to {device['ip']}: {e}")

內容解密:

  1. 定義裝置列表:將需要管理的裝置資訊(IP 地址、使用者名稱、密碼)存放在一個列表中。
  2. 遍歷裝置列表:使用 for 迴圈遍歷每個裝置,並嘗試建立 SSH 連線。
  3. 例外處理:使用 try-except 結構捕捉可能發生的異常,如連線失敗等,並列印錯誤資訊。

使用 Paramiko 和 Netmiko 實作網路裝置自動化管理

在現代網路管理中,自動化是提升效率和減少錯誤的關鍵。本文將探討如何使用 Python 中的 Paramiko 和 Netmiko 函式庫來實作對多台網路裝置的自動化管理。

使用 Paramiko 連線多台裝置

Paramiko 是一個強大的 Python 函式庫,用於實作 SSHv2 協定的安全遠端連線。以下是一個使用 Paramiko 連線多台裝置並執行命令的範例。

程式碼範例

import paramiko
import time

# 定義裝置 IP 地址列表和命令列表
hosts = ["10.10.10.1", "10.10.10.2", "10.10.10.3"]
command_list = ["conf t", "int g0/0", "description NEW-TEST"]

# 外層迴圈遍歷裝置 IP 地址
for ip in hosts:
    # 建立 SSH 連線
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(ip, 22, "admin", "cisco")
    commands = client.invoke_shell()

    # 內層迴圈執行命令列表中的命令
    for command in command_list:
        commands.send("{} \n".format(command))
        time.sleep(1)
        output = commands.recv(1000000)
        output = output.decode("utf-8")
        print(output)

內容解密:

  1. 匯入必要的模組:首先,我們匯入 paramikotime 模組。paramiko 用於建立 SSH 連線,而 time 用於在命令之間新增延遲。
  2. 定義裝置列表和命令列表:我們定義了一個包含裝置 IP 地址的列表 hosts 和一個包含要執行的命令的列表 command_list
  3. 外層迴圈:遍歷 hosts 列表中的每個 IP 地址,建立 SSH 連線,並呼叫 invoke_shell() 方法開啟一個互動式 shell 會話。
  4. 內層迴圈:對於每個連線的裝置,遍歷 command_list 中的命令,並透過 send() 方法將命令傳送到裝置。time.sleep(1) 用於在命令之間新增一秒的延遲,以避免命令被丟失或混淆。
  5. 接收輸出:使用 recv() 方法接收命令的輸出,並將其解碼為 UTF-8 格式後列印出來。

使用 Netmiko 連線單一裝置

Netmiko 是另一個用於簡化 SSH 連線的 Python 函式庫,它根據 Paramiko 並支援多個網路裝置廠商。

程式碼範例

from netmiko import Netmiko

# 定義裝置資訊字典
device = {
    "host": "10.10.10.1",
    "username": "admin",
    "password": "cisco",
    "device_type": "cisco_ios",
    "global_delay_factor": 0.1,
}

# 建立 Netmiko 連線
net_connect = Netmiko(**device)

# 傳送組態命令到 Cisco 裝置
# 省略了具體的命令傳送程式碼,請參考 Netmiko 檔案

內容解密:

  1. 匯入 Netmiko:從 netmiko 模組匯入 Netmiko 類別。
  2. 定義裝置資訊:建立一個字典 device,包含主機 IP 地址、使用者名稱、密碼、裝置型別等資訊。
  3. 建立 Netmiko 連線:使用 Netmiko 類別建立到裝置的連線,將 device 字典解封裝為關鍵字引數傳遞給 Netmiko 建構函式。
  4. 傳送命令:透過建立的連線物件,可以呼叫方法傳送命令到裝置。具體方法請參考 Netmiko 的官方檔案。