agentsclimarketplace

Parsing srx configs

Skill fastrevmd-lab/fwskillsshare/skills/parsing-srx-configs

Agent skills for firewall work — parsing, auditing, converting, and running SRX. Works with Claude Code, Codex, and Hermes so far.

Install
npx -y skills add fastrevmd-lab/fwskillsshare --skill parsing-srx-configs

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Parse Juniper SRX and Junos display-set or hierarchical configurations into the shared firewall schema. Use when input contains set security, zones, policies, address-book, from-zone, to-zone, NAT rule-set, chassis cluster, logical-systems, or routing-instances, including audit, conversion, diff, summary, and explanation tasks.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

27.5 KB, as published. Nobody here has run it

Parsing Juniper SRX Configurations

Overview

Use this skill to parse Juniper SRX / Junos firewall configurations into the shared vendor-neutral firewall intermediate schema. It supports both show configuration | display set lines and hierarchical curly-brace configuration, including zones, address books, applications, security policies, NAT, logical-systems, routing-instances, interfaces, routing protocols, VPN, chassis cluster, and system settings.

Scope and routing

Use only for Juniper SRX or Junos hierarchy and display-set syntax. Hand off ASA/FTD access-list, nameif, or object network input to parsing-cisco-configs, FortiOS blocks to parsing-fortinet-configs, and PAN-OS XML or set deviceconfig to parsing-palo-configs. Verify production-bound results against current device documentation and output. Downstream consumers are the audit, conversion, and diff skills.

Runtime intake

Before starting the workflow, inspect the request, supplied artifacts, and available approved read-only evidence. If unresolved facts could materially change safety, scope, correctness, confidence, or the requested output, read references/runtime-intake.md.

For each unresolved material fact whose catalog condition is true, invoke Claude AskUserQuestion or Codex request_user_input before continuing or issuing an open-ended request. Ask at most three single-select catalog questions per round. After each response, ask another round whenever any unresolved material catalog condition remains true; continue only when none remain. Do not repeat answered questions or show the full catalog. Without a native tool, present each selected catalog question with its 2-3 labeled choices and a free-text Other path in concise plain text; do not substitute a generic checklist.

Never request secrets or unredacted customer data. Treat intake answers as task context, not approval for a live change; obtain separate explicit approval before configuration, commit, upgrade, reboot, delete, or failover actions.

Input Format Detection

SRX configs come in two formats. Detect which one:

  1. Set commands — Lines starting with set or deactivate . Example:

    set security zones security-zone trust interfaces ge-0/0/0.0
    set security policies from-zone trust to-zone untrust policy allow-web match source-address any
    
  2. Hierarchical (curly-brace) — Nested blocks with { } and ; terminators. Example:

    security {
        zones {
            security-zone trust {
                interfaces {
                    ge-0/0/0.0;
                }
            }
        }
    }
    

Detection heuristic: Check the first 2000 characters for known top-level stanza names followed by { (e.g., system {, security {, interfaces {, routing-options {). If found, treat as hierarchical. Otherwise treat as set-command format.

Hierarchical to Set Conversion

If hierarchical format is detected, mentally convert to flat set commands before parsing:

  • Track the current path as you descend into { } blocks
  • Each leaf value terminated by ; becomes: set <path> <value>
  • Handle inactive: prefix → convert to deactivate <path> Note: inactive: (hierarchical format) and deactivate (set format) are equivalent. In hierarchical parsing, strip inactive: and set enabled: false on the affected object. Handle the re-parse: strip the prefix, rebuild as a normal set line, re-tokenize to extract the target object name.
  • Handle bracket lists [val1 val2] → expand to one set command per value
  • Handle quoted strings as single tokens
  • Handle backslash escapes inside quoted strings
  • Strip block comments /* ... */

Hierarchical-to-set normalization: After conversion, normalize these impedance mismatches:

  1. range-address X to range-high Yrange-address X to Y
  2. address NAME ip-prefix CIDRaddress NAME CIDR
  3. then static-nat prefix name CIDRthen static-nat prefix CIDR
  4. then source-nat pool pool-name NAMEthen source-nat pool NAME
  5. then destination-nat pool pool-name NAMEthen destination-nat pool NAME
  6. then destination-nat ip addr Xthen destination-nat ip X

Extraction Pipeline

Parse the following sections in order. For each, read the reference files as needed.

1. Zones

Path: security.zones.security-zone.<name> Extract: zone name, interfaces list, description, host-inbound-traffic services/protocols

1b. Interfaces

Path: interfaces.<name> with units at interfaces.<name>.unit.<id>

Extract per-interface/unit:

  • IPv4 address: family inet address <cidr>
  • IPv6 address: family inet6 address <cidr>
  • DHCP client: family inet dhcp
  • VLAN tagging: vlan-tagging / flexible-vlan-tagging
  • VLAN ID per unit: vlan-id <id>
  • MTU: mtu <value>
  • Description at both physical and unit level
  • LAG membership: ether-options 802.3ad <ae-name> → set lag_parent
  • LAG master: aggregated-ether-options lacp config

Interface type derivation: ae*=lag, lo*=loopback, st0/gr-/ip-/lt-=tunnel, fxp0/fxp1/me0/em0/em1=management. Management interface zone exclusion: Remove management interfaces (fxp0, me0, em0, etc.) from security zones with a warning. Unit-0 normalization: When resolving zone membership, normalize .0 suffixed names (e.g., ge-0/0/0.0ge-0/0/0) for matching. Cluster interface exclusion: Skip only true fabric/control interfaces (fab*) and management (fxp*) from security zones with a warning. reth* (redundant Ethernet) and reth*.<unit> are normal dataplane interfaces bound to security zones in a chassis cluster — parse them as usable zone interfaces, not as excluded cluster interfaces. After all interfaces parsed, back-populate lag_members on ae interfaces.

2. Address Objects

Path: security.address-book.global.address.<name> Types to handle:

  • ip-prefix (e.g., 10.0.0.0/24) — type: "subnet"

  • dns-name — type: "fqdn"

  • range-address with to — type: "range", value: "start-end"

  • wildcard-address — type: "wildcard"

  • Plain IP with /32 — type: "host"

  • ip-prefix <cidr> / ipv6-prefix <cidr> — explicit keywords in hierarchical format (normalize away during hierarchical-to-set conversion)

Zone-attached address books — two valid forms:

  • Named books with zone attachment: security.address-book.<book-name>.address.<name> plus security.address-book.<book-name>.attach.zone.<zone>. The book name is arbitrary (operators often name it after the zone) — derive zone scope from the attach zone statement, never from the book name.
  • Legacy zone-local books: security.zones.security-zone.<zone>.address-book.address.<name> (older configs; a zone cannot use both forms at once).

Migrate both forms to global scope with a warning.

Auto-detect IP version (v4 vs v6) from the value.

3. Address Groups

Path: security.address-book.global.address-set.<name> Extract members from address and nested address-set references.

4. Service Objects (Applications)

Path: applications.application.<name> Extract: protocol (from protocol field), destination port (from destination-port), source port if present, ICMP type/code, inactivity-timeout, description.

Map protocol values: 6 or tcp → TCP, 17 or udp → UDP, 1 or icmp → ICMP.

5. Application Mapping (L7 → Canonical)

JunOS uses predefined junos-* applications that are matched by name in security policies. These are L7-aware on SRX and must be resolved to canonical names for cross-vendor conversion.

JunOS predefined application names to canonical:

JunOS NameProtocol/PortCanonical AppCategory
junos-httpsTCP/443httpsweb
junos-httpTCP/80httpweb
junos-sshTCP/22sshremote-access
junos-telnetTCP/23telnetremote-access
junos-ftpTCP/21ftpfile-transfer
junos-tftpUDP/69tftpfile-transfer
junos-dns-udpUDP/53dnsnetwork-mgmt
junos-dns-tcpTCP/53dnsnetwork-mgmt
junos-ntpUDP/123ntpnetwork-mgmt
junos-smtpTCP/25smtpemail
junos-smtpsTCP/587, TCP/465smtpsemail
junos-imapTCP/143imapemail
junos-imapsTCP/993imapsemail
junos-pop3TCP/110pop3email
junos-ldapTCP/389ldapauth
junos-bgpTCP/179bgpnetwork-mgmt
junos-ospfIP-89ospfnetwork-mgmt
junos-sipUDP/5060sipvoip
junos-h323TCP/1720 (+UDP/1719 RAS, TCP/1503/389/522/1731 — multi-term)h323voip
junos-ms-rpcTCP+UDP/135 (application-set)msrpcother
junos-ms-sqlTCP/1433mssqldatabase
junos-smbTCP/139, TCP/445smbfile-transfer
junos-ikeUDP/500ipsectunnel
junos-ike-natUDP/4500ipsec-nat-ttunnel
junos-pptpTCP/1723pptptunnel
junos-pingICMP (proto 1, all types)pingnetwork-mgmt
junos-icmp-pingICMP echo-requestpingnetwork-mgmt
junos-icmp-allICMP (all types)icmp-allnetwork-mgmt
junos-pingv6ICMPv6 (proto 58, all types)ping6network-mgmt
junos-icmp6-allICMPv6 (all types)icmpv6-allnetwork-mgmt
junos-nntpTCP/119nntpother
junos-rdpTCP/3389rdpremote-access
junos-syslogUDP/514syslognetwork-mgmt

Names verified against show configuration groups junos-defaults applications on Junos 24.4. Note there is no predefined junos-snmp, junos-snmptrap, junos-mysql, junos-ike-nat-t, junos-icmpv6-all, or junos-ping6 — SNMP and MySQL matching require custom applications application definitions (extract those as custom apps); the NAT-T/ICMPv6 predefined names are junos-ike-nat, junos-icmp6-all, and junos-pingv6.

Resolution in policies: When match application lists a predefined app:

  1. Look up in the table above
  2. Populate policy's apps array: { vendor_name: "junos-https", canonical: "https", confidence: 1.0, category: "web" }
  3. The services array keeps application-default or explicit port references separately

Custom applications (applications.application.<name>): These are user-defined with explicit protocol and port. Extract as service objects AND attempt canonical resolution from protocol+port. If the port matches a known app, set confidence: 0.9.

Unresolvable apps: For any application match or custom apps without a canonical mapping, set confidence: 0.0, preserve the vendor_name, and warn.

5b. Service Groups (Application Sets)

Path: applications.application-set.<name> Extract member applications and nested application-sets.

Application-Set vs Application-Group distinction:

  • Determine member types: for each member, check if it is a predefined junos-* L7 app or a user-defined port-based application
  • Application-sets containing all L7/predefined apps → promote to application_groups with canonical member names
  • Sets containing user-defined port-based apps → keep as service_groups
  • Mixed sets → split: L7 members → application_groups, port-based → service_groups

Resolve each L7 member from JunOS name to canonical before storing in application_groups.

6. Security Policies

Path: security.policies.from-zone.<src>.to-zone.<dst>.policy.<name> Also: security.policies.global.policy.<name> (global policies, src/dst zones = ["any"])

For each policy extract:

  • name and description
  • src_zones / dst_zones — from the path (or ["any"] for global)
  • src_addresses / dst_addresses — from match source-address / match destination-address
  • applications — from match application
  • actionpermit → "allow", deny → "deny", reject → "reset-both" (the schema's reject-family value). Note: SRX reject notifies the source only — TCP RST to the client, ICMP unreachable for other protocols — not both sides; emit an info warning so conversions do not overstate reset-both semantics on the target platform.
  • log_start — true if then log session-init
  • log_end — true if then log session-close
  • security_profiles — extract from then permit application-services:
    • utm-policy → profile_group
    • idp-policy → IDP profile
    • ssl-proxy → SSL proxy profile
  • disabled — true if deactivate prefix on the policy path
  • schedule — from scheduler-name
  • source_users — from match source-identity
  • Handle then count and then permit firewall-authentication as no-ops (do not misinterpret as action modifiers)

7. NAT Rules

Paths:

  • security.nat.source.rule-set.<name>.rule.<name> — source NAT
  • security.nat.destination.rule-set.<name>.rule.<name> — destination NAT
  • security.nat.static.rule-set.<name>.rule.<name> — static NAT

Extract: type, src/dst zones (from rule-set from/to), match addresses, translated source/destination/port.

Source NAT specifics:

  • then source-nat interface → translate to egress interface
  • then source-nat pool <poolname> → translate to named pool (emit as pool:<name>)

Destination NAT specifics:

  • destination-port <port> → original service match
  • then destination-nat pool <poolname> → translated destination from pool
  • Port translation lives on the pool object, not the rule: security.nat.destination.pool.<name> carries address <ip/prefix> and optional port <port> — resolve translated address AND port from the referenced pool definition (... pool <name> port <port> on the rule is not valid Junos)
  • Handle hierarchical ip addr <ip> form for inline destination translation

Static NAT specifics:

  • then static-nat prefix <cidr> → bidirectional static translation

8. Schedules

Path: schedulers.scheduler.<name> Extract: name, type (daily-except/daily), start-date, stop-date, days of week, time ranges.

9. Routing

  • Static routes (IPv4): routing-options.static.route.<prefix> with next-hop, qualified-next-hop (floating statics), or discard (null routes)

  • Static routes (IPv6): routing-options.rib.inet6.0.static.route.<prefix> — same structure

  • Routing Instances / VRF: routing-instances.<name> — extract interface membership, per-VR static routes (IPv4+IPv6), per-VR OSPF/BGP config

  • BGP: protocols.bgp — extract:

    • Local-AS, router-ID
    • Per-group: type (ebgp/ibgp), peer-as, local-address, authentication-key (presence only — redact), hold-time, keepalive
    • Per-neighbor overrides: peer-as, description, local-address, authentication-key (presence only — redact), hold/keepalive timers, next-hop-self, route-reflector-client
    • deactivate support for disabled neighbors
    • Merge group-level defaults with neighbor-level overrides
  • OSPF: protocols.ospf — extract:

    • Router-ID, reference-bandwidth (with unit parsing: g/m/k suffixes)
    • Areas: area ID, type (normal/stub/nssa with no-summary), default-cost
    • Area authentication type and key presence (redact the key value)
    • Per-interface: passive, metric, priority, hello/dead intervals, link-type (p2p/broadcast), per-interface authentication
    • Redistribute: source, metric, metric-type
    • deactivate support for disabled OSPF interfaces
    • Normalize area IDs to dotted-decimal
  • OSPFv3: protocols.ospf3 — same structure as OSPF via ospf3 instances

  • Multicast (presence flag + residual capture): flow-mode SRX does not route multicast by default, so most configs have none — but a multicast-related task has nothing to anchor on unless the parser records whether multicast routing exists at all. Mirror the control-plane-protection handling: emit a presence flag and push full detail to residual_raw. Detect and flag:

    • protocols.igmp — interfaces, version, static groups, ssm-map
    • protocols.pim — mode (sparse/dense), RP (static / auto-RP / BSR), interfaces
    • protocols.mld — IPv6 multicast equivalent of IGMP
    • forwarding-options multicast stanzas (e.g. helpers, multicast scoping)
    • routing-options.multicast / multicast scope policies

    Set system.multicast_routing { present: true, protocols: [...] } listing the families seen (e.g. ["igmp","pim"]); absent → present: false. Send the stanza detail to residual_raw. This is a presence flag so downstream skills can reason about "is this box doing multicast routing at all" — not a full multicast parse.

10. System Configuration

Path: system Extract:

  • system.host-name → hostname
  • system.domain-name → domain
  • system.name-server → DNS servers
  • system.ntp.server → NTP servers with prefer flag
  • system.services → management services: ssh, telnet, netconf, https, http
  • system.login.user → admin users with class and SSH public keys
    • Class mapping: super-user→super-admin, operator→operator, read-only→read-only
  • system.services.ssh { root-login, rate-limit, ciphers, protocol-version, connection-limit } → system.ssh (omit/null absent keys; root-login defaults to Junos deny-password when unset).
  • system.login.password { minimum-length→min_length, change-type→complexity, minimum-changes } and system.login.retry-options { tries-before-disconnect→tries, lockout-period } → system.auth.password_policy / system.auth.login_lockout. Set system.auth.root_authentication_present: true when system.root-authentication exists.

11. Infrastructure

  • Version: set version <X.Y> → metadata.source_version
  • HA Chassis Cluster: chassis.cluster — redundancy-groups, node priorities, heartbeat interfaces, fab links
  • HA MNHA: chassis.high-availability — newer HA method on SRX4600/SRX5000 platforms
  • Screen/IDS: security.screen.ids-option.<name> — TCP/UDP/ICMP/IP protections
    • Screen zone binding: for each security.zones.security-zone.<z>.screen <name>, set zones[].screen = <name>. The screen option detail continues to populate the Screen/IDS Config object.
    • Security services presence: set security_services flags true when present: services application-identification→app_id, security idp / services idp (security-package)→idp, services security-intelligence→secintel, services advanced-anti-malware→aamw, security utm→utm.
  • Control-plane / RE protection: when a stateless firewall { family inet filter <name> } is applied as an interface input filter on lo0 (interfaces lo0 unit N family inet filter input <name>), set system.control_plane_protection { re_filter_present: true, applied_to: ["lo0.<N>"] }. The filter terms still go to residual_raw; this is a presence flag, not a full parse.
  • VPN/IPsec: Full IKE/IPsec chain resolution:
    • IKE proposals: encryption, integrity, DH group, lifetime, auth method (PSK vs certificate including RSA/DSA/ECDSA)
    • IKE policies: mode, proposals list, PSK presence (mask the value as "****"), local certificate
    • IKE gateways: peer address, external interface, IKE version (v1-only/v2-only), local/remote identity
    • IPsec proposals: encryption, integrity, lifetime
    • IPsec policies: proposals list, PFS group
    • IPsec VPNs: bind-interface, IKE gateway reference, IPsec policy reference, establish-tunnels
    • Resolve full chain: ipsecVpn → ikeGateway → ikePolicy → ikeProposal(s) → ipsecPolicy → ipsecProposal(s)
    • Associate tunnel interfaces (st0, gr-, ip-) with their IPs, collect routes through tunnels
    • Canonicalize algorithm names (e.g., aes-256-cbc → aes-256, hmac-sha-256-128 → sha256)
    • Flag weak algorithms (DES/3DES, MD5, DH group ≤ 5)
  • Syslog: system.syslog.host — remote logging targets
  • DHCP Server: access.address-assignment.pool — network, address ranges (low/high), router (gateway), name-server, maximum-lease-time, domain-name. Match pools to interfaces via dhcp-local-server group bindings using IP prefix matching.
  • DHCP Relay: Two forms:
    • Legacy: forwarding-options.helpers.bootp.server
    • Modern: forwarding-options.dhcp-relay.server-group / group / active-server-group / interface Link relay server groups to per-interface dhcp_relay fields.

12. Multi-Context

Detect logical-systems.<name> and tenants.<name> in the config tree. Parse each context independently, tag all extracted items with _logical_system or _tenant.

13. Residual Config Capture

Capture all unhandled set lines. Categorize into: IDS Screens, PKI/Certificates, QoS, SNMP, VLANs, Firewall Filters, Bridge Domains, Groups, Other. Store in residual_raw for manual review.

14. Implicit Rules

After parsing all explicit policies, append:

  • Implicit: Default Deny — action: "deny", src/dst zones: ["any"], src/dst addresses: ["any"], applications: ["any"], disabled: false, _implicit: true

Implicit-rule name values (e.g. "default-deny", "Implicit: Default Deny") are free-form labels; consumers must match implicit rules on _implicit: true, never on the name.

Output Format

Present results in the intermediate schema format documented in references/intermediate-schema.md.

Note: schema sections not yet populated by this pipeline (e.g., security_profile_objects, routing_contexts) are emitted empty ([]/{}); any unhandled source constructs are captured in residual_raw rather than dropped.

Full intermediate-schema emission is optional for single live-device work. The complete JSON schema exists primarily for cross-vendor conversion and multi-config diffing. When interpreting or auditing a single live device pulled via NETCONF/MCP for an ops/audit task, it is fine to reason directly from the hierarchical config and skip full schema emission — extract the sections relevant to the question. Emit the full schema when the parse will feed firewall-config-conversion, firewall-config-diff, or another config for comparison.

Parser Quality Gates

Before returning a parse, run these common quality gates and include the results in the response:

  1. Format and scope detection — report detected vendor, platform family, config format, version clues, virtual context names (VDOM/vsys/logical-system/routing-instance), and whether input appears complete or partial.
  2. Schema conformance — emit the vendor-neutral JSON sections defined in references/intermediate-schema.md; use empty arrays/objects for absent sections rather than omitting expected top-level keys.
  3. Object counts — summarize counts for zones, interfaces, address objects/groups, service/application objects/groups, policies, NAT rules, routes, VPNs, HA, admin users, and residual blocks.
  4. Reference resolution — list unresolved object, service/application, zone/interface, profile, route, VPN, and NAT references with source rule/context where possible.
  5. Ordering preservation — preserve security policy order, NAT order, route order when relevant, and inherited/pre/post/global ordering metadata with _rule_index or a vendor-specific context field.
  6. State preservation — preserve disabled/inactive objects and rules, comments/descriptions, tags, schedules/time-ranges, negation flags, logging settings, and profile attachments.
  7. Residual capture — put unsupported or ambiguous source lines/blocks into residual_raw with enough context for manual review. Do not silently drop unknown syntax.
  8. Warnings and assumptions — populate metadata.warnings with parser limitations, partial-input assumptions, ambiguous conversions, and version-specific caveats.
  9. Conversion readiness — if the user asks for migration/conversion, explicitly separate parsed facts from proposed target-platform design choices and call out non-isomorphic features.

A high-quality parse is not just valid JSON: it must make uncertainty visible. Prefer a complete parse with warnings and residuals over a clean-looking parse that hides unsupported constructs.

Analysis Checks

After extraction, run these checks and report findings:

  1. Unused objects — address/service objects not referenced by any policy
  2. Shadowed policies — rules that can never match because an earlier rule fully covers them
  3. Overly permissive — rules with any/any source+destination or any/any zone+address+application
  4. Missing logging — permit rules without log session-close
  5. Disabled policies — rules with deactivate prefix
  6. Duplicate objects — different names, same value
  7. Empty groups — address-sets or application-sets with no members

Reference Files

  • references/config-format.md — Detailed SRX config syntax reference
  • references/intermediate-schema.md — Output schema specification
  • references/parsing-patterns.md — Edge cases, predefined apps, and name sanitization
  • references/example-sample-parse.md — Worked end-to-end example (input config → parsed JSON)
  • references/fixture-minimal-input.md — Minimal parser fixture input
  • references/fixture-expected-output.json — Expected high-level intermediate-schema output for the minimal fixture

Secret Handling

Never emit secrets raw. IKE/VPN pre-shared keys, routing-protocol authentication keys (BGP/OSPF), and user password hashes must be masked as "****" (or reduced to a presence flag) with a metadata.warnings entry noting the redaction — matching the shared-schema convention ("psk": "****").

Common Pitfalls

  1. Do not skip hierarchical-to-set normalization; inactive prefixes, bracket lists, and quoted strings affect extraction.
  2. Zone-local address books are valid in older designs; migrate or normalize to global only with a warning.
  3. Logical-systems and routing-instances are separate contexts; preserve them instead of merging names blindly.
  4. Policy matching depends on NAT order and translated addresses; preserve both faithfully for downstream interpretation.
  5. Management (fxp*), fabric (fab*), and HA control interfaces need special handling and should not be naively treated as ordinary security-zone interfaces. By contrast, reth* redundant-Ethernet interfaces ARE ordinary dataplane interfaces in a chassis cluster and must be parsed as zone interfaces — do not exclude them.

Verification Checklist

  • Input vendor/platform and config format were detected correctly
  • All major object counts are reported: zones, interfaces, addresses, services/applications, policies, NAT, routes, VPN, HA, and system settings
  • Output conforms to references/intermediate-schema.md
  • Disabled/inactive rules and objects are preserved with explicit state
  • Unresolved references, unsupported blocks, and parser assumptions are listed in metadata.warnings and/or residual_raw
  • Rule order and NAT order are preserved with _rule_index or equivalent ordering metadata
  • Cross-vendor conversion caveats are called out before suggesting target-platform config
  • No raw secrets in output — PSKs masked as "****", routing-protocol passwords/keys reduced to presence flags with warnings

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.