Was macht Netmiko-SSH-Automation?
Verwenden Sie diese Fähigkeit, wenn Sie Python-Automatisierung schreiben oder überprüfen, die mit Netmiko eine Verbindung zu Netzwerkgeräten herstellt. Halten Sie den Standardpfad schreibgeschützt; Konfigurationsänderungen benötigen ein separates Änderungsfenster, eine Peer-Review und einen Rollback-Plan.
Wann verwenden
- Sammeln von
show-Befehlsausgaben auf Routern, Switches oder Firewalls. - Erstellen eines kleinen Audit-Skripts für Schnittstellen-, Routing- oder Konfigurationsnachweise.
- Hinzufügen von Timeouts und Ausnahmebehandlung zu Netzwerk-SSH-Skripten.
- Parsen von Befehlsausgaben mit TextFSM, wenn eine Vorlage vorhanden ist.
- Überprüfen der Automatisierung, bevor sie Produktionsgeräte berührt.
Sicherheitsstandards
- Beginnen Sie mit schreibgeschützter
send_command()-Sammlung. - Halten Sie das Inventar klein und explizit; scannen Sie keine gesamten Adressbereiche.
- Verwenden Sie Umgebungsvariablen, einen Tresor oder
getpass; hardcodieren Sie niemals Anmeldeinformationen. - Setzen Sie Verbindungs- und Lese-Timeouts.
- Begrenzen Sie die Parallelität, sodass ältere Geräte nicht überlastet werden.
- Erfordern Sie ein explizites Operator-Flag vor
send_config_set(). - Rufen Sie
save_config()erst auf, wenn die Änderung verifiziert und genehmigt wurde.
Schreibgeschütztes Verbindungsmuster
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("Benutzername: "),
"password": os.environ.get("NETMIKO_PASSWORD") or getpass("Passwort: "),
"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("Authentifizierung fehlgeschlagen")
except NetmikoTimeoutException:
print("SSH-Verbindung zeitüberschritten")
except ReadTimeout:
print("Befehlslesezeit überschritten")
Verwenden Sie Platzhalteradressen aus Dokumentationsbereichen in Beispielen. Halten Sie das echte Inventar in einer ignorierten lokalen Datei oder einem Secrets-verwalteten System.
Batch-Sammlung
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())
Halten Sie max_workers niedrig, es sei denn, die Geräteumgebung und AAA-Systeme sind bekannt dafür, eine höhere Verbindungsanzahl zu verarbeiten.
Strukturiertes Parsen
Netmiko kann TextFSM, TTP oder Genie bitten, unterstützte Befehlsausgaben zu parsen. Behandeln Sie die Parser-Ausgabe als Optimierung, nicht als einzigen Beweispfad.
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("Keine Parser-Vorlage gefunden; rohe Ausgabe zur Überprüfung speichern")
else:
for row in parsed:
print(row)
Wenn das Parsen eine blockierende Entscheidung beeinflusst, bewahren Sie die rohe Befehlsausgabe zusammen mit dem geparsten Ergebnis auf, damit ein Operator Abweichungen überprüfen kann.
Bewachtes Konfigurationsmuster
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("Nur Trockenlauf. Kandidaten-Befehle:")
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("Verhalten überprüfen, bevor die Startkonfiguration gespeichert wird.")
Das Speichern der Konfiguration ist ein separater Genehmigungsschritt. Fügen Sie in der Produktion einen Rollback-Ausschnitt hinzu und erfassen Sie Vorher-/Nachher-Nachweise im Änderungsdatensatz.
Überprüfungscheckliste
- Identifiziert das Skript eine explizite Inventarquelle?
- Sind Anmeldeinformationen in Quelle, Protokollen und Ausnahmemeldungen nicht enthalten?
- Sind
conn_timeout,auth_timeoutundread_timeoutfür Befehle gesetzt? - Werden Fehler pro Gerät gemeldet, ohne die gesamte Batch zu stoppen?
- Vermeidet das Skript breite Scans und unbegrenzte Parallelität?
- Sind Konfigurationsänderungen hinter einem Trockenlauf oder expliziten Operator-Flag?
- Ist
save_config()vom initialen Push getrennt und mit der Verifizierung verknüpft?
Anti-Patterns
- Hartcodieren von Passwörtern, Enable-Secrets oder privaten Schlüsseln im Quellcode.
- Senden von Konfigurationsbefehlen als Standard-Code-Pfad.
- Ausführen von Automatisierung gegen einen CIDR-Bereich anstatt einem überprüften Inventar.
- Protokollieren vollständiger Running-Konfigurationen auf gemeinsam genutzten Systemen ohne Bereinigung.
- Behandlung des Parser-Erfolgs als Beweis, dass der Gerätezustand korrekt ist.
Siehe auch
- Skill:
cisco-ios-patterns - Skill:
network-config-validation - Skill:
network-interface-health