Automatisation SSH Netmiko
Utilisez cette compétence lors de l'écriture ou de la révision de scripts Python d'automatisation qui se connectent à des périphériques réseau avec Netmiko. Gardez le chemin par défaut en lecture seule ; les modifications de configuration nécessitent une fenêtre de changement séparée, une relecture par les pairs et un plan de retour arrière.
Quand l'utiliser
- Collecter la sortie de commandes
showsur des routeurs, commutateurs ou pare-feu. - Créer un petit script d'audit pour rassembler des preuves sur les interfaces, le routage ou la configuration.
- Ajouter des délais d'attente et une gestion des exceptions aux scripts SSH réseau.
- Analyser la sortie de commandes avec TextFSM lorsqu'un modèle existe.
- Réviser l'automatisation avant qu'elle ne touche les équipements de production.
Valeurs par défaut de sécurité
- Commencez par une collecte en lecture seule avec
send_command(). - Gardez l'inventaire petit et explicite ; ne balayez pas des plages d'adresses entières.
- Utilisez des variables d'environnement, un coffre-fort ou
getpass; ne codez jamais les identifiants en dur. - Définissez des délais d'attente de connexion et de lecture.
- Limitez la concurrence pour ne pas surcharger les équipements anciens.
- Exigez un indicateur explicite de l'opérateur avant
send_config_set(). - N'appelez pas
save_config()tant que le changement n'a pas été vérifié et approuvé.
Modèle de connexion en lecture seule
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("Nom d'utilisateur : "),
"password": os.environ.get("NETMIKO_PASSWORD") or getpass("Mot de passe : "),
"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("Échec de l'authentification")
except NetmikoTimeoutException:
print("Délai d'attente de la connexion SSH dépassé")
except ReadTimeout:
print("Délai de lecture de la commande dépassé")
Utilisez des adresses IP de la plage de documentation dans les exemples. Conservez l'inventaire réel dans un fichier local ignoré ou un système de gestion des secrets.
Collecte par lots
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())
Gardez max_workers bas sauf si le parc d'équipements et les systèmes AAA sont connus pour supporter un volume de connexions plus élevé.
Analyse structurée
Netmiko peut demander à TextFSM, TTP ou Genie d'analyser la sortie de commandes prises en charge. Considérez la sortie de l'analyseur comme une optimisation, pas comme le seul chemin de preuve.
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("Aucun modèle d'analyseur correspondant ; stockez la sortie brute pour révision")
else:
for row in parsed:
print(row)
Si l'analyse influence une décision bloquante, conservez la sortie brute de la commande à côté du résultat analysé afin qu'un opérateur puisse inspecter les divergences.
Modèle de configuration encadrée
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("Simulation uniquement. Commandes candidates :")
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("Vérifiez le comportement avant de sauvegarder la configuration de démarrage.")
Sauvegarder la configuration est une étape d'approbation distincte. En production, incluez un extrait de retour arrière et capturez les preuves avant/après dans le dossier de changement.
Liste de vérification pour la révision
- Le script identifie-t-il une source d'inventaire explicite ?
- Les identifiants sont-ils absents du code source, des journaux et des messages d'exception ?
conn_timeout,auth_timeoutet leread_timeoutde la commande sont-ils définis ?- Les échecs sont-ils rapportés par équipement sans arrêter tout le lot ?
- Le script évite-t-il les analyses larges et la concurrence illimitée ?
- Les modifications de configuration sont-elles derrière un indicateur de simulation ou explicite ?
save_config()est-il séparé de l'application initiale et lié à la vérification ?
Anti-patrons
- Coder en dur les mots de passe, les secrets enable ou les clés privées dans le code source.
- Envoyer des commandes de configuration comme chemin de code par défaut.
- Exécuter l'automatisation sur une plage CIDR au lieu d'un inventaire révisé.
- Journaliser des configurations complètes en cours d'exécution sur des systèmes partagés sans anonymisation.
- Considérer le succès de l'analyseur comme une preuve que l'état de l'équipement est correct.
Voir aussi
- Compétence :
cisco-ios-patterns - Compétence :
network-config-validation - Compétence :
network-interface-health