Pre-deployment checks for router and switch configs: dangerous commands, duplicate addresses, subnet overlaps, stale references, management-plane risk, and IOS-style security hygiene. USE WHEN reviewing Cisco IOS/IOS-XE snippets or script-generated config before a change window or automation run.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Pre-deployment checks for router and switch configs: dangerous commands, duplicate addresses, subnet overlaps, stale references, management-plane risk, and IOS-style security hygiene. USE WHEN reviewing Cisco IOS/IOS-XE snippets or script-generated config before a change window or automation run.
origin
community
cluster
devops-infra
version
1.0.0
Network Config Validation
Use this skill to review network configuration before a change window or before
an automation run touches production devices.
When to Use
Reviewing Cisco IOS or IOS-XE style snippets before deployment.
Auditing generated config from scripts or templates.
Looking for dangerous commands, duplicate IP addresses, or subnet overlaps.
Checking whether ACLs, route-maps, prefix-lists, or line policies are referenced
but not defined.
Building lightweight pre-flight scripts for network automation.
How It Works
Treat config validation as layered evidence, not as a complete parser. Regex
checks are useful for pre-flight warnings, but final approval still needs a
network engineer to review intent, platform syntax, and rollback steps.
Validate in this order:
Destructive commands.
Credential and management-plane exposure.
Duplicate addresses and overlapping subnets.
Stale references to ACLs, route-maps, prefix-lists, and interfaces.
Operational hygiene such as NTP, timestamps, remote logging, and banners.
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,
)
defextract_interfaces(config: str) -> list[dict[str, str]]:
results = []
current = Nonefor line in config.splitlines():
if line.startswith("interface "):
current = line.split(maxsplit=1)[1]
continuematch = IP_ADDRESS_RE.match(line)
if current andmatch:
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
deffind_duplicate_ips(config: str) -> list[str]:
ips = [entry["ip"] for entry in extract_interfaces(config)]
counts = Counter(ips)
returnsorted(ip for ip, count in counts.items() if count > 1)
deffind_subnet_overlaps(config: str) -> list[tuple[str, str]]:
networks = [ipaddress.ip_network(entry["network"]) for entry in extract_interfaces(config)]
overlaps = []
for index, left inenumerate(networks):
for right in networks[index + 1:]:
if left.overlaps(right):
overlaps.append((str(left), str(right)))
return overlaps
Management-Plane Checks
Parse VTY blocks by section so access-class checks do not spill across unrelated
lines.
import re
defiter_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]
continueif current:
if line andnot line.startswith(" "):
blocks.append("\n".join(current))
current = []
else:
current.append(line)
if current:
blocks.append("\n".join(current))
return blocks
defcheck_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 allows Telnet; require SSH only.")
ifnot re.search(r"\baccess-class\s+\S+\s+in\b", block, re.I):
issues.append("VTY block has no inbound access-class source restriction.")
ifnot re.search(r"\bexec-timeout\s+\d+\s+\d+\b", block, re.I):
issues.append("VTY block has no explicit exec-timeout.")
return issues
Security Hygiene Checks
SECURITY_PATTERNS = [
(re.compile(r"\bsnmp-server community\s+(public|private)\b", re.I),
"default SNMP community configured"),
(re.compile(r"\bsnmp-server community\s+\S+", re.I),
"SNMPv2 community string configured; prefer SNMPv3 authPriv"),
(re.compile(r"\bip ssh version 1\b", re.I),
"SSH version 1 enabled"),
(re.compile(r"\benable password\b", re.I),
"enable password is present; use enable secret"),
(re.compile(r"\busername\s+\S+\s+password\b", re.I),
"local username uses password instead of secret"),
]
BEST_PRACTICE_PATTERNS = [
(re.compile(r"\bntp server\b", re.I), "NTP server"),
(re.compile(r"\bservice timestamps\b", re.I), "log timestamps"),
(re.compile(r"\blogging\s+\S+", re.I), "logging destination or buffer"),
(re.compile(r"\bsnmp-server group\s+\S+\s+v3\s+priv\b", re.I), "SNMPv3 authPriv group"),
(re.compile(r"\bbanner\s+(login|motd)\b", re.I), "login banner"),
]
defcheck_security(config: str) -> list[str]:
return [message for pattern, message in SECURITY_PATTERNS if pattern.search(config)]
defcheck_missing_hygiene(config: str) -> list[str]:
return [
f"Missing {description}"for pattern, description in BEST_PRACTICE_PATTERNS
ifnot pattern.search(config)
]
Examples
Change-Window Preflight
Run dangerous-command checks on the exact snippet to be pasted.
Run duplicate IP and subnet overlap checks against the full candidate config.
Confirm every referenced ACL, route-map, and prefix-list exists.
Confirm rollback commands and out-of-band access before any management-plane
change.
Automation Preflight
Use validation as a blocking gate before Netmiko, NAPALM, Ansible, or vendor API
automation pushes a generated config. Fail closed on dangerous commands and
credentials. Warn on best-practice gaps that are outside the change scope.
Anti-Patterns
Treating regex validation as a device parser.
Applying generated config without a dry-run diff.
Recommending SNMPv2 community strings as a monitoring requirement.
Checking VTY blocks with regex that can accidentally span unrelated sections.
Testing firewall behavior by disabling ACLs instead of reading counters/logs.