netmiko-ssh-automation

netmiko-ssh-automation

熱門

提供安全的 Python Netmiko 設計模式,涵蓋唯讀資料收集、受控的批次 SSH 連線、TextFSM 解析、具防護機制的組態變更、逾時設定以及網路自動化錯誤處理。

24萬星標
3.6萬分支
更新於 2026/8/2
SKILL.md
唯讀
名稱
netmiko-ssh-automation
描述

提供安全的 Python Netmiko 設計模式,涵蓋唯讀資料收集、受控的批次 SSH 連線、TextFSM 解析、具防護機制的組態變更、逾時設定以及網路自動化錯誤處理。

Netmiko SSH 自動化

在撰寫或審查使用 Netmiko 連線至網路設備的 Python 自動化腳本時,請使用此 Skill。預設流程應保持唯讀;變更組態需在獨立的變更視窗中執行,並具備同儕審查與復原計畫。

使用時機

  • 收集路由器、交換器或防火牆上的 show 指令輸出。
  • 建立小型稽核腳本,以取得介面、路由或組態相關證據。
  • 為網路 SSH 腳本新增逾時機制與例外處理。
  • 當有對應範本時,使用 TextFSM 解析指令輸出。
  • 在自動化腳本套用至正式環境設備前進行審查。

安全預設值

  • 優先使用唯讀的 send_command() 收集資料。
  • 保持清冊(inventory)規模小且明確;切勿掃描整個 IP 位址範圍。
  • 使用環境變數、金鑰管理系統(vault)或 getpass;絕不硬編碼(hardcode)憑證。
  • 設定連線與讀取逾時。
  • 限制併發數,避免舊型設備過載。
  • 在執行 send_config_set() 前,必須要求明確的操作員標籤(operator flag)。
  • 變更未經確認與核准前,請勿呼叫 save_config()

唯讀連線模式

import os
from getpass import getpass
from netmiko import ConnectHandler
from netmiko.exceptions import (
    NetmikoAuthenticationException,
    NetmikoTimeoutException,
    ReadTimeout,
)

device = {
    "device_type": "cisco_ios",
    "host": "192.0.2.10",
    "username": os.environ.get("NETMIKO_USERNAME") or input("Username: "),
    "password": os.environ.get("NETMIKO_PASSWORD") or getpass("Password: "),
    "secret": os.environ.get("NETMIKO_ENABLE_SECRET"),
    "conn_timeout": 10,
    "auth_timeout": 20,
    "banner_timeout": 15,
    "read_timeout_override": 30,
}

try:
    with ConnectHandler(**device) as conn:
        if device.get("secret") and not conn.check_enable_mode():
            conn.enable()
        output = conn.send_command("show ip interface brief", read_timeout=30)
        print(output)
except NetmikoAuthenticationException:
    print("Authentication failed")
except NetmikoTimeoutException:
    print("SSH connection timed out")
except ReadTimeout:
    print("Command read timed out")

在範例中使用文件專用的占位符位址。請將實際清冊保存在被忽略的本機檔案或金鑰管理系統中。

批次收集

from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Any

def collect_show(device: dict[str, Any], command: str) -> dict[str, Any]:
    host = device["host"]
    try:
        with ConnectHandler(**device) as conn:
            output = conn.send_command(command, read_timeout=45)
        return {"host": host, "ok": True, "output": output}
    except (NetmikoAuthenticationException, NetmikoTimeoutException, ReadTimeout) as exc:
        return {"host": host, "ok": False, "error": type(exc).__name__}

results = []
with ThreadPoolExecutor(max_workers=8) as pool:
    futures = [pool.submit(collect_show, device, "show version") for device in devices]
    for future in as_completed(futures):
        results.append(future.result())

除非已知網路設備總數與 AAA 系統機能可承受更高的連線量,否則請保持 max_workers 在較小數值。

結構化解析

Netmiko 可呼叫 TextFSM、TTP 或 Genie 來解析支援的指令輸出。請將解析器輸出視為優化手段,而非唯一的證據來源。

with ConnectHandler(**device) as conn:
    parsed = conn.send_command(
        "show ip interface brief",
        use_textfsm=True,
        raise_parsing_error=False,
        read_timeout=30,
    )

if isinstance(parsed, str):
    print("No parser template matched; store raw output for review")
else:
    for row in parsed:
        print(row)

若解析結果是用於關鍵的阻斷性決策,請在保留解析結果的同時附上原始指令輸出,以便操作員檢視不一致之處。

防護型組態模式

import os

commands = [
    "interface GigabitEthernet0/1",
    "description CHANGE-1234 UPLINK-TO-CORE",
]

apply_changes = os.environ.get("APPLY_NETWORK_CHANGES") == "1"

if not apply_changes:
    print("Dry run only. Candidate commands:")
    print("\n".join(commands))
else:
    with ConnectHandler(**device) as conn:
        conn.enable()
        before = conn.send_command("show running-config interface GigabitEthernet0/1")
        output = conn.send_config_set(commands)
        after = conn.send_command("show running-config interface GigabitEthernet0/1")
        print(before)
        print(output)
        print(after)
        print("Verify behavior before saving startup config.")

儲存組態是獨立的核准步驟。在正式環境中,變更紀錄應包含復原程式碼片段(rollback snippet)以及變更前後的對比證據。

審查檢核表

  • 腳本是否指定了明確的清冊來源?
  • 原始碼、日誌與例外訊息中是否均未包含憑證?
  • 是否已設定 conn_timeoutauth_timeout 以及指令 read_timeout
  • 失敗是否以單一設備為單位回報,且不會中止整個批次作業?
  • 腳本是否避免了大範圍掃描與未加限制的併發?
  • 組態變更是否具備試運行(dry-run)或明確的操作員標籤保護?
  • save_config() 是否與初始推送分開,並與驗證步驟相連動?

反模式

  • 在原始碼中硬編碼密碼、enable 密碼或私鑰。
  • 將傳送組態指令設為預設執行路徑。
  • 對 CIDR 區段直接執行自動化,而非使用經審核的清冊。
  • 將完整的運行中組態(running config)記錄至未經去敏處理的共用系統。
  • 將解析器的成功執行誤認為設備狀態正確的證明。

參見

  • Skill: cisco-ios-patterns
  • Skill: network-config-validation
  • Skill: network-interface-health