agentsclimarketplace

Srx ipsec hub spoke

Skill fastrevmd-lab/fwskillsshare/skills/srx-ipsec-hub-spoke

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 srx-ipsec-hub-spoke

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

Design, configure, audit, and troubleshoot Juniper SRX static route-based IPsec hub-and-spoke. Use when handling per-spoke IKE gateways, one st0 per spoke, static routes, anti-recursion, centralized source NAT, VPN-to-untrust policy, or hub hairpinning. Use AutoVPN for changing spokes and ADVPN for direct shortcuts.

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

23.1 KB, as published. Nobody here has run it

SRX Static Point-to-Point IPsec Hub-and-Spoke (Full-Tunnel Backhaul)

Overview

Static per-spoke route-based IPsec is the simplest, most explicit way to build a hub-and-spoke overlay: each spoke is an explicitly configured peer with its own IKE gateway, IPsec VPN, st0 unit, and static route on the hub. There is no dynamic gateway, no traffic selectors, and no Auto Route Insertionrouting alone decides what each tunnel carries.

This skill applies that to full-tunnel backhaul: every spoke sends everything not local to its own LAN up its tunnel to the hub. Core principle: if traffic is not local to a spoke, it goes to the hub. The hub then source-NATs internet-bound traffic out its WAN and hairpins spoke-to-spoke traffic out the destination spoke's tunnel un-NAT'd. The motivation is centralized egress — inspect/filter/log all internet traffic at one point (UTM/IDP on the hub).

The full-tunnel changes versus a split tunnel are confined to four things: the spoke's default route into the tunnel, hub egress routing/NAT, two added hub security policies, and the hub's per-spoke static routes. Everything else is standard route-based IPsec.

Attribution. The reference topology, full-tunnel backhaul approach, and the validated set-format configuration this skill summarizes come from Jason Anderson's lab srx-p2p-ipsec-public (https://github.com/anderson-jason573/srx-p2p-ipsec-public), built on four vSRX (Junos OS 23.2R2.21) plus a Cisco IOS-XE WAN transit router. See references/source-design-summary.md.

Scope and routing

Use static tunnels for a small stable estate where every peer, st0, and route must be explicit. Use srx-autovpn-full-tunnel for many or changing spokes, srx-advpn for direct branch shortcuts, and another design when spokes need local breakout.

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.

Topology Model

                CSR1 / upstream router  (loopback = "the internet")
        WAN /30   WAN /30    WAN /30    WAN /30
           │         │          │          │
        srx01      srx02      srx03      srx04
         HUB       spoke      spoke      spoke
     192.168.1/24  .2/24      .3/24      .4/24   (LANs)

   Three static P2P tunnels, one per spoke:
     srx01 st0.0 <══> srx02 st0.0
     srx01 st0.1 <══> srx03 st0.0
     srx01 st0.2 <══> srx04 st0.0
ElementRole
Hub WAN (untrust)IKE/IPsec endpoint + internet egress; PAT target
Hub LAN (trust)Local hub subnet
Hub st0.0/1/2 (VPN)One st0 unit per spoke, all in one VPN zone
Spoke WAN (untrust)IKE/IPsec endpoint to the hub WAN IP
Spoke st0.0 (VPN)Single tunnel to the hub

All st0 units are unnumbered, point-to-point (no multipoint) — each unit terminates exactly one peer; the hub just has several. Routing is by static route, so no tunnel IP is needed. Management (fxp0) is out-of-band.

Static Hub-and-Spoke Mechanics

  • One IKE gateway per spoke, pinned by the spoke's WAN IP (address 10.0.x.2). No dynamic hostname / group-ike-id, no hostname identities.
  • IKEv2 / IPsec. Phase 1: PSK, DH group 14, SHA-256, AES-256-CBC, v2-only. Phase 2: ESP, AES-256-GCM, PFS group 14, 3600 s. Clamp tcp-mss ipsec-vpn 1350.
  • One bound st0 unit per tunnel. Hub: st0.0 (→srx02), st0.1 (→srx03), st0.2 (→srx04). Each spoke: a single st0.0 to the hub.
  • No traffic selectors. Each VPN is a plain route-based tunnel; the negotiated proxy-id defaults to 0.0.0.0/0 ↔ 0.0.0.0/0, so one SA per spoke can carry internet and inter-spoke traffic — routing, not a selector, decides what enters each st0.
  • No Auto Route Insertion. The hub needs an explicit static route to each spoke LAN (192.168.x.0/24 → st0.n). Nothing is installed automatically.
  • establish-tunnels immediately is convenient so tunnels come up without data traffic to trigger them.

Auth: lab PSK vs. production PKI. A single shared PSK keeps the focus on the topology, but is not production practice. Prefer certificate-based (PKI) auth with per-device identity, or at minimum strong, unique per-tunnel PSKs in a secrets manager with rotation.

Routing — the entire story

Because there are no traffic selectors, routing decides what each st0 carries.

Spoke

RoutePurpose
0.0.0.0/0 → st0.0Default into the tunnel — internet, hub LAN, and other spokes
HUB_WAN/32 → <underlay next-hop>Anti-recursion — ESP to the hub WAN must NOT enter the tunnel
WAN /30s → <underlay next-hop>Underlay reachability

A single route-based SA (proxy-id 0.0.0.0/0) carries all of it.

Anti-recursion is the #1 gotcha of full tunnel. The spoke default points into st0.0, but the ESP packets that carry the tunnel are destined to the hub's WAN IP. Without the more-specific host route HUB_WAN/32 → <underlay next-hop>, that ESP would follow the default into the tunnel → infinite recursion and an instant black-hole. Keep it (and the connected WAN /30) more-specific than the default.

Hub

RoutePurpose
192.168.2.0/24 → st0.0Reach/return to srx02 (also receives srx03/srx04-to-srx02 hairpin)
192.168.3.0/24 → st0.1Reach/return to srx03
192.168.4.0/24 → st0.2Reach/return to srx04
0.0.0.0/0 → <WAN next-hop>Internet egress for de-encapsulated spoke traffic
WAN /30s → <WAN next-hop>Reach each spoke's WAN IP to build its tunnel

Spoke-to-spoke needs no special tunnel config: srx02→srx03 follows srx02's default into st0.0, arrives at the hub, matches the hub's 192.168.3.0/24 → st0.1 route, and leaves on the srx03 tunnel. Because all st0 units are in the hub's VPN zone, that hairpin is an intra-zone VPN → VPN flow.

Caveat — competing management default (gotcha #2, ECMP trap). Many vSRX images carry 0.0.0.0/0 → <mgmt-gw> via fxp0 in inet.0. Adding a second 0.0.0.0/0 does not override it — Junos installs both as ECMP, so half the traffic leaks out fxp0 and NAT / the untrust policy never applies. Production fix: put fxp0 in a management routing-instance. Lab shortcut (validated): route the specific internet destination — <sim-internet>/32 → st0.0 on spokes, <sim-internet>/32 → <WAN nh> on the hub — plus 192.168.0.0/16 → st0.0 on each spoke for hub-LAN and spoke-to-spoke. These stay more-specific than the management default and exercise the full data path.

Hub NAT and Security Policies

Source NAT (internet egress only)

set security nat source rule-set VPN-BACKHAUL from zone VPN
set security nat source rule-set VPN-BACKHAUL to zone untrust
set security nat source rule-set VPN-BACKHAUL rule SNAT-INTERNET match source-address 192.168.0.0/16
set security nat source rule-set VPN-BACKHAUL rule SNAT-INTERNET match destination-address 0.0.0.0/0
set security nat source rule-set VPN-BACKHAUL rule SNAT-INTERNET then source-nat interface

Scoped from zone VPN to zone untrust, so it matches only internet egress. All spoke tunnels are in the VPN zone, so one rule-set covers every spoke. Spoke-to-spoke (VPN → VPN) and spoke-to-hub-LAN (VPN → trust) never match and stay un-NAT'd — real private IPs preserved between sites.

Hub-LAN hosts to the internet are trust → untrust and are not covered. Add a parallel trust → untrust rule to make the hub the NAT egress for its own LAN.

Security policies

PolicySplit tunnelFull-tunnel backhaul
trust → untrustpermitsame
trust → VPNpermitsame
VPN → trustpermitsame
VPN → untrustadd permit (spoke internet egress)
VPN → VPNadd permit (spoke-to-spoke hairpin across st0 units)

All tunnel interfaces share one VPN zone, so the spoke-to-spoke hairpin (srx02's st0.0 → srx03's st0.1) is an intra-zone VPN → VPN flow — one policy covers every spoke pair. Return traffic is stateful — no reverse policy. On the spoke, all LAN egress now exits via zone VPN (st0.0), so the spoke's trust → VPN policy must permit the full backhaul scope (destination-address any or the intended backhauled prefixes) — a policy scoped to the hub LAN would leave the tunnel up while user internet traffic is silently denied. The spoke's trust → untrust becomes dead (no local breakout) but is harmless.

Config Skeleton (set format)

PSK is a placeholder substituted at deploy time from a git-ignored secrets file — never commit it.

Hub (one block per spoke; srx02 shown)

# --- Tunnel interfaces, one unit per spoke (P2P, unnumbered) ---
set interfaces st0 unit 0 family inet     # -> srx02
set interfaces st0 unit 1 family inet     # -> srx03
set interfaces st0 unit 2 family inet     # -> srx04

# --- Shared IKE/IPsec proposals & policies ---
set security ike proposal IKE-PROP authentication-method pre-shared-keys
set security ike proposal IKE-PROP dh-group group14
set security ike proposal IKE-PROP authentication-algorithm sha-256
set security ike proposal IKE-PROP encryption-algorithm aes-256-cbc
set security ike proposal IKE-PROP lifetime-seconds 86400
set security ike policy IKE-POL proposals IKE-PROP
set security ike policy IKE-POL pre-shared-key ascii-text "$IPSEC_PSK"
set security ipsec proposal IPSEC-PROP protocol esp
set security ipsec proposal IPSEC-PROP encryption-algorithm aes-256-gcm
set security ipsec proposal IPSEC-PROP lifetime-seconds 3600
set security ipsec policy IPSEC-POL perfect-forward-secrecy keys group14
set security ipsec policy IPSEC-POL proposals IPSEC-PROP

# --- Per-spoke gateway (pinned by spoke WAN IP) + VPN bound to its st0 unit ---
set security ike gateway GW-srx02 ike-policy IKE-POL
set security ike gateway GW-srx02 address 10.0.1.2
set security ike gateway GW-srx02 external-interface ge-0/0/0.0
set security ike gateway GW-srx02 version v2-only
set security ipsec vpn VPN-srx02 bind-interface st0.0
set security ipsec vpn VPN-srx02 ike gateway GW-srx02
set security ipsec vpn VPN-srx02 ike ipsec-policy IPSEC-POL
set security ipsec vpn VPN-srx02 establish-tunnels immediately
# ... repeat GW-srx03/VPN-srx03 -> st0.1, GW-srx04/VPN-srx04 -> st0.2 ...
set security flow tcp-mss ipsec-vpn mss 1350

# --- Zones (all st0 units in the VPN zone) ---
set security zones security-zone untrust host-inbound-traffic system-services ike
set security zones security-zone untrust interfaces ge-0/0/0.0
set security zones security-zone trust interfaces ge-0/0/1.0
set security zones security-zone VPN host-inbound-traffic system-services ping
set security zones security-zone VPN interfaces st0.0
set security zones security-zone VPN interfaces st0.1
set security zones security-zone VPN interfaces st0.2

# --- Hub security policies (full-tunnel: add VPN->untrust egress + VPN->VPN hairpin) ---
# (source-NAT rule-set SNAT-INTERNET, zone VPN->untrust, is shown in "Hub NAT and Security Policies")
set security policies from-zone trust to-zone untrust policy trust-untrust match source-address any
set security policies from-zone trust to-zone untrust policy trust-untrust match destination-address any
set security policies from-zone trust to-zone untrust policy trust-untrust match application any
set security policies from-zone trust to-zone untrust policy trust-untrust then permit
set security policies from-zone VPN to-zone untrust policy vpn-internet match source-address any
set security policies from-zone VPN to-zone untrust policy vpn-internet match destination-address any
set security policies from-zone VPN to-zone untrust policy vpn-internet match application any
set security policies from-zone VPN to-zone untrust policy vpn-internet then permit
set security policies from-zone VPN to-zone VPN policy spoke-to-spoke match source-address any
set security policies from-zone VPN to-zone VPN policy spoke-to-spoke match destination-address any
set security policies from-zone VPN to-zone VPN policy spoke-to-spoke match application any
set security policies from-zone VPN to-zone VPN policy spoke-to-spoke then permit

# --- Hub routing: explicit per-spoke LAN routes (no ARI) + egress default ---
set routing-options static route 192.168.2.0/24 next-hop st0.0
set routing-options static route 192.168.3.0/24 next-hop st0.1
set routing-options static route 192.168.4.0/24 next-hop st0.2
set routing-options static route 0.0.0.0/0 next-hop 10.0.0.1      # see ECMP caveat

Spoke (srx02 shown)

set interfaces st0 unit 0 family inet

# --- Same IKE/IPsec proposals & policies as the hub (per-device, must be defined here too) ---
set security ike proposal IKE-PROP authentication-method pre-shared-keys
set security ike proposal IKE-PROP dh-group group14
set security ike proposal IKE-PROP authentication-algorithm sha-256
set security ike proposal IKE-PROP encryption-algorithm aes-256-cbc
set security ike proposal IKE-PROP lifetime-seconds 86400
set security ike policy IKE-POL proposals IKE-PROP
set security ike policy IKE-POL pre-shared-key ascii-text "$IPSEC_PSK"
set security ipsec proposal IPSEC-PROP protocol esp
set security ipsec proposal IPSEC-PROP encryption-algorithm aes-256-gcm
set security ipsec proposal IPSEC-PROP lifetime-seconds 3600
set security ipsec policy IPSEC-POL perfect-forward-secrecy keys group14
set security ipsec policy IPSEC-POL proposals IPSEC-PROP

set security ike gateway GW-hub ike-policy IKE-POL
set security ike gateway GW-hub address 10.0.0.2          # the HUB WAN IP
set security ike gateway GW-hub external-interface ge-0/0/0.0
set security ike gateway GW-hub version v2-only
set security ipsec vpn VPN-hub bind-interface st0.0
set security ipsec vpn VPN-hub ike gateway GW-hub
set security ipsec vpn VPN-hub ike ipsec-policy IPSEC-POL
set security ipsec vpn VPN-hub establish-tunnels immediately

# --- Zones: st0.0 in the VPN zone; untrust must accept IKE ---
set security zones security-zone untrust host-inbound-traffic system-services ike
set security zones security-zone untrust interfaces ge-0/0/0.0
set security zones security-zone trust interfaces ge-0/0/1.0
set security zones security-zone VPN interfaces st0.0

# --- Policy: ALL LAN egress now exits via zone VPN — destination must be any ---
set security policies from-zone trust to-zone VPN policy LAN-TO-TUNNEL match source-address any
set security policies from-zone trust to-zone VPN policy LAN-TO-TUNNEL match destination-address any
set security policies from-zone trust to-zone VPN policy LAN-TO-TUNNEL match application any
set security policies from-zone trust to-zone VPN policy LAN-TO-TUNNEL then permit
set security policies from-zone VPN to-zone trust policy TUNNEL-TO-LAN match source-address any
set security policies from-zone VPN to-zone trust policy TUNNEL-TO-LAN match destination-address any
set security policies from-zone VPN to-zone trust policy TUNNEL-TO-LAN match application any
set security policies from-zone VPN to-zone trust policy TUNNEL-TO-LAN then permit

# Routing: default into the tunnel + ANTI-RECURSION host route to the hub WAN
set routing-options static route 0.0.0.0/0 next-hop st0.0
set routing-options static route 10.0.0.2/32 next-hop 10.0.1.1   # anti-recursion (CRITICAL)

See references/source-design-summary.md for full per-device detail.

Verification

show security ike security-associations            # one Phase 1 SA per spoke, UP
show security ipsec security-associations           # one IPsec SA per spoke, bound to st0.0/1/2
show security ipsec security-associations detail     # proxy-id 0.0.0.0/0 <-> 0.0.0.0/0 (no selectors)
show route 192.168.2.0/24                            # static, via the correct st0 unit
show security nat source rule all                    # SNAT-INTERNET hit count incrementing
show security nat source summary
show security flow session                           # spoke-src -> internet, xlated to hub WAN IP
show system core-dumps                               # must stay zero

Internet backhaul: from a spoke, ping <sim-internet> source <spoke-LAN-gw> — hub session shows the source translated to the hub WAN IP. Spoke-to-spoke: ping <other-spoke-LAN> source <spoke-LAN-gw> — hub session shows the flow entering on one st0 unit and leaving on another, zone VPN → VPN, no NAT.

Troubleshooting Matrix

StageSymptomCommon causes
UnderlayPeers can't reach each otherTransport routing/filtering; verify ping between WAN IPs
Phase 1 (IKE)No IKE SA / stuckPSK mismatch, proposal/DH mismatch, wrong peer address, IKEv1-vs-v2 mismatch
Phase 2 (IPsec)IKE up, no IPsec SAIPsec proposal/PFS mismatch, proxy-id mismatch
RoutingSpoke LAN unreachable from hubMissing/incorrect per-spoke static route to the right st0 unit (no ARI here)
Data planeTunnel up, no trafficSpoke default not into st0, st0 in wrong zone, VPN→untrust/VPN→VPN policy missing
Internet egressNAT zero hits / traffic leaksManagement-default ECMP out fxp0; NAT rule-set not VPN→untrust
RecursionTunnel flaps / black-holeMissing anti-recursion host route HUB_WAN/32
Spoke-to-spokeOne direction onlyHub missing the destination spoke's /24 → st0.n route or VPN→VPN policy
FragmentationLarge flows fail, small ones workTunnel MTU/MSS — keep/lower tcp-mss ipsec-vpn

IKE tracing: set security ike traceoptions file ike-trace / flag ike / level 15 (iked-based platforms take a numeric trace level; level detail fails commit on Junos 24.4R1 — live-verified); read show log ike-trace; renegotiate with clear security ike security-associations and clear security ipsec security-associations. Live daemon log: show log iked (modern) or show log kmd (older).

Caveats and Tradeoffs

  1. Anti-recursion route — the single most common break (see the anti-recursion callout above).
  2. Adding a spoke is a hub change — a new IKE gateway, IPsec VPN, st0 unit, and static route on the hub. The defining tradeoff of the static approach: fine for a few stable sites, painful at scale.
  3. No local breakout — all spoke internet traffic concentrates on the hub's WAN, CPU, and NAT table. Upside: centralized inspection/logging.
  4. MTU / MSS — backhauling large flows over ESP plus NAT makes fragmentation likely; keep the MSS clamp.
  5. Spoke-to-spoke hairpin enters and leaves on different st0 units (unlike AutoVPN's single shared st0.0); the shared VPN zone makes it one VPN → VPN policy.

Choose This vs. AutoVPN

Static P2P hub-spoke (this skill)AutoVPN full-tunnel (srx-autovpn-full-tunnel)
Hub gatewaysOne static gateway per spoke (by IP)One dynamic group-ike-id gateway
Hub tunnel interfacesOne st0 unit per spokeSingle shared st0.0
What scopes the tunnelRouting only — no selectorsTraffic selectors
Hub → spoke-LAN routesStatic, one per spokeAuto Route Insertion (ARI-TS)
Add a new spokeHub change: +gateway +VPN +st0 +routeZero hub change
Best forA few small, stable, explicit sitesMany or churning sites

Backhaul behavior, NAT, anti-recursion, and the management-default caveat are identical between the two. Start static for a handful of explicit sites; switch to AutoVPN when spoke count grows or churns.

If neither fits because spoke-to-spoke traffic dominates, see srx-advpn for its three-way ADVPN vs AutoVPN vs Static comparison.

Verification Checklist

  • Each spoke pinned by address <spoke-WAN-IP>; spoke pins the hub by address <HUB_WAN>
  • One st0 unit per spoke on the hub, all in the VPN zone; spoke has a single st0.0
  • Hub has an explicit 192.168.x.0/24 → st0.n route for every spoke (no ARI)
  • Spoke has 0.0.0.0/0 → st0.0 AND the anti-recursion HUB_WAN/32 host route
  • Hub egress default does not ECMP with a management default
  • Source-NAT rule-set is VPN → untrust only; VPN→untrust and VPN→VPN policies permit
  • show system core-dumps is zero

Source Notes

This original playbook was inspired by Jason Anderson's attributed srx-p2p-ipsec-public lab and checked against Juniper Junos IPsec VPN documentation. The upstream lab has no explicit license and is not included or relicensed here. See references/source-index.md and the independently written references/source-design-summary.md.

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.