# Srx Autovpn Full Tunnel

> Design, configure, audit, and troubleshoot Juniper SRX AutoVPN full-tunnel hub backhaul. Use when handling group-ike-id gateways, traffic selectors, ARI, shared st0, anti-recursion routes, source NAT, VPN hairpinning, NAT-T, or Junos 24.4R1+ PSK and 0.0.0.0/0 commit errors. Use ADVPN for direct spoke shortcuts.

- **Type:** Skill
- **Install:** `agentstack add skill-fastrevmd-lab-fwskillsshare-srx-autovpn-full-tunnel`
- **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-autovpn-full-tunnel
- **Website:** https://mechub.org

## Install

```sh
agentstack add skill-fastrevmd-lab-fwskillsshare-srx-autovpn-full-tunnel
```

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

## About

# SRX AutoVPN Full-Tunnel Backhaul

## Overview

AutoVPN lets one hub gateway accept IPsec connections from any number of spokes
with **no per-spoke hub configuration**. *Full-tunnel backhaul* is the design
choice to send **everything a spoke does not own locally** up the tunnel to the
hub, instead of the conventional split tunnel (only hub-LAN traffic in the
tunnel, internet broken out locally, no spoke-to-spoke).

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 back out the tunnel un-NAT'd. The motivation is
**centralized egress** — all internet traffic can be inspected, filtered, and
logged at one point (UTM/IDP on the hub).

The full-tunnel changes are confined to four things: the **traffic selector
scope**, **spoke routing**, **hub egress routing/NAT**, and **two added hub
security policies**. Everything else — IKE/IPsec parameters and the AutoVPN
dynamic-gateway mechanics — is standard AutoVPN.

> **Attribution.** The reference topology, full-tunnel backhaul approach, and the
> validated `set`-format configuration this skill summarizes come from Jason
> Anderson's lab `srx-autovpn-backhaul-public`
> (https://github.com/anderson-jason573/srx-autovpn-backhaul-public), built and
> validated 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 this design when all spoke internet and inter-spoke traffic must traverse a centralized hub. Use `srx-ipsec-hub-spoke` for a small explicit estate, `srx-advpn` when direct spoke shortcuts are required, 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)

   AutoVPN: all spokes terminate on the hub's single st0.0.
```

| Element | Role |
|---------|------|
| Hub WAN (`untrust`) | IKE/IPsec endpoint + internet egress; PAT target |
| Hub LAN (`trust`) | Local hub subnet |
| Hub `st0.0` (`VPN`) | One bound tunnel interface for **all** spokes |
| Spoke WAN (`untrust`) | IKE/IPsec endpoint to the hub WAN IP |
| Spoke `st0.0` (`VPN`) | Single tunnel to the hub |
| Underlay | Any IP transport that lets each spoke WAN reach the hub WAN |

`st0` units are **unnumbered, point-to-point** (no `multipoint` keyword) —
required for traffic selectors. Management (`fxp0`) is out-of-band and never
carries tunnel traffic.

## AutoVPN Mechanics

- **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`
  to absorb ESP overhead.
- **Dynamic hub gateway.** `dynamic hostname ` + `dynamic ike-user-type
  group-ike-id` makes the hub accept any spoke presenting an IKE ID under
  `*.`. Each spoke sets `local-identity hostname srxNN.` and pins
  the hub with `remote-identity hostname srx01.`.
- **Single bound tunnel.** Every spoke terminates on the hub's one `st0.0`; there
  is no per-spoke `st0` unit on the hub.
- **Auto Route Insertion (ARI).** When a spoke SA comes up, the hub
  automatically installs a route to that spoke's LAN `/24` via `st0.0` (protocol
  `ARI-TS`). The hub needs **no static routes to spoke LANs**.
- **Traffic selectors** define which source/destination prefixes each end carries
  — the lever full tunnel pulls.

> **Version constraint (field-verified): `ike-user-type` + IKEv2 + PSK does not
> commit on current Junos.** On vSRX3 24.4R1.9 and 25.4R1.12, pairing `dynamic
> ike-user-type` (**group-ike-id or shared-ike-id**) with `authentication-method
> pre-shared-keys` fails commit with:
> `When dynamic ike-user-type is configured, IKEv2 with authentication-method
> pre-shared-key is not allowed`. A zero-touch PSK AutoVPN hub cannot be built
> on these images. Pick the path **before** writing config:
>
> - **PSK** → drop `ike-user-type` entirely and configure **per-spoke IKEv2
>   gateways** on the hub, each pinned by a unique `remote-identity hostname
>   .`. Functionally the same full-tunnel hub-and-spoke
>   (field-verified with 6 spokes), but zero-touch is lost: adding a spoke
>   means adding a hub gateway/VPN/`st0` unit.
> - **Zero-touch `group-ike-id`** → use **certificate (PKI) authentication**.
>   See the `srx-advpn` skill's PKI-enrollment section for the workflow.
>
> The original reference lab (Junos 23.2R2) committed `group-ike-id` + PSK;
> treat that combination as legacy-image-only.

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

## Traffic Selectors — the core

Full tunnel is fundamentally a traffic-selector change: the spoke must *request*
the whole internet, and the hub must *accept* any destination.

| Selector | Split tunnel | Full-tunnel backhaul |
|----------|--------------|----------------------|
| Spoke `local-ip` | `192.168.x.0/24` (its LAN) | same |
| Spoke `remote-ip` | `192.168.1.0/24` (hub LAN only) | **the full IPv4 space — as two `/1` halves, see below** |
| Hub `local-ip` | `192.168.1.0/24` (hub LAN) | **`0.0.0.0/0`** |
| Hub `remote-ip` | `192.168.0.0/16` (spoke summary) | same |

**Commit blocker (field-verified on 24.4R1.9 / 25.4R1.12): the literal spoke
`remote-ip 0.0.0.0/0` is rejected when the gateway is pinned by a static
`address`** — the normal spoke case:
`Remote-ip 0.0.0.0/0 in traffic-selector is not supported when address is
configured under ike gateway`. Split the default into two halves that avoid
the literal `0.0.0.0/0` but cover the same space:

```
set security ipsec vpn SPOKE-VPN traffic-selector TS-LO local-ip 192.168.x.0/24 remote-ip 0.0.0.0/1
set security ipsec vpn SPOKE-VPN traffic-selector TS-HI local-ip 192.168.x.0/24 remote-ip 128.0.0.0/1
```

Both halves commit cleanly and bring up two child SAs per spoke.

Two facts that surprise people:

1. **Hub `local-ip 0.0.0.0/0` does NOT create a default route via `st0.0`.**
   The per-spoke `/24` the hub installs comes from the *other* selector axis:
   hub `remote-ip 192.168.0.0/16` narrowed by the spoke's `local-ip
   192.168.x.0/24` = the spoke's specific `/24`, and **ARI keys off that
   narrowed remote selector**, so the hub installs clean per-spoke `/24`
   routes. The broad axis (hub `local-ip 0.0.0.0/0` ∩ spoke `remote-ip`
   wildcard) never becomes a hub route.
2. **Spoke-to-spoke needs no extra selector config.** With hub `local-ip
   0.0.0.0/0`, the inbound SA from spoke A already accepts spoke B's subnet as a
   destination, and the outbound SA to spoke B already accepts spoke A as source.

### Hub `remote-ip`: specific supernet vs. `0.0.0.0/0` wildcard

This is a **different axis** from the `0.0.0.0/0` used on the spoke `remote-ip` /
hub `local-ip` above — do not conflate them. The hub `remote-ip` controls which
spoke prefixes the hub will accept (and, via ARI, which routes appear).

| | Supernet (`192.168.0.0/16`) | Wildcard (`0.0.0.0/0`) |
|---|---|---|
| Use when | Spoke LANs summarize cleanly | Spoke LANs discontiguous / unsummarizable |
| Hub-side guardrail | Yes — IKE rejects prefixes outside the summary | None — hub trusts every spoke |
| Zero-touch hub | Mostly (new out-of-summary LAN forces a widen) | Fully |
| Blast radius if a spoke is rogue | Contained | Large — a spoke could advertise the hub LAN or another site's prefix; ARI would install it (route hijack). (ARI never installs a `0.0.0.0/0` selector, so a rogue *default* is not the risk — rogue specifics are.) |

Default to the **supernet** whenever addressing permits; it keeps the guardrail.
Use the wildcard only when there is genuinely no summarizable scheme, and push the
guardrail to per-spoke security policy/filtering instead.

Two caveats regardless of choice:
- **Spokes must propose their specific `/24`, not `0.0.0.0/0`** — else the
  negotiated selector stays `0.0.0.0/0` and ARI has no specific prefix to install.
- **Overlapping spoke subnets are not solved by selectors** — that is a NAT
  problem (static/twice-NAT at the colliding spoke), not a VPN problem.

## Routing Changes

### Spoke

| | Split tunnel | Full-tunnel backhaul |
|---|---|---|
| Tunnel route | `192.168.1.0/24 → st0.0` | **`0.0.0.0/0 → st0.0`** (default into tunnel) |
| Hub WAN host route | `HUB_WAN/32 → ` | **same — and now CRITICAL** |
| WAN `/30` routes | via underlay | same |

> **Anti-recursion is the #1 gotcha of full tunnel.** The spoke default now
> points into `st0.0`, but the ESP packets that *carry* the tunnel are destined to
> the hub's WAN IP. If that traffic also followed the default into the tunnel you
> get infinite recursion and an instant black-hole. Keep the host route
> `HUB_WAN/32 → ` (and the connected WAN `/30`) **more-specific**
> than the new default.

### Hub

| | Split tunnel | Full-tunnel backhaul |
|---|---|---|
| WAN `/30` routes | via underlay | same |
| Spoke LAN routes | ARI `192.168.x.0/24 → st0.0` | same (ARI) |
| Default route | none | **add `0.0.0.0/0 → `** (egress for de-encapsulated internet traffic) |

> **Caveat — competing management default (ECMP trap).** Many vSRX images carry a
> management default `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 next-hops as **ECMP**,
> so half the traffic wrongly egresses `fxp0` and NAT / the `untrust` policy never
> applies. *Removing* the management default risks cutting OOB access.
> - **Production fix:** put `fxp0` in a dedicated **management routing-instance**
>   so `inet.0`'s default can legitimately point into the WAN/tunnel.
> - **Lab shortcut:** route the specific internet destination instead
>   (`/32 → st0.0` on spoke, `/32 → ` on hub),
>   plus `192.168.0.0/16 → st0.0` on each spoke for hub-LAN and spoke-to-spoke.
>   Being more-specific than the management default, these exercise the full data
>   path without disturbing management.

## Hub NAT and Security Policies

### Source NAT (internet egress only)

PAT spoke private sources to the hub's WAN egress IP so the upstream has an
address to return to. **Scope the rule-set `from zone VPN to zone untrust`** so it
matches only internet egress — spoke-to-spoke (`VPN → VPN`) and spoke-to-hub-LAN
(`VPN → trust`) never match and stay un-NAT'd, preserving real private IPs between
sites.

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

> Hub-LAN hosts to the internet are `trust → untrust` and are **not** covered.
> Add a parallel `trust → untrust` source-NAT rule if the hub should also be 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) |

Return traffic for both NAT'd internet and inter-spoke flows is handled by the
stateful session table — no reverse policy needed. 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 split-tunnel policy scoped to the hub LAN
would silently drop internet-bound traffic at the spoke. The spoke's
`trust → untrust` policy becomes dead (no local breakout) but is harmless to
leave.

## Config Skeleton (hub, `set` format)

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

```
# --- Tunnel interface (P2P, unnumbered) ---
set interfaces st0 unit 0 family inet

# --- IKE Phase 1 ---
set security ike proposal AUTOVPN-IKE-PROP authentication-method pre-shared-keys
set security ike proposal AUTOVPN-IKE-PROP dh-group group14
set security ike proposal AUTOVPN-IKE-PROP authentication-algorithm sha-256
set security ike proposal AUTOVPN-IKE-PROP encryption-algorithm aes-256-cbc
set security ike proposal AUTOVPN-IKE-PROP lifetime-seconds 86400
set security ike policy AUTOVPN-IKE-POL proposals AUTOVPN-IKE-PROP
set security ike policy AUTOVPN-IKE-POL pre-shared-key ascii-text "$AUTOVPN_PSK"
# Dynamic gateway — accepts any spoke whose IKE ID is *.homelab.local
# NOTE: on Junos 24.4R1+/25.4R1 the 'dynamic ike-user-type' line below + PSK
# will NOT commit — see the version-constraint callout (per-spoke gateways for
# PSK, or certificate auth for zero-touch group-ike-id).
set security ike gateway AUTOVPN-HUB-GW ike-policy AUTOVPN-IKE-POL
set security ike gateway AUTOVPN-HUB-GW dynamic hostname homelab.local
set security ike gateway AUTOVPN-HUB-GW dynamic ike-user-type group-ike-id
set security ike gateway AUTOVPN-HUB-GW dynamic reject-duplicate-connection
set security ike gateway AUTOVPN-HUB-GW local-identity hostname srx01.homelab.local
set security ike gateway AUTOVPN-HUB-GW external-interface ge-0/0/0.0
set security ike gateway AUTOVPN-HUB-GW version v2-only

# --- IPsec Phase 2 ---
set security ipsec proposal AUTOVPN-IPSEC-PROP protocol esp
set security ipsec proposal AUTOVPN-IPSEC-PROP encryption-algorithm aes-256-gcm
set security ipsec proposal AUTOVPN-IPSEC-PROP lifetime-seconds 3600
set security ipsec policy AUTOVPN-IPSEC-POL perfect-forward-secrecy keys group14
set security ipsec policy AUTOVPN-IPSEC-POL proposals AUTOVPN-IPSEC-PROP
set security ipsec vpn AUTOVPN-HUB bind-interface st0.0
set security ipsec vpn AUTOVPN-HUB ike gateway AUTOVPN-HUB-GW
set security ipsec vpn AUTOVPN-HUB ike ipsec-policy AUTOVPN-IPSEC-POL
# Full-tunnel selector: hub local-ip 0.0.0.0/0 accepts ANY destination from spokes
set security ipsec vpn AUTOVPN-HUB traffic-selector TS-ALL local-ip 0.0.0.0/0
set security ipsec vpn AUTOVPN-HUB traffic-selector TS-ALL remote-ip 192.168.0.0/16
set security flow tcp-mss ipsec-vpn mss 1350

# --- Zones (st0.0 in its own 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

# --- Routing: ARI handles spoke LANs; add the egress default (see ECMP caveat) ---
set routing-options static route 0.0.0.0/0 next-hop 10.0.0.1
```

Spoke differs only in: `local-identity hostname srxNN.homelab.local`,
`remote-identity hostname srx01.homelab.local`, gateway `address `,
the **two-half selector** `local-ip 192.168.x.0/24` + `remote-ip 0.0.0.0/1` /
`128.0.0.0/1` (the literal `0.0.0.0/0` fails commit with a static gateway
`address` — see Traffic Selectors), a default route `0.0.0.0/0 → st0.0`, **and
the anti-recursion host route `HUB_WAN/32 → `**.

Two spoke prerequisites that are easy to miss (both field-verified):
- The spoke's `untrust` zone needs `host-inbound-traffic system-services ike`
  **even though the spoke initiates** — without it the NAT-T UDP-4500 return
  is dropped at host-inbound: IKE_SA_INIT (500) round-trips, then IKE_AUTH
  retransmits forever while the reply dies at the spoke's WAN zone.
- The spoke's `trust → V

…

## 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-autovpn-full-tunnel
- 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%.
