Lessons · FortiGate IPsec S2S · ADVPN overlay
Static route-based IPsec is one parent SA and a static (or BGP) route. ADVPN adds a second object: a dynamic child SA between spokes, triggered by IKE after the hub has forwarded the first packet. Do not debug shortcuts until the parent hub-spoke overlay and iBGP are up. ADVPN 2.0 (edge discovery + dynamic BGP, FortiOS 7.4.2+) is a later design; this lab is classic ADVPN 1.0 with BGP RR.
ADVPN keeps a hub-spoke IPsec overlay as the control path, then builds spoke-to-spoke shortcut tunnels on demand. Hub phase1 is type dynamic with auto-discovery-sender enable and add-route disable. Each spoke points remote-gw 203.0.113.1, auto-discovery-receiver enable, net-device enable. Overlay iBGP AS 65001 reflects LAN prefixes without next-hop-self. First packet hairpins the hub; hub sends IKE shortcut-offer; child SA comes up; recursive lookup of BGP NH 10.10.100.2 now exits the shortcut. GUI does not expose the auto-discovery flags — finish in CLI.
Why spokes still hairpin
The day-one ticket is always the same: “IPsec is up, so spoke-to-spoke should be direct.” Wrong. A green parent SA to the hub only proves the overlay underlay. Direct spoke-to-spoke is a different SA, created after three other things are true: the hub is allowed to send shortcut offers, the spoke is allowed to receive them, and overlay routing still lists the remote spoke overlay IP as BGP next-hop so the kernel has something to resolve via the new child.
Three hairpin-forever states look identical in IPsec Monitor (parent up, no child):
- Hub missing
auto-discovery-sender enable— IKE never sends a shortcut-offer, even when spoke-to-spoke traffic transits. - Spoke missing
auto-discovery-receiver enable— offer arrives, spoke ignores it. - Hub iBGP
next-hop-self enable— spokes learn10.22.0.0/24 via 10.10.100.254(the hub). Recursive lookup never points at Spoke2. Shortcut, if it even forms, is unused.
IPsec Monitor showing advpn-hub / spoke1 up is the parent. A shortcut is a child name (spoke1_0 or similar) that appears only after spoke-to-spoke traffic and a successful IKE offer. Do not “add a static spoke-to-spoke tunnel” to fake ADVPN — that is a mesh, and it does not scale.
Concept — hub-spoke overlay
ADVPN is a hub-and-spoke IPsec fabric that can later shortcut. Every spoke has one (or more) parent tunnels to the hub. The hub phase1 is type dynamic so N spokes share one object. Overlay addresses live on the tunnel interfaces. Dynamic routing — lab is iBGP — advertises each site LAN across that overlay. That is the control plane. The data plane for spoke-to-spoke starts as a hairpin and only then becomes a shortcut.
Read the solid lines first. Those are the parent overlay. The dashed magenta line is a child SA that IKE creates after spoke-to-spoke traffic transits the hub.
Hub-spoke IPsec is the overlay. ADVPN is permission for IKE to build a shortcut on top of that overlay. Overlay BGP must leave the next-hop as the remote spoke, or the shortcut has nowhere to be used.
auto-discovery-sender
Hub. When spoke-to-spoke traffic transits, IKE may send a shortcut-offer (FortiOS INFORMATIONAL) to the initiator. Off = hairpin forever.
auto-discovery-receiver
Spoke. Accepts the offer and initiates the child SA toward the peer’s public IP. Off = offer ignored.
auto-discovery-forwarder
Intermediate hub in a hierarchical ADVPN (regional hub between spokes and a core). Lab is single-hub — leave this unset.
net-device
Classic sample: hub disable (tunnel-id as gateway), spoke enable so each shortcut is its own interface the kernel can point a /32 at.
Overlay routing is the steering plane
IKE does not install spoke LAN routes. Fortinet is explicit: ADVPN requires a dynamic routing protocol. Lab is iBGP on the overlay, one AS, hub as route reflector. Each spoke advertises its LAN. The hub reflects those prefixes to the other spokes and leaves the BGP next-hop as the originating spoke’s overlay IP.
That next-hop is the whole trick. Spoke1 learns 10.22.0.0/24 via 10.10.100.2. Until a shortcut exists, 10.10.100.2 recursively resolves via the parent tunnel to the hub. After the shortcut comes up, IKE injects a /32 (or a dedicated shortcut interface) to 10.10.100.2 via the child SA. Same BGP prefix. Better recursive resolution. Traffic leaves the hairpin without a BGP reconvergence.
| Plane | Lab object | If you get this wrong |
|---|---|---|
| Underlay | Hub WAN 203.0.113.1, Spoke1 198.51.100.11, Spoke2 198.51.100.22 | Parent IKE never comes up. Not an ADVPN ticket yet. |
| Parent IPsec | advpn-hub dynamic; spoke remote-gw 203.0.113.1 | No overlay, no BGP, no offer. |
| Overlay address | 10.10.100.0/24 — hub .254, Spoke1 .1, Spoke2 .2 | BGP source/update-source has nothing to bind to. |
| iBGP | AS 65001, hub neighbor-group + neighbor-range, route-reflector-client enable | Spokes never learn remote LANs. Hairpin has no destination. |
| Next-hop | Leave original NH. Do not set next-hop-self on the hub RR. | NH becomes the hub. Shortcut unused even if IKE builds it. |
| IKE routes | add-route disable on hub and spokes | IKE-installed kernel routes fight BGP. Shortcut steering breaks. |
BGP prefix does not change when the shortcut comes up. Only the recursive resolution of 10.10.100.2 changes. That is why next-hop-self is lethal.
Fortinet’s SD-WAN architecture note: ADVPN with BGP RR must preserve original next-hops. You cannot replace spoke LANs with a hub-originated summary and still shortcut. A hub LAN summary is fine for DC prefixes. Spoke-to-spoke needs the specific prefix + original NH. ADVPN 2.0 / dynamic BGP is the later design that drops RR; do not mix that neighbor-group with this lab’s route-reflector-client enable.
Path — first packet, then IKE offer
Order is the whole job. A shortcut cannot form before the parent, and it will not be used if overlay routing still points at the hub.
- Spoke1 and Spoke2 bring up parent IKE/IPsec to
203.0.113.1. - iBGP establishes over the overlay. Hub RR reflects
10.22.0.0/24to Spoke1 with NH10.10.100.2. - Host in
10.11.0.0/24sends to10.22.0.0/24. Spoke1 encapsulates toward the hub (only current resolution of that NH). - Hub forwards the packet to Spoke2 and, because sender is enabled, emits an IKE shortcut-offer toward Spoke1 containing Spoke2’s public IP
198.51.100.22. - Spoke1 (receiver) initiates a child SA to Spoke2. On success, IKE installs a path to
10.10.100.2via the child. Subsequent packets skip the hub.
Stop at the first stage that has no evidence. Parent down is IKE/PSK/WAN. BGP down is overlay IP or neighbor-range. No child after traffic is sender/receiver, policy, selectors, or NAT.
Hub vs spoke knobs
The GUI will let you build a dial-up IPsec named like ADVPN. It will not set the flags that make ADVPN. Fortinet admin guide: GUI does not support auto-discovery-sender, auto-discovery-receiver, auto-discovery-forwarder, or iBGP neighbor-group. Finish those in CLI.
| Knob | Hub advpn-hub | Spoke spoke1 / spoke2 |
|---|---|---|
type | dynamic (dial-up) | static, remote-gw 203.0.113.1 |
net-device | disable in the classic BGP sample (tunnel-id as gateway; tunnel-search is gone as of 7.0) | enable — each shortcut is its own interface |
add-route | disable — BGP owns overlay routes | disable |
| auto-discovery | sender enable | receiver enable |
| phase2 selectors | leave 0.0.0.0/0 | leave 0.0.0.0/0 — a LAN-to-LAN selector will not cover a shortcut SA |
| BGP | neighbor-group + neighbor-range 10.10.100.0/24, route-reflector-client enable, no next-hop-self | neighbor 10.10.100.254, advertise own LAN |
| Policy | overlay-to-overlay (and overlay-to-LAN) accept, NAT off — first packet must forward | LAN-to-overlay accept, NAT off |
A phase2 with src-subnet 10.11.0.0/24 and dst-subnet 10.1.0.0/24 is a valid static S2S. It is a broken ADVPN. Shortcut traffic is spoke-LAN to spoke-LAN, often with overlay addresses in IKE. Leave phase2 0.0.0.0/0 and constrain with firewall policy.
Do — Side A / B / C
Lab: hub WAN 203.0.113.1, Spoke1 198.51.100.11, Spoke2 198.51.100.22, overlay 10.10.100.0/24, iBGP AS 65001. One underlay. No SD-WAN members in this lesson.
Side A — underlay / reachability
-
Hub and spokes can UDP/500 and UDP/4500
From Spoke1,
203.0.113.1answers IKE. NAT-T on. If a spoke sits behind NAT, the hub still sees it as a dynamic peer; spoke-to-spoke IKE then depends on at least one side being reachable on 500/4500. Two NAT-hidden spokes with no hairpin mapping is a shortcut that will never complete — parent stays up. -
Do not publish LAN routes on the WAN
Underlay is only the three WAN addresses. Overlay IPs stay on the tunnel interfaces. If
10.11.0.0/24is already in the WAN VRF, you do not have an ADVPN problem — you have a leak.
Side B — product (IPsec, overlay, BGP, policy)
-
Hub phase1 + phase2
VPN > IPsec Tunnels can create the dial-up object. Then CLI — the GUI will not set sender. Source: FortiOS admin guide “ADVPN and shortcut paths” / “ADVPN with BGP as the routing protocol”.
VPN › IPsec Tunnels › advpn-hub
advpn-hub — custom tunnel
Source: FortiOS admin guide — GUI does not support auto-discovery-sender/receiver/forwarder. After OK, still CLI the three flags, net-device, and add-route disable. Phase2 selectors stay 0.0.0.0/0.
config vpn ipsec phase1-interface
edit "advpn-hub"
set type dynamic
set interface "wan1"
set ike-version 2
set peertype any
set net-device disable
set add-route disable
set auto-discovery-sender enable
set psksecret <lab-psk>
next
end
config vpn ipsec phase2-interface
edit "advpn-hub"
set phase1name "advpn-hub"
set auto-negotiate enable
next
end
config system interface
edit "advpn-hub"
set ip 10.10.100.254 255.255.255.255
set remote-ip 10.10.100.253 255.255.255.0
set allowaccess ping
next
end
config vpn ipsec phase1-interface
edit "spoke1"
set interface "wan1"
set ike-version 2
set peertype any
set net-device enable
set add-route disable
set auto-discovery-receiver enable
set remote-gw 203.0.113.1
set psksecret <lab-psk>
next
end
config vpn ipsec phase2-interface
edit "spoke1"
set phase1name "spoke1"
set auto-negotiate enable
next
end
config system interface
edit "spoke1"
set ip 10.10.100.1 255.255.255.255
set remote-ip 10.10.100.254 255.255.255.255
set allowaccess ping
next
end
-
Overlay iBGP — hub RR, original next-hop
Network > BGP can set AS and a neighbor. Neighbor-group, neighbor-range, and RR client are CLI. Do not enable next-hop-self on the hub group.
Network › BGP
BGP — AS 65001
Source: FortiOS “ADVPN with BGP as the routing protocol” — iBGP, neighbor-group/neighbor-range, route-reflector-client enable. Next-hop-self is not in that sample. Enabling it is the usual L3 own-goal.
config router bgp
set as 65001
set router-id 10.10.100.254
config neighbor-group
edit "advpn"
set remote-as 65001
set route-reflector-client enable
set link-down-failover enable
next
end
config neighbor-range
edit 1
set prefix 10.10.100.0 255.255.255.0
set neighbor-group "advpn"
next
end
config network
edit 1
set prefix 10.1.0.0 255.255.255.0
next
end
end
config router bgp
set as 65001
set router-id 10.10.100.1
config neighbor
edit "10.10.100.254"
set remote-as 65001
set update-source "spoke1"
set link-down-failover enable
next
end
config network
edit 1
set prefix 10.11.0.0 255.255.255.0
next
end
end
-
Firewall policy that forwards the first hairpin
Hub: overlay-to-overlay (tunnel interface or a zone that contains
advpn-hub) accept, NAT disabled, for spoke LANs. If this policy drops, the hub never forwards stage 3 and IKE never offers. Spokes: LAN to tunnel accept, NAT disabled. Source: same ADVPN BGP guide plus ordinary FortiOS policy lookup.
Side C — proof
-
Parent identity
diagnose vpn tunnel list— parentadvpn-hub/spoke1up.get router info bgp neighbors— Established to10.10.100.254/.1/.2. -
NH is the remote spoke, not the hub
On Spoke1:
get router info routing-table bgpshows10.22.0.0/24 via 10.10.100.2. If you seevia 10.10.100.254, stop and remove next-hop-self. Do not ping yet expecting a shortcut. -
Generate spoke-to-spoke, then re-list tunnels
From a host in
10.11.0.0/24(or sourced ping on Spoke1): traffic to10.22.0.1. Re-rundiagnose vpn tunnel list. You want a child (spoke1_0or similar) with remote198.51.100.22. Then the same BGP prefix recursively via that child. IKE debug if the child never appears:diagnose debug application ike -1and look for shortcut-offer / SHORTCUT-QUERY.
- Parent SA up both spokes. iBGP Established.
- Spoke1 RIB:
B 10.22.0.0/24 via 10.10.100.2— not via10.10.100.254. - After traffic: child tunnel in
diagnose vpn tunnel list. - Subsequent packets do not increment hub overlay-to-overlay session counters the way the first packet did.
One flow after go-live
After the parent overlay is up:
- PC in 10.11.0.0/24 sends to 10.22.0.1. Spoke1 looks up BGP, NH 10.10.100.2, currently via parent to hub.
- Hub policy accepts overlay-to-overlay, forwards to Spoke2, IKE sender emits shortcut-offer to Spoke1 with 198.51.100.22.
- Spoke1 receiver starts child IKE. Child SA up. Kernel path to 10.10.100.2 now via the shortcut interface / tunnel-id.
- Same BGP prefix. New recursive resolution. Packets skip the hub until the shortcut idles out (if idle-timeout is set) and the process repeats.
Two underlays (DIA + MPLS) means two parent tunnels, two network-id values, and usually auto-discovery-crossover block so a shortcut does not form across overlays. SLA steering is a different lesson. Do not add a second overlay until this single-hub shortcut is proven.
Traps + proof
diagnose vpn tunnel list showing a child SA after spoke-to-spoke traffic, plus BGP NH still the remote overlay IP. A green parent on IPsec Monitor is necessary and not sufficient.| Symptom | Likely cause | Proof / fix |
|---|---|---|
| Parent up, no child after spoke-to-spoke ping | Sender missing on hub, receiver missing on spoke, or hub policy dropped the hairpin. | show vpn ipsec phase1-interface for the two flags. Policy hit count on overlay-to-overlay. IKE debug for shortcut-offer. |
| Child forms, traffic still hairpins | Hub next-hop-self; NH is 10.10.100.254. Or add-route enable hid the BGP path. | get router info routing-table bgp — NH must be 10.10.100.2. Remove next-hop-self; add-route disable. |
| IKE error on shortcut, parent stays up | Phase2 LAN-to-LAN selectors, or both spokes NAT-hidden. | Phase2 0.0.0.0/0. Confirm 500/4500 between 198.51.100.11 and .22. Two NATs without mapping will not shortcut. |
| BGP never Established | Overlay IPs missing, or hub has no neighbor-range for 10.10.100.0/24. | get router info bgp neighbors. Ping 10.10.100.254 over the parent. Fix interface IPs before ADVPN flags. |
| GUI tunnel looks “ADVPN-ready” | Dial-up IPsec without CLI sender/receiver. | GUI cannot set those flags (admin guide). If show lacks them, it is site-to-site dial-up, not ADVPN. |
| net-device mismatch / no shortcut iface | Spoke net-device disable while you expected a child interface to appear in SD-WAN or policy. | Classic sample: hub disable, spoke enable. Do not flip the hub to enable just because the spoke is enable. |
| Shortcut across MPLS vs DIA | Crossover allowed on two network-id overlays. | FortiOS 7.2.5+ auto-discovery-crossover block per overlay. Not this lab’s single underlay. |
diagnose vpn tunnel list get router info bgp neighbors get router info routing-table bgp # expect: B 10.22.0.0/24 via 10.10.100.2 # after spoke-to-spoke traffic diagnose vpn tunnel list | grep -A2 spoke1 # child remote = 198.51.100.22 diagnose debug reset diagnose debug application ike -1 diagnose debug enable # generate traffic; look for shortcut-offer / SHORTCUT-QUERY diagnose debug disable
- Hub
type dynamic,auto-discovery-sender enable,add-route disable,net-device disable. - Each spoke
remote-gw 203.0.113.1,auto-discovery-receiver enable,net-device enable,add-route disable. - Phase2 0.0.0.0/0 both sides. Overlay IPs in 10.10.100.0/24.
- iBGP 65001, hub RR, no next-hop-self. Spoke RIB NH is the remote overlay IP.
- Hub overlay-to-overlay policy accept, NAT off.
- After a spoke-to-spoke ping: child in
diagnose vpn tunnel list.
Knowledge check
Six judgment calls on hub-spoke overlay and shortcuts — not menu trivia.
Sources
- FortiOS admin guide — ADVPN with BGP as the routing protocol (hub
net-device disable,add-route disable,auto-discovery-sender; spokenet-device enable,auto-discovery-receiver; iBGP neighbor-group / RR) - FortiOS admin guide — ADVPN and shortcut paths (GUI does not support auto-discovery flags or IBGP neighbor-group)
- FortiOS SD-WAN architecture — ADVPN support with BGP RR (preserve original next-hop; recursive resolution via shortcut)
- FortiOS 7.0 handbook / older ADVPN example — IKE shortcut-offer / SHORTCUT-QUERY; dynamic routing required; IKE does not handle routing
- Fortinet Community — Technical Tip: disable shortcut creation (sender/receiver disable; net-device note)
- Fortinet Community — auto-discovery-crossover (7.2.5+, multi-overlay; out of this lab’s single underlay)
- FortiOS 7.6 — Dynamic BGP / ADVPN 2.0 is a different neighbor-group (RR off, shortcut-triggered spoke-spoke BGP). Do not mix with this RR lab.
Related: IPsec site-to-site · SD-WAN SLA · SD-WAN SLA rules · FortiGate interview