# Srx Ipsec Hub Spoke

> 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.

- **Type:** Skill
- **Install:** `agentstack add skill-fastrevmd-lab-fwskillsshare-srx-ipsec-hub-spoke`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [fastrevmd-lab](https://agentstack.voostack.com/s/fastrevmd-lab)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [fastrevmd-lab](https://github.com/fastrevmd-lab)
- **Source:** https://github.com/fastrevmd-lab/fwskillsshare/tree/main/skills/srx-ipsec-hub-spoke
- **Website:** https://mechub.org

## Install

```sh
agentstack add skill-fastrevmd-lab-fwskillsshare-srx-ipsec-hub-spoke
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 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 Insertion** — **routing
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.

## 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
```

| Element | Role |
|---------|------|
| 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

| Route | Purpose |
|-------|---------|
| `0.0.0.0/0 → st0.0` | Default into the tunnel — internet, hub LAN, and other spokes |
| `HUB_WAN/32 → ` | **Anti-recursion** — ESP to the hub WAN must NOT enter the tunnel |
| WAN `/30`s `→ ` | 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 → `,
> 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

| Route | Purpose |
|-------|---------|
| `192.168.2.0/24 → st0.0` | Reach/return to srx02 (also receives srx03/srx04-to-srx02 hairpin) |
| `192.168.3.0/24 → st0.1` | Reach/return to srx03 |
| `192.168.4.0/24 → st0.2` | Reach/return to srx04 |
| `0.0.0.0/0 → ` | Internet egress for de-encapsulated spoke traffic |
| WAN `/30`s `→ ` | 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 →  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 — `/32 →
> st0.0` on spokes, `/32 → ` 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

| Policy | Split tunnel | Full-tunnel backhaul |
|--------|--------------|----------------------|
| `trust → untrust` | permit | same |
| `trust → VPN` | permit | same |
| `VPN → trust` | permit | same |
| `VPN → untrust` | — | **add permit** (spoke internet egress) |
| `VPN → VPN` | — | **add 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:

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [fastrevmd-lab](https://github.com/fastrevmd-lab)
- **Source:** [fastrevmd-lab/fwskillsshare](https://github.com/fastrevmd-lab/fwskillsshare)
- **License:** Apache-2.0
- **Homepage:** https://mechub.org

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-fastrevmd-lab-fwskillsshare-srx-ipsec-hub-spoke
- Seller: https://agentstack.voostack.com/s/fastrevmd-lab
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
