| Solution | Topology Diagram:  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:  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:  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
|