Was macht Netzwerkkonfigurations-Validierung (Pre-Flight Checks)?
Verwenden Sie dieses Skill, um eine Netzwerkkonfiguration vor einem Änderungsfenster oder bevor eine Automatisierung produktive Geräte berührt, zu überprüfen.
Wann verwenden
- Überprüfung von Cisco IOS- oder IOS-XE-Snippets vor dem Deployment.
- Prüfung von generierter Konfiguration aus Skripten oder Vorlagen.
- Suche nach gefährlichen Befehlen, doppelten IP-Adressen oder Subnetz-Überlappungen.
- Prüfung, ob ACLs, Route-Maps, Prefix-Listen oder Line-Policies referenziert, aber nicht definiert sind.
- Erstellung von leichten Preflight-Skripten für die Netzwerk-Automation.
Wie es funktioniert
Behandeln Sie die Konfigurationsvalidierung als schichtweise Evidenz, nicht als vollständigen Parser. Regex-Prüfungen sind nützlich für Preflight-Warnungen, aber die endgültige Freigabe erfordert weiterhin einen Netzwerktechniker, der die Absicht, die Plattformsyntax und die Rollback-Schritte überprüft.
Validieren Sie in dieser Reihenfolge:
- Destruktive Befehle.
- Gefährdung von Anmeldedaten und Management-Ebene.
- Doppelte Adressen und überlappende Subnetze.
- Verwaiste Referenzen zu ACLs, Route-Maps, Prefix-Listen und Schnittstellen.
- Betriebliche Hygiene wie NTP, Zeitstempel, Remote-Logging und Banner.
Erkennung gefährlicher Befehle
import re
DANGEROUS_PATTERNS: list[tuple[re.Pattern[str], str]] = [
(re.compile(r"\breload\b", re.I), "reload verursacht Ausfallzeit"),
(re.compile(r"\berase\s+(startup|nvram|flash)", re.I), "löscht permanenten Speicher"),
(re.compile(r"\bformat\b", re.I), "formatiert ein Gerätedateisystem"),
(re.compile(r"\bno\s+router\s+(bgp|ospf|eigrp)\b", re.I), "entfernt einen Routing-Prozess"),
(re.compile(r"\bno\s+interface\s+\S+", re.I), "entfernt Schnittstellenkonfiguration"),
(re.compile(r"\baaa\s+new-model\b", re.I), "ändert Authentifizierungsverhalten"),
(re.compile(r"\bcrypto\s+key\s+(zeroize|generate)\b", re.I), "ändert Geräte-SSH-Schlüssel"),
]
def find_dangerous_commands(lines: list[str]) -> list[dict[str, str | int]]:
findings = []
for line_number, line in enumerate(lines, start=1):
stripped = line.strip()
for pattern, reason in DANGEROUS_PATTERNS:
if pattern.search(stripped):
findings.append({
"line": line_number,
"command": stripped,
"reason": reason,
})
return findings
Doppelte IPs und Subnetz-Überlappungen
import ipaddress
import re
from collections import Counter
IP_ADDRESS_RE = re.compile(
r"^\s*ip address\s+"
r"(?P<ip>\d{1,3}(?:\.\d{1,3}){3})\s+"
r"(?P<mask>\d{1,3}(?:\.\d{1,3}){3})\b",
re.I | re.M,
)
def extract_interfaces(config: str) -> list[dict[str, str]]:
results = []
current = None
for line in config.splitlines():
if line.startswith("interface "):
current = line.split(maxsplit=1)[1]
continue
match = IP_ADDRESS_RE.match(line)
if current and match:
ip = match.group("ip")
mask = match.group("mask")
network = ipaddress.ip_interface(f"{ip}/{mask}").network
results.append({"interface": current, "ip": ip, "network": str(network)})
return results
def find_duplicate_ips(config: str) -> list[str]:
ips = [entry["ip"] for entry in extract_interfaces(config)]
counts = Counter(ips)
return sorted(ip for ip, count in counts.items() if count > 1)
def find_subnet_overlaps(config: str) -> list[tuple[str, str]]:
networks = [ipaddress.ip_network(entry["network"]) for entry in extract_interfaces(config)]
overlaps = []
for index, left in enumerate(networks):
for right in networks[index + 1:]:
if left.overlaps(right):
overlaps.append((str(left), str(right)))
return overlaps
Checks der Management-Ebene
Analysieren Sie VTY-Blöcke abschnittsweise, damit Access-Class-Prüfungen nicht auf unzusammenhängende Zeilen übergreifen.
import re
def iter_blocks(config: str, starts_with: str) -> list[str]:
blocks = []
current: list[str] = []
for line in config.splitlines():
if line.startswith(starts_with):
if current:
blocks.append("\n".join(current))
current = [line]
continue
if current:
if line and not line.startswith(" "):
blocks.append("\n".join(current))
current = []
else:
current.append(line)
if current:
blocks.append("\n".join(current))
return blocks
def check_vty_blocks(config: str) -> list[str]:
issues = []
for block in iter_blocks(config, "line vty"):
if re.search(r"transport\s+input\s+.*telnet", block, re.I):
issues.append("VTY erlaubt Telnet; nur SSH erforderlich.")
if not re.search(r"\baccess-class\s+\S+\s+in\b", block, re.I):
issues.append("VTY-Block hat keine eingehende Access-Class-Quellbeschränkung.")
if not re.search(r"\bexec-timeout\s+\d+\s+\d+\b", block, re.I):
issues.append("VTY-Block hat kein explizites exec-timeout.")
return issues
Sicherheitshygiene-Prüfungen
SECURITY_PATTERNS = [
(re.compile(r"\bsnmp-server community\s+(public|private)\b", re.I),
"Standard-SNMP-Community konfiguriert"),
(re.compile(r"\bsnmp-server community\s+\S+", re.I),
"SNMPv2-Community-String konfiguriert; bevorzugen Sie SNMPv3 authPriv"),
(re.compile(r"\bip ssh version 1\b", re.I),
"SSH Version 1 aktiviert"),
(re.compile(r"\benable password\b", re.I),
"enable password vorhanden; verwenden Sie enable secret"),
(re.compile(r"\busername\s+\S+\s+password\b", re.I),
"Lokaler Benutzername verwendet Passwort anstatt Secret"),
]
BEST_PRACTICE_PATTERNS = [
(re.compile(r"\bntp server\b", re.I), "NTP-Server"),
(re.compile(r"\bservice timestamps\b", re.I), "Log-Zeitstempel"),
(re.compile(r"\blogging\s+\S+", re.I), "Logging-Ziel oder -Puffer"),
(re.compile(r"\bsnmp-server group\s+\S+\s+v3\s+priv\b", re.I), "SNMPv3 authPriv-Gruppe"),
(re.compile(r"\bbanner\s+(login|motd)\b", re.I), "Login-Banner"),
]
def check_security(config: str) -> list[str]:
return [message for pattern, message in SECURITY_PATTERNS if pattern.search(config)]
def check_missing_hygiene(config: str) -> list[str]:
return [
f"Fehlende {description}"
for pattern, description in BEST_PRACTICE_PATTERNS
if not pattern.search(config)
]
Beispiele
Änderungsfenster-Preflight
- Führen Sie Checks auf gefährliche Befehle für das exakt einzufügende Snippet durch.
- Führen Sie Prüfungen auf doppelte IPs und Subnetz-Überlappungen für die vollständige Kandidatenkonfiguration durch.
- Bestätigen Sie, dass jede referenzierte ACL, Route-Map und Prefix-Liste existiert.
- Bestätigen Sie Rollback-Befehle und Out-of-Band-Zugriff vor jeder Änderung der Management-Ebene.
Automatisierungs-Preflight
Verwenden Sie die Validierung als blockierendes Gate, bevor Netmiko, NAPALM, Ansible oder eine Anbieter-API eine generierte Konfiguration pusht. Fail closed bei gefährlichen Befehlen und Anmeldedaten. Warnen Sie bei Lücken zu Best Practices, die außerhalb des Änderungsumfangs liegen.
Anti-Patterns
- Regex-Validierung als Geräteparser behandeln.
- Generierte Konfiguration ohne Dry-Run-Diff anwenden.
- SNMPv2-Community-Strings als Monitoring-Anforderung empfehlen.
- VTY-Blöcke mit Regex prüfen, die versehentlich über nicht zusammenhängende Abschnitte greifen kann.
- Firewall-Verhalten testen, indem ACLs deaktiviert werden, anstatt Counters/Logs zu lesen.
Siehe auch
- Agent:
network-config-reviewer - Agent:
network-troubleshooter - Skill:
network-interface-health