Skip to main content
agomes
Staff
Staff
October 15, 2025

Technical Tip: ADVPN Configuration Guide – FortiGate Hub with Two Spokes

  • October 15, 2025
  • 0 replies
  • 3754 views
Description This article describes how to configure an ADVPN (Auto-Discovery VPN) between one Hub and two Spokes using IKEv2 and BGP (iBGP) for dynamic routing.
Scope FortiGate 7.x and earlier.
Solution

Topology Diagram:

 

2025-10-08 16_22_44-Chat _ AS_BRAZILIAN-TEAM _ Microsoft Teams.png

 

Prerequisites:

  • FortiOS 7.x or newer

  • IKEv2 must be used

  • VPN must be interface-based

  • BGP (iBGP) used for routing between overlay interfaces

  • The Hub acts as a BGP Route Reflector (RR)

  • The Spokes are configured as RR clients

  • ADVPN must be enabled with appropriate flags in each phase1-interface

 

Addressing plan:

 

Device IPSEC (Overlay) LAN Subnet Role BGP AS
HUB-FGT 169.254.1.1/32 (Optional LAN) RR 65000
SPOKE1-FGT 169.254.1.2/32 10.1.1.0/24 Client 65000
SPOKE2-FGT 169.254.1.3/32 10.2.2.0/24 Client 65000

 

HUB-FGT configuration:

 

# Interfaces config system interface     edit "port1"         set alias "WAN"         set ip <HUB-WAN-IP> <MASK>     next end  # IPsec (Phase 1 & 2) config vpn ipsec phase1-interface     edit "ADVPN-HUB"         set interface "port1"         set ike-version 2         set type dynamic         set peertype any         set nattraversal enable         set add-route disable         set dpd on-idle         set proposal aes256-sha256         set psksecret <shared-psk>         set auto-discovery-sender enable         set auto-discovery-forwarder enable     next end  config vpn ipsec phase2-interface     edit "ADVPN-HUB-p2"         set phase1name "ADVPN-HUB"         set proposal aes256-sha256         set pfs enable         set dhgrp 14         set auto-negotiate enable         set src-subnet 0.0.0.0 0.0.0.0         set dst-subnet 0.0.0.0 0.0.0.0     next end  BGP Configuration (Route Reflector) config router bgp     set as 65000     set router-id 10.255.255.1      config neighbor-group         edit "ADVPN-SPOKES"             set remote-as 65000             set route-reflector-client enable             set next-hop-self enable         next     end      config neighbor-range         edit 1             set prefix 10.255.255.0 255.255.255.0             set neighbor-group "ADVPN-SPOKES"         next     end end  # Firewall Policies config firewall policy     edit 0         set name "LAN-to-ADVPN"         set srcintf "lan" "lo-hub"         set dstintf "ADVPN-HUB"         set srcaddr "all"         set dstaddr "all"         set action accept         set schedule always         set service ALL     next     edit 0         set name "ADVPN-to-LAN"         set srcintf "ADVPN-HUB"         set dstintf "lan" "lo-hub"         set srcaddr "all"         set dstaddr "all"         set action accept         set schedule always         set service ALL     next end  config system interface     edit "ADVPN-HUB"         set vdom "root"         set ip 169.254.1.1 255.255.255.255         set allowaccess ping         set type tunnel         set snmp-index 13         set interface "port1"     next end  edit 3     set name "shortcut"     set srcintf "ADVPN-HUB"     set dstintf "ADVPN-HUB"     set action accept     set srcaddr "all"     set dstaddr "all"     set schedule "always"     set service "ALL"     set logtraffic all next end

 

SPOKE1-FGT configuration:

 

# Interfaces config system interface     edit "port1"         set alias "WAN"         set ip <SPOKE1-WAN-IP> <MASK>  # or set mode dhcp     next     edit "lan"         set ip 10.1.1.1 255.255.255.0     next end  # IPsec config vpn ipsec phase1-interface     edit "ADVPN-SPK1"         set interface "port1"         set ike-version 2         set remote-gw <HUB-WAN-IP>         set nattraversal enable         set add-route disable         set dpd on-idle         set proposal aes256-sha256         set psksecret <shared-psk>         set auto-discovery-receiver enable     next end  config vpn ipsec phase2-interface     edit "ADVPN-SPK1-p2"         set phase1name "ADVPN-SPK1"         set proposal aes256-sha256         set pfs enable         set dhgrp 14         set auto-negotiate enable         set src-subnet 0.0.0.0 0.0.0.0         set dst-subnet 0.0.0.0 0.0.0.0     next end  # BGP config router bgp     set as 65000     set router-id 10.255.255.11      config neighbor         edit 10.255.255.1             set remote-as 65000             set update-source "lo-spk1"         next     end      config network         edit 1             set prefix 10.1.1.0/24         next         edit 2             set prefix 10.255.255.11/32         next     end end  # Policies config firewall policy     edit 0         set name "LAN-to-ADVPN"         set srcintf "lan"         set dstintf "ADVPN-SPK1"         set action accept         set schedule always         set service ALL     next     edit 0         set name "ADVPN-to-LAN"         set srcintf "ADVPN-SPK1"         set dstintf "lan"         set action accept         set schedule always         set service ALL     next end  config system interface     edit "ADVPN-SPK1"         set vdom "root"         set ip 169.254.1.2 255.255.255.255         set allowaccess ping         set type tunnel         set remote-ip 169.254.1.1 255.255.255.0         set snmp-index 15         set interface "port1"     next end

 

SPOKE2-FGT configuration:
 

Same as Spoke1, but using:

Overlay: 169.254.1.3/32

LAN: 10.2.2.0/24

Router ID: 10.255.255.12

 

Interface ADVPN-SPK2:

 

config system interface     edit "ADVPN-SPK2"         set vdom "root"         set ip 169.254.1.3 255.255.255.255         set allowaccess ping         set type tunnel         set remote-ip 169.254.1.1 255.255.255.0         set snmp-index 11         set interface "port1"     next end

 

Validation and troubleshooting:

 

Check IPsec tunnels:

 

Run 'get vpn ipsec tunnel summary':

 

HUB # get vpn ipsec tunnel summary 'ADVPN-HUB_0' 190.188.100.2:0  selectors(total,up): 1/1  rx(pkt,err): 0/0  tx(pkt,err): 0/0 'ADVPN-HUB_1' 190.188.100.3:0  selectors(total,up): 1/1  rx(pkt,err): 0/0  tx(pkt,err): 0/0  Spoke1 # get vpn ipsec tunnel summary 'ADVPN-SPK1' 190.188.100.1:0  selectors(total,up): 1/1  rx(pkt,err): 0/0  tx(pkt,err): 0/2  Spoke2 # get vpn ipsec tunnel summary 'ADVPN-SPK2' 190.188.100.1:0  selectors(total,up): 1/1  rx(pkt,err): 0/0  tx(pkt,err): 0/2 

 

Run 'diagnose vpn ike gateway list':

 

diagnose vpn ike gateway list  vd: root/0 name: ADVPN-HUB_1 version: 2 interface: port1 3 addr: 190.188.100.1:500 -> 190.188.100.3:500 tun_id: 169.254.1.3/::10.0.0.12 remote_location: 0.0.0.0 network-id: 0 created: 703s ago peer-id: 190.188.100.3 peer-id-auth: no auto-discovery: 1 sender PPK: no IKE SA: created 1/1  established 1/1  time 0/0/0 ms IPsec SA: created 1/1  established 1/1  time 0/0/0 ms    id/spi: 9 fbe20a9e6b749d81/20414acaad5e9127   direction: responder   status: established 703-703s ago = 0ms   proposal: aes256-sha256   child: no   SK_ei: 802fd45d1a7914f2-6ed26e4c16541876-579146a391f5d7a1-be28e8aca8fa378a   SK_er: 878e8adaa2186983-069717c5abd51d49-72e778e2d84f227c-74b19e7523e3f162   SK_ai: fddd22e7d0481a48-572483b32fb0fd26-89ceb1b31bd1247a-e08f11843cd990a7   SK_ar: 829be0721d91daaa-6bd3f392b3ab22e3-5a7893c8fb6243ee-78c97d1ff62c3441   PPK: no   message-id sent/recv: 0/19   lifetime/rekey: 86400/85426   DPD sent/recv: 00000000/00000000   peer-id: 190.188.100.3  vd: root/0 name: ADVPN-HUB_0 version: 2 interface: port1 3 addr: 190.188.100.1:500 -> 190.188.100.2:500 tun_id: 169.254.1.2/::10.0.0.13 remote_location: 0.0.0.0 network-id: 0 created: 453s ago peer-id: 190.188.100.2 peer-id-auth: no auto-discovery: 1 sender PPK: no IKE SA: created 1/1  established 1/1  time 10/10/10 ms IPsec SA: created 1/1  established 1/1  time 0/0/0 ms    id/spi: 10 b0ebea184a20717c/5d0c9f3c523a0180   direction: responder   status: established 453-453s ago = 10ms   proposal: aes256-sha256   child: no   SK_ei: 007fd9c1b1bf08ce-7faabda3b05a5658-98891f7f7ebd78e9-4deb245f651e25fc   SK_er: ec26ff9414ace8ba-cb16c769b7635fe7-0e6baa02b37dff5d-42e62d6cef802ed9   SK_ai: 1c6234978eebf68d-ead5c82d0eddd049-743d3d9819033ebb-bbbad3a0c429a13d   SK_ar: 10aba40c698f76d2-215f1fa458b961a8-e9f148bafb7c7938-0e1b52071173b10a   PPK: no   message-id sent/recv: 0/12   lifetime/rekey: 86400/85676   DPD sent/recv: 00000000/00000000   peer-id: 190.188.100.2  HUB # 

 

Check BGP:

 

Run 'diagnose vpn tunnel list':

 

HUB # diagnose vpn tunnel list list all ipsec tunnel in vd 0 ------------------------------------------------------ name=ADVPN-HUB_0 ver=2 serial=e 190.188.100.1:0->190.188.100.2:0 nexthop=0.0.0.0 tun_id=169.254.1.2 tun_id6=::10.0.0.13 dst_mtu=1500 dpd-link=on weight=1 bound_if=3 real_if=3 lgwy=static/1 tun=intf mode=dial_inst/3 encap=none/74408 options[122a8]=npu rgwy-chg frag-rfc  run_state=0 role=primary accept_traffic=1 overlay_id=0  parent=ADVPN-HUB index=0 proxyid_num=1 child_num=0 refcnt=5 ilast=10 olast=10 ad=s/1 stat: rxp=23 txp=22 rxb=1492 txb=1435 dpd: mode=on-idle on=1 idle=60000ms retry=3 count=0 seqno=2 natt: mode=none draft=0 interval=0 remote_port=0 fec: egress=0 ingress=0 proxyid=ADVPN-HUB-p2 proto=0 sa=1 ref=3 serial=1 ads adf   src: 0:0.0.0.0-255.255.255.255:0   dst: 0:0.0.0.0-255.255.255.255:0   SA:  ref=3 options=21a02 type=00 soft=0 mtu=1438 expire=42691/0B replaywin=2048        seqno=17 esn=0 replaywin_lastseq=00000018 qat=0 rekey=0 hash_search_len=1   life: type=01 bytes=0/0 timeout=43191/43200   dec: spi=2b93bf02 esp=aes key=32 41c8a3a952b1f4faa44eaf39474bd8c284656c0b06bfb163f10e87a521ba8f4d        ah=sha256 key=32 329d78b2f41496c714eefeeac037480b32efa06d73c697f285c1fdb9764124e1   enc: spi=e9717e25 esp=aes key=32 9309c53c5a860574952b907048372ea1685684249ee355d2deff6da9a85e10b9        ah=sha256 key=32 b2cc816c2cf825ba6f0ab506e5d3feeb486127265992088ee975ec2b728dc821   dec:pkts/bytes=46/2984, enc:pkts/bytes=44/4419   npu_flag=00 npu_rgwy=190.188.100.2 npu_lgwy=190.188.100.1 npu_selid=c dec_npuid=0 enc_npuid=0 ------------------------------------------------------ name=ADVPN-HUB_1 ver=2 serial=d 190.188.100.1:0->190.188.100.3:0 nexthop=0.0.0.0 tun_id=169.254.1.3 tun_id6=::10.0.0.12 dst_mtu=1500 dpd-link=on weight=1 bound_if=3 real_if=3 lgwy=static/1 tun=intf mode=dial_inst/3 encap=none/74408 options[122a8]=npu rgwy-chg frag-rfc  run_state=0 role=primary accept_traffic=1 overlay_id=0  parent=ADVPN-HUB index=1 proxyid_num=1 child_num=0 refcnt=5 ilast=21 olast=21 ad=s/1 stat: rxp=38 txp=30 rxb=2417 txb=1959 dpd: mode=on-idle on=1 idle=60000ms retry=3 count=0 seqno=1 natt: mode=none draft=0 interval=0 remote_port=0 fec: egress=0 ingress=0 proxyid=ADVPN-HUB-p2 proto=0 sa=1 ref=3 serial=1 ads adf   src: 0:0.0.0.0-255.255.255.255:0   dst: 0:0.0.0.0-255.255.255.255:0   SA:  ref=3 options=21a02 type=00 soft=0 mtu=1438 expire=42435/0B replaywin=2048        seqno=1f esn=0 replaywin_lastseq=00000027 qat=0 rekey=0 hash_search_len=1   life: type=01 bytes=0/0 timeout=43186/43200   dec: spi=2b93bf01 esp=aes key=32 188763a362f1f32100b04c7e529c71feac989ec60fce7e856edc01d3694c9b0c        ah=sha256 key=32 7067e43c8d0d26e8d35a5a7e415d7238946130026a9d32a5e67c9d5e5c6bbad5   enc: spi=7e2bb596 esp=aes key=32 51d29ca3f0a09d1a9a0830532e12c8713f44b73fb53a686b96242f83a65d8094        ah=sha256 key=32 6c7a7d5dcb621e40b15474a0fa446d23736f713a6f7a1558b7fce71ec8c0bddf   dec:pkts/bytes=76/4834, enc:pkts/bytes=60/6031   npu_flag=00 npu_rgwy=190.188.100.3 npu_lgwy=190.188.100.1 npu_selid=b dec_npuid=0 enc_npuid=0 ------------------------------------------------------ name=ADVPN-HUB ver=2 serial=4 190.188.100.1:0->0.0.0.0:0 nexthop=0.0.0.0 tun_id=10.0.0.2 tun_id6=::10.0.0.2 dst_mtu=0 dpd-link=on weight=1 bound_if=3 real_if=0 lgwy=static/1 tun=intf mode=dialup/2 encap=none/552 options[0228]=npu frag-rfc  role=primary accept_traffic=1 overlay_id=0  proxyid_num=0 child_num=2 refcnt=4 ilast=42954399 olast=42954399 ad=/0 stat: rxp=127 txp=72 rxb=8322 txb=4862 dpd: mode=on-idle on=0 idle=60000ms retry=3 count=0 seqno=0 natt: mode=none draft=0 interval=0 remote_port=0 fec: egress=0 ingress=0 run_tally=0  HUB # 

 

Run 'get router info bgp summary':

 

HUB # get router info bgp summary  VRF 0 BGP router identifier 10.255.255.1, local AS number 65000 BGP table version is 1 1 BGP AS-PATH entries 0 BGP community entries Next peer check timer due in 39 seconds  Neighbor    V         AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd 169.254.1.2 4      65000      13      12        1    0    0 00:08:40        1 169.254.1.3 4      65000      16      16        1    0    0 00:11:48        1  Total number of neighbors 2   HUB # 

 

Run 'get router info bgp neighbors':

 

HUB # get router info bgp neighbors VRF 0 neighbor table: BGP neighbor is 169.254.1.2, remote AS 65000, local AS 65000, internal link  Member of peer-group ADVPN-SPOKES for session parameters   BGP version 4, remote router ID 10.255.255.11   BGP state = Established, up for 00:09:32   Last read 00:00:01, hold time is 180, keepalive interval is 60 seconds   Configured hold time is 180, keepalive interval is 60 seconds   Neighbor capabilities:     Route refresh: advertised and received (old and new)     Address family IPv4 Unicast: advertised and received     Address family VPNv4 Unicast: advertised and received     Address family IPv6 Unicast: advertised and received   Received 14 messages, 0 notifications, 0 in queue   Sent 13 messages, 0 notifications, 0 in queue   Route refresh request: received 0, sent 0   NLRI treated as withdraw: 0   Minimum time between advertisement runs is 30 seconds   For address family: IPv4 Unicast   BGP table version 1, neighbor version 1   Index 1, Offset 0, Mask 0x2   ADVPN-SPOKES peer-group member   Route-Reflector Client   NEXT_HOP is always this router   Community attribute sent to this neighbor (both)   1 accepted prefixes, 1 prefixes in rib   1 announced prefixes   For address family: VPNv4 Unicast   BGP table version 1, neighbor version 1   Index 0, Offset 0, Mask 0x0   ADVPN-SPOKES peer-group member   Community attribute sent to this neighbor (both)   0 accepted prefixes, 0 prefixes in rib   0 announced prefixes   For address family: IPv6 Unicast   BGP table version 1, neighbor version 1   Index 0, Offset 0, Mask 0x0   ADVPN-SPOKES peer-group member   Community attribute sent to this neighbor (both)   0 accepted prefixes, 0 prefixes in rib   0 announced prefixes   Connections established 1; dropped 0 Local host: 169.254.1.1, Local port: 179 Foreign host: 169.254.1.2, Foreign port: 14718 Egress interface: 22 Nexthop: 169.254.1.1 Nexthop global: :: Nexthop local: :: BGP connection: non shared network  BGP neighbor is 169.254.1.3, remote AS 65000, local AS 65000, internal link  Member of peer-group ADVPN-SPOKES for session parameters   BGP version 4, remote router ID 10.255.255.12   BGP state = Established, up for 00:12:40   Last read 00:00:28, hold time is 180, keepalive interval is 60 seconds   Configured hold time is 180, keepalive interval is 60 seconds   Neighbor capabilities:     Route refresh: advertised and received (old and new)     Address family IPv4 Unicast: advertised and received     Address family VPNv4 Unicast: advertised and received     Address family IPv6 Unicast: advertised and received   Received 17 messages, 0 notifications, 0 in queue   Sent 17 messages, 0 notifications, 0 in queue   Route refresh request: received 0, sent 0   NLRI treated as withdraw: 0   Minimum time between advertisement runs is 30 seconds   For address family: IPv4 Unicast   BGP table version 1, neighbor version 1   Index 0, Offset 0, Mask 0x1   ADVPN-SPOKES peer-group member   Route-Reflector Client   NEXT_HOP is always this router   Community attribute sent to this neighbor (both)   1 accepted prefixes, 1 prefixes in rib   1 announced prefixes   For address family: VPNv4 Unicast   BGP table version 1, neighbor version 1   Index 0, Offset 0, Mask 0x0   ADVPN-SPOKES peer-group member   Community attribute sent to this neighbor (both)   0 accepted prefixes, 0 prefixes in rib   0 announced prefixes   For address family: IPv6 Unicast   BGP table version 1, neighbor version 1   Index 0, Offset 0, Mask 0x0   ADVPN-SPOKES peer-group member   Community attribute sent to this neighbor (both)   0 accepted prefixes, 0 prefixes in rib   0 announced prefixes   Connections established 1; dropped 0 Local host: 169.254.1.1, Local port: 179 Foreign host: 169.254.1.3, Foreign port: 8032 Egress interface: 22 Nexthop: 169.254.1.1 Nexthop global: :: Nexthop local: :: BGP connection: non shared network

 

ADVPN shortcut behavior:

  • When Spoke1 sends traffic to Spoke2, it first goes through the Hub.

  • The Hub signals both Spokes to form a direct shortcut tunnel.

  • Traffic then flows directly Spoke1 ↔ Spoke2, reducing latency and Hub load.

 

Spoke1 - Shortcut:

 

2025-10-08 18_11_50-Chat _ AS_BRAZILIAN-TEAM _ Microsoft Teams.png

 

Spoke 1 BGP route through shortcut (169.254.1.3):

 

Spoke1 # get router info routing-table bgp Routing table for VRF=0 B       10.2.2.0/24 [200/0] via 169.254.1.3 (recursive via ADVPN-SPK1 tunnel 190.188.100.3), 00:04:38, [1/0]

 

Spoke2 - Shortcut:

 

2025-10-08 18_11_57-Chat _ AS_BRAZILIAN-TEAM _ Microsoft Teams.png

 

Spoke 2 BGP route through shortcut (169.254.1.2):

 

Spoke2 # get router info routing-table bgp Routing table for VRF=0 B       10.1.1.0/24 [200/0] via 169.254.1.2 (recursive via ADVPN-SPK2 tunnel 169.254.1.2), 00:04:38, [1/0]

 

Best practices:

  • Use IKEv2 only.

  • Keep add-route disable to let BGP handle routing.

  • Use loopbacks as stable router IDs.

  • Use neighbor-range on the Hub to simplify BGP peer management.

  • For ADVPN and ISPs link using PPPoE, it's recommended to use 'config system pppoe-interface' instead of 'set mode ppoe': 

config system pppoe-interface     edit "PPPOE"         set device "portX"         set username <username>         set password <password>     next end  config system interface     edit "PPPOE"         set mode pppoe                     set type tunnel     next end

 

IPsec configuration:

 

config vpn ipsec phase1-interface     edit "ADVPN-SPK1"         set interface "PPPOE"         set ike-version 2         set remote-gw <HUB-WAN-IP>         set nattraversal enable         set add-route disable         set dpd on-idle         set proposal aes256-sha256         set psksecret <shared-psk>         set auto-discovery-receiver enable     next end