Netmiko SSH Automatisierung
Verwenden Sie diese Fähigkeit, wenn Sie Python-Automatisierung schreiben oder überprüfen, die eine Verbindung zu Netzwerkgeräten mit Netmiko herstellt. Behalten Sie den Standardpfad schreibgeschützt bei; 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 existiert.
- Ü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; kodieren Sie niemals Anmeldeinformationen fest. - Legen Sie Verbindungs- und Lesetimeouts fest.
- Begrenzen Sie die Parallelität, damit ä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 abgelaufen")
except ReadTimeout:
print("Befehlslesezeit abgelaufen")
Verwenden Sie Platzhalteradressen aus Dokumentationsbereichen in Beispielen. Halten Sie das eigentliche Inventar in einer ignorierten lokalen Datei oder einem geheimnisverwalteten 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, der Gerätebestand und die AAA-Systeme sind bekannt dafür, höhere Verbindungsvolumen 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 Beweisweg.
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; speichern Sie die Rohausgabe zur Überprüfung")
else:
for row in parsed:
print(row)
Wenn das Parsen eine blockierende Entscheidung steuert, bewahren Sie die Rohbefehlsausgabe 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. Kandidatenbefehle:")
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("Überprüfen Sie das Verhalten, bevor Sie die Startkonfiguration speichern.")
Das Speichern der Konfiguration ist ein separater Genehmigungsschritt. Fügen Sie in der Produktion einen Rollback-Ausschnitt ein und erfassen Sie Vorher-/Nachher-Nachweise im Änderungsdatensatz.
Überprüfungs-Checkliste
- Identifiziert das Skript eine explizite Inventarquelle?
- Sind Anmeldeinformationen aus Quellcode, Protokollen und Ausnahmenachrichten entfernt?
- Sind
conn_timeout,auth_timeoutund Befehls-read_timeoutgesetzt? - 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 explizitem Operator-Flag geschützt?
- Ist
save_config()separat vom ersten Push und an die Verifikation gebunden?
Anti-Patterns
- Hartcodieren von Passwörtern, Enable-Secrets oder privaten Schlüsseln im Quellcode.
- Senden von Konfigurationsbefehlen als Standardcodepfad.
- Ausführen von Automatisierung gegen einen CIDR-Bereich anstelle eines überprüften Inventars.
- Protokollieren vollständiger Running-Configs in gemeinsam genutzten Systemen ohne Bereinigung.
- Behandlung des Parser-Erfolgs als Beweis dafür, dass der Gerätezustand korrekt ist.
Siehe auch
- Fähigkeit:
cisco-ios-patterns - Fähigkeit:
network-config-validation - Fähigkeit:
network-interface-health