{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreib2z7l3n44a7awh6jztq267zmff7udgmdspvr5x5bysuw2b5huy4q",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3moh6h6ndpyk2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreigsb2nsn7uuegybtyx67cwmfrdzzlxawkldldyyjpqjdbrqtfli6i"
    },
    "mimeType": "image/webp",
    "size": 121082
  },
  "path": "/zynovex/batfish-marks-huawei-vrp-as-unsupported-so-i-built-a-source-traceable-ir-for-it-fh0",
  "publishedAt": "2026-06-17T01:06:47.000Z",
  "site": "https://dev.to",
  "tags": [
    "networking",
    "python",
    "security",
    "opensource",
    "Batfish",
    "vrp-ir",
    "https://github.com/zynovexllc/vrp-ir"
  ],
  "textContent": "If you do network automation, you reach for Batfish. And if you've ever pointed it at a Huawei box, you've hit the wall: Batfish's own source marks Huawei **VRP** as `UNSUPPORTED`. `ntc-templates` helps, but only for `display` _show-command_ output — there's no open parser for the saved `display current-configuration` file. And `ciscoconfparse2` is Cisco-shaped and only gives you an integer line number, not field-level provenance.\n\nSo for anyone doing Huawei **acceptance / audit** work, a basic capability was just missing: turn a saved config into a structured model you can reason about, where you can always trace a value back to the exact line it came from.\n\nThat's the gap vrp-ir fills.\n\n##  Provenance is the whole point\n\n`vrp-ir` parses a Huawei VRP/USG config into a typed model where **every parsed value carries a`SourceRef` back to its `file:line`**:\n\n\n\n    from vrp_ir import parse_file\n\n    cfg = parse_file(\"edge-fw.cfg\")\n    ip = cfg.interfaces[0].ipv4[0]\n    print(ip.address.value, ip.prefix_length.value)  # 10.10.10.1 24\n    print(ip.address.source)                          # edge-fw.cfg:11  <- provenance\n\n\nWhen a value looks wrong, you jump straight to the line — you don't grep the raw config. That sounds small until you're reviewing a 4,000-line firewall dump and every claim in your report needs to be defensible.\n\n##  From IR to a line-cited security audit\n\nProvenance pays off the moment you turn the IR into findings. `vrp-ir audit` runs 13 security acceptance checks, and **every finding cites the exact config line** it's based on:\n\n\n    $ vrp-ir audit edge-fw.cfg\n    ### FW-DEFAULT-DENY [CRITICAL] — default action denies unmatched traffic\n    Default action is 'permit': all traffic matching no rule is allowed.\n    Evidence:\n    - edge-fw.cfg:14 — default action permit\n\n\nThe checks cover the boring-but-deadly stuff: permit-any rules, a non-default permit default action, cleartext management (Telnet/HTTP), VTY accepting Telnet or missing an inbound ACL, weak SSH ciphers (CBC/3DES/DES), local AAA users with Telnet, address-sets that resolve to `0.0.0.0/0`, and HRP consistency.\n\nAnd because `--strict` exits non-zero on any failure, it drops straight into CI as an acceptance gate:\n\n\n    $ vrp-ir audit edge-fw.cfg --strict || echo \"acceptance failed\"\n\n\nNo more \"the report says it's fine\" with nothing to point at — each line of the report points at a line of the config.\n\n##  Design choices\n\n  * **Zero-dependency core** , Python 3.9+, `pip install vrp-ir`. Easy to embed.\n  * **Reuse, don't reinvent.** It complements `ntc-templates` (show-command parsing), `napalm` (live collection) and Batfish (multi-vendor analysis) — it doesn't try to replace them.\n  * **No garbage facts.** If a value can't be parsed cleanly, it's skipped rather than surfaced wrong. Provenance or nothing.\n\n\n\n##  Where it's going — and how to help\n\nIt's `v0.6` / alpha and moving fast. Next up: SNMP communities, NTP/Syslog presence, `vsys`, and a wider real-world test corpus. The best contributions are **real, de-identified configs it parses wrong** — those become the best issues. There are a handful of `good first issue`s open right now (parsing SNMP/NTP/syslog with provenance) if you want a gentle on-ramp.\n\n`vrp-ir` is Apache-2.0 and stays that way. It's the open core of AegisTwin, a Huawei security-acceptance workbench I'm building — but the parser and the audit are useful on their own today.\n\n→ Repo + 30-second demo: https://github.com/zynovexllc/vrp-ir",
  "title": "Batfish marks Huawei VRP as unsupported — so I built a source-traceable IR for it"
}