Network Config Validation

affaan-m/ECC/skills/network-config-validation

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775无许可证275K 个星标收录于 2026年10月9日更新于 2026年10月9日仓库4天前更新

Pre-deployment checks for router and switch configuration, including dangerous commands, duplicate addresses, subnet overlaps, stale references, management-plane risk, and IOS-style security hygiene. Use when reviewing a router or switch configuration before deployment.

AI 生成的概览

在部署前审查路由器和交换机配置,检查危险命令、地址冲突、失效引用和安全缺口。

功能
为 Cisco IOS/IOS-XE 风格的路由器和交换机配置提供分层部署前校验指导。它给出 Python 正则与 ipaddress 代码片段,用于标记破坏性命令、重复 IP 地址、子网重叠、未定义的 ACL/route-map/prefix-list 引用、管理平面弱点以及安全卫生问题。输出为带行号和原因的发现列表,定位为预检警告而非完整解析器。
适用场景
适用于在变更窗口前审查路由器或交换机配置,或在自动化将生成的配置推送到生产设备之前进行校验。也适合审计模板生成的配置,以及为网络自动化构建轻量级预检。
运行要求
该技能不附带脚本,仅为说明和示例代码。运行示例需要 Python 3 环境及标准库模块 re、ipaddress 和 collections。无需凭据或网络访问。

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:

  1. Destructive commands.
  2. Credential and management-plane exposure.
  3. Duplicate addresses and overlapping subnets.
  4. Stale references to ACLs, route-maps, prefix-lists, and interfaces.
  5. Operational hygiene such as NTP, timestamps, remote logging, and banners.

Dangerous Command Detection

python
import re
DANGEROUS_PATTERNS: list[tuple[re.Pattern[str], str]] = [    (re.compile(r"\breload\b", re.I), "reload causes downtime"),    (re.compile(r"\berase\s+(startup|nvram|flash)", re.I), "erases persistent storage"),    (re.compile(r"\bformat\b", re.I), "formats a device filesystem"),    (re.compile(r"\bno\s+router\s+(bgp|ospf|eigrp)\b", re.I), "removes a routing process"),    (re.compile(r"\bno\s+interface\s+\S+", re.I), "removes interface configuration"),    (re.compile(r"\baaa\s+new-model\b", re.I), "changes authentication behavior"),    (re.compile(r"\bcrypto\s+key\s+(zeroize|generate)\b", re.I), "changes device SSH keys"),]
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

Duplicate IPs And Subnet Overlaps

python
import ipaddressimport refrom 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

Management-Plane Checks

Parse VTY blocks by section so access-class checks do not spill across unrelated lines.

python
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 allows Telnet; require SSH only.")        if not re.search(r"\baccess-class\s+\S+\s+in\b", block, re.I):            issues.append("VTY block has no inbound access-class source restriction.")        if not 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

python
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"),]
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"Missing {description}"        for pattern, description in BEST_PRACTICE_PATTERNS        if not pattern.search(config)    ]

Examples

Change-Window Preflight

  1. Run dangerous-command checks on the exact snippet to be pasted.
  2. Run duplicate IP and subnet overlap checks against the full candidate config.
  3. Confirm every referenced ACL, route-map, and prefix-list exists.
  4. 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.

See Also

  • Agent: network-config-reviewer
  • Agent: network-troubleshooter
  • Skill: network-interface-health

来源与署名

来源:affaan-m/ECC位于skills/network-config-validation提交ef648e0

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架