Configuring ADVPN in FortiOS 5.4 (Expert)
In this recipe, we will explore a new VPN feature introduced in FortiOS 5.4.0: ADVPN.
ADVPN (Auto Discovery VPN) is an IPsec technology based on an IETF RFC draft (https://tools.ietf.org/html/draft-sathyanarayan-ipsecme-advpn-03). In simple terms, ADVPN allows a traditional hub and spoke VPN's spokes to establish dynamic, on-demand direct tunnels between each other so as to avoid routing through the topology's hub device. ADVPN requires the use of dynamic routing in order to function and FortiOS 5.4 supports both BGP and RIP. This recipe will focus on using BGP and its route-reflector mechanism as the dynamic routing solution to use with ADVPN.
ADVPN's primary advantages is that it provides the full meshing capabilities to a standard hub and spoke topology, greatly reducing the provisioning effort required for full spoke to spoke low delay reachability and addressing the scalability issues associated with very large fully meshed VPN networks.
BGP (and specifically, iBGP) is a natural fit for ADVPN as its route reflector mechanism resides on the VPN hub device and mirrors routing information from each spoke peer to each other. Furthermore, dynamic group peers result in near zero-touch hub provisioning when a new spoke is introduced in the topology.
As pictured, while the static configuration will involve both spoke FortiGate units to connect to our circular hub FortiGate, Spoke A will be able to establish a dynamic on-demand shortcut IPSec tunnel to Spoke B (and vice versa) if a host behind either spoke attempts to reach a host behind the other spoke. We will complete the configuration below and our verification step below will include reachability from 192.168.2.1 (spoke A) to 192.168.3.1 (spoke B) over the dynamically created shortcut link.
This recipe is documented in CLI as configuration such as BGP and ADVPN are best done using the command line interface. We are assuming basic IP and default routing configuration has been completed on the devices.
1. Configure the Hub FortiGate
Using the CLI, configure phase 1 parameters.
The auto-discovery commands enable the sending and receiving of shortcut messages to spokes (the hub is responsible for lettings the spokes know that they should establish those tunnels).
Note: aggressive mode is not supported currently for ADVPN.
config vpn ipsec phase1-interface edit "ADVPN" set type dynamic set interface "wan1" set proposal aes128-sha1 set dhgrp 2 set auto-discovery-sender enable set add-route disable set psksecret fortinet next end
Configure the phase2 parameters.
This is a standard phase 2 configuration.
config vpn ipsec phase2-interface edit "ADVPN-P2" set phase1name "ADVPN" set proposal aes128-sha1 next end
Configure the tunnel interface IP.
ADVPN requires that tunnel IPs be configured on each device connecting to the topology. Those IP addresses need to be unique for each peer. A particularity of the hub is that it needs to define a bogus remote-IP address (10.10.10.254 in our example). This address should be unused in the topology and it will not be actually considered as part of the configuration for the hub.
config system interface edit "ADVPN" set vdom "root" set ip 10.10.10.1 255.255.255.255 set type tunnel set remote-ip 10.10.10.254 set interface "wan1" next end
Configure iBGP and route-reflection.
iBGP will be our overlay protocol of choice for enabling ADVPN communications. We are using an arbitrary private AS number (65000) in our example, and configuring a dynamic client group to reduce provisioning requirements.
While we are advertising our LAN network directly (“config network” command), route redistribution is a perfectly valid alternative.
config router bgp set as 65000 set router-id 10.10.10.1 config neighbor-group edit "ADVPN-PEERS" set remote-as 65000 set route-reflector-client enable set next-hop-self enable next end config neighbor-range edit 0 set prefix 10.10.10.0 255.255.255.0 set neighbor-group "ADVPN-PEERS" next end config network edit 0 set prefix 192.168.1.0 255.255.255.0 next end end
Configure basic policies to allow traffic to flow between the local network and the ADVPN VPN topology. As we generally desire traffic to be allowed between spokes in an ADVPN setup, we must remember to create a policy allowing spoke to spoke communications.
config firewall policy edit 0 set name "OUT ADVPN" set srcintf "lan" set dstintf "ADVPN" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set status enable next edit 0 set name "IN ADVPN" set srcintf "ADVPN" set dstintf "lan" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set status enable next edit 0 set name "ADVPNtoADVPN" set srcintf "ADVPN" set dstintf "ADVPN" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set status enable next end
2. Configure the Spoke FortiGates
Using the CLI, configure phase 1 parameters.
Note that we are configuring only one of the spokes in this example – the parameters that need to change for each spoke are highlighted in red.
config vpn ipsec phase1-interface
edit "ADVPN"
set interface "wan1"
set proposal aes128-sha1
set dhgrp 2
set auto-discovery-receiver enable
set add-route disable
set remote-gw 10.1.1.1
set psksecret fortinet
next
end
Configure the phase2 parameters.
config vpn ipsec phase2-interface edit "ADVPN-P2" set phase1name "ADVPN" set proposal aes128-sha1 set auto-negotiate enable next end
Configure the tunnel interface IP.
Notice that on the spokes, the remote IP is actually used and points to the IP defined on the hub.
config system interface
edit "ADVPN"
set vdom "root"
set ip 10.10.10.2 255.255.255.255
set type tunnel
set remote-ip 10.10.10.1
set interface "wan1"
next
end
Config iBGP.
This is a static standard configuration and as stated for the hub, redistribution could be used instead of explicit route advertisement.
config router bgp set as 65000 set router-id 10.10.10.2 config neighbor edit "10.10.10.1" set soft-reconfiguration enable set remote-as 65000 set next-hop-self enable next end config network edit 0 set prefix 192.168.2.0 255.255.255.0 next end end
Configure a static route for the tunnel IP subnet.
This is an important special step for the spokes as they need a summary route that identifies all tunnel IP used over your topology to point towards the ADVPN interface. In our example, we use 10.10.10.0/24 (if our network planning expects less than 255 sites). Be sure to adequately plan this IP range as it needs to be hardcoded in the spokes.
config router static edit 0 set dst 10.10.10.0 255.255.255.0 set device "ADVPN" next end
Configure policies.
config firewall policy edit 0 set name "OUT ADVPN" set srcintf "lan" set dstintf "ADVPN" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set status enable next edit 0 set name "IN ADVPN" set srcintf "ADVPN" set dstintf "lan" set srcaddr "all" set dstaddr "all" set action accept set schedule "always" set service "ALL" set status enable next end
Results
We can validate the behaviour of our configuration using a few commands. We are going to run these commands from SPOKE A.
get router info routing-table bgp will at a minimum display the learned routes from the topology. Note the recursive routing – a result of our spoke's required static route. In this case, there has not been any traffic between our local subnet (192.168.2.0/24) and the other spoke's subnet, as the routes are both going through the hub.
B 192.168.1.0/24 [200/0] via 10.0.0.1, ADVPN, 22:30:21 B 192.168.3.0/24 [200/0] via 10.0.0.3 (recursive via 10.0.0.1), 22:30:21
However once we initiate a ping between both spokes, we obtain a different display of routing information – routing now goes through a newly established dynamic tunnel directly through the remote spoke rather than through the hub. The ping hiccup that occurs is the tunnel rerouting through a newly negotiated tunnel to the other spoke.
Our routing information now displays the remote subnet as being available through the spoke directly, through interface ADVPN_0, a dynamically instantiated interface going to that spoke.
FG # exec ping-options source 192.168.2.1 FG # exec ping 192.168.3.1 PING 192.168.3.1 (192.168.3.1): 56 data bytes 64 bytes from 192.168.3.1: icmp_seq=0 ttl=254 time=38.3 ms 64 bytes from 192.168.3.1: icmp_seq=1 ttl=254 time=32.6 ms Warning: Got ICMP 3 (Destination Unreachable) 64 bytes from 192.168.3.1: icmp_seq=2 ttl=255 time=43.0 ms 64 bytes from 192.168.3.1: icmp_seq=3 ttl=255 time=31.7 ms 64 bytes from 192.168.3.1: icmp_seq=4 ttl=255 time=31.2 ms --- 192.168.3.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 31.2/35.3/43.0 ms FG # get router info routing-table bgp B 192.168.1.0/24 [200/0] via 10.0.0.1, ADVPN, 22:34:13 B 192.168.3.0/24 [200/0] via 10.0.0.3, ADVPN_0, 00:02:28
Some additional data can be obtained using the very useful diag vpn tunnel list command. We are highlighting the aspects in the output which convey data specific to ADVPN, in this case the auto-discovery flag and the child-parent relationship of new instantiated dynamic tunnel interfaces.
FG # diag vpn tunnel list list all ipsec tunnel in vd 0 ------------------------------------------------------ name=ADVPN_0 ver=1 serial=a 10.1.1.2:0->10.1.1.3:0 bound_if=6 lgwy=static/1 tun=intf/0 mode=dial_inst/3 encap=none/0 parent=ADVPN index=0 proxyid_num=1 child_num=0 refcnt=19 ilast=3 olast=604 auto-discovery=2 stat: rxp=7 txp=7 rxb=1064 txb=588 dpd: mode=on-demand on=1 idle=20000ms retry=3 count=0 seqno=0 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=ADVPN-P2 proto=0 sa=1 ref=2 serial=1 auto-negotiate adr src: 0:0.0.0.0/0.0.0.0:0 dst: 0:0.0.0.0/0.0.0.0:0 SA: ref=3 options=2f type=00 soft=0 mtu=1438 expire=42680/0B replaywin=2048 seqno=8 esn=0 life: type=01 bytes=0/0 timeout=43152/43200 dec: spi=9a487db3 esp=aes key=16 55e53d9fbc8dbeaa6df1032fbc80c4f6 ah=sha1 key=20 a1470452c6a444f26a070add087f0d970c18e3a7 enc: spi=3c37fea7 esp=aes key=16 8fd62a6745a9ba4fda062d4504b76851 ah=sha1 key=20 44c606f1ef1bf5739ba62f6572031aa956974d0a dec:pkts/bytes=7/588, enc:pkts/bytes=7/1064 ------------------------------------------------------ name=ADVPN ver=1 serial=9 10.1.1.2:0->10.1.1.1:0 bound_if=6 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/0 proxyid_num=1 child_num=1 refcnt=22 ilast=8 olast=8 auto-discovery=2 stat: rxp=3120 txp=3120 rxb=399536 txb=191970 dpd: mode=on-demand on=1 idle=20000ms retry=3 count=0 seqno=12 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=ADVPN-P2 proto=0 sa=1 ref=2 serial=1 auto-negotiate adr src: 0:0.0.0.0/0.0.0.0:0 dst: 0:0.0.0.0/0.0.0.0:0 SA: ref=3 options=2f type=00 soft=0 mtu=1438 expire=4833/0B replaywin=2048 seqno=5ba esn=0 life: type=01 bytes=0/0 timeout=43148/43200 dec: spi=9a487db2 esp=aes key=16 4f70d27edad656cfcacbae61b23d4b11 ah=sha1 key=20 b19ea87c90dd92d1cab58cbf24ae8fe12ee927cb enc: spi=b3dde355 esp=aes key=16 efbb4440df75018610b4ba8f5756167d ah=sha1 key=20 81cc9cee3bee1c2dba0eb1e7ac66e9d34b67bde9 dec:pkts/bytes=1465/90152, enc:pkts/bytes=1465/187560 ------------------------------------------------------