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 從公開儲存庫中收錄這些內容。

檢舉或申請下架