SD-WAN integration with OCVPN
OCVPN has the capability to enable SD-WAN in order to dynamically add its tunnel interfaces as SD-WAN members. Users can configure SD-WAN health checks and service rules to direct traffic over the OCVPN tunnels.
The following example uses a dual hub and spoke topology. Each hub and spoke has two WAN link connections to the ISP. The spokes generate two IPsec tunnels to each hub (four tunnels in total). BGP neighbors are established over each tunnel and routes from the hubs and other spokes learned from all neighbors, which forms an ECMP scenario. All tunnels are placed as SD-WAN members, so traffic can be distributed across tunnels based on the configured SD-WAN service rules.
To integrate SD-WAN with OCVPN in the GUI:
- Configure the primary hub:
- Go to VPN > Overlay Controller VPN and set the Status to Enable.
- For Role, select Primary Hub.
- Enter the WAN interfaces (port15 and port16) and tunnel IP allocation block (10.254.0.0/16).
The WAN interface is position sensitive, meaning a tunnel will be created with the first position interface on the hub to the first position interface on the spoke, and so on. In this example, FGT_A (primary hub) will create two tunnels with FGT_C (spoke):
- FGT_A port15 <==> FGT_C internal1
- FGT_A port16 <==> FGT_C internal2
- Enable Auto-discovery shortcuts.
- Enable Add OCVPN tunnels to SD-WAN. The IPsec tunnels will be added automatically to the SD-WAN members if SD-WAN is enabled.
- Configure the overlays on the primary hub:
- In the Overlays section, click Create New.
- Enter a name and add the local interface (port2). Note the overlay is either based on local subnets or local interfaces, but not both.
By default, inter-overlay traffic is not enabled. Toggle Allow traffic from other overlays to enable it.
- Click OK and repeat these steps to create the second overlay (loop1).
- Click Apply.
- Configure the secondary hub with the same settings as the primary hub.
- Configure the spoke:
- Go to VPN > Overlay Controller VPN and set the Status to Enable.
- For Role, select Spoke.
- Enter the WAN interfaces (internal1 and internal2).
- Enable Auto-discovery shortcuts.
- Enable Add OCVPN tunnels to SD-WAN. The IPsec tunnels will be added automatically to the SD-WAN members if SD-WAN is enabled.
- Configure the overlays.
The overlay names on the spokes must match the hub for the traffic to be allowed through the same overlay.
- Click Apply.
- Configure the other spoke with the same settings.
- On a spoke, go to Network > SD-WAN Zones to view the configuration generated by OCVPN.
Firewall policies will be automatically generated by OCVPN between the local interfaces and the SD-WAN interface. Each policy will define the proper local and remote networks for its source and destination addresses.
To integrate SD-WAN with OCVPN in the CLI:
- Configure the primary hub:
config vpn ocvpn set role primary-hub set sdwan enable set wan-interface "port15" "port16" set ip-allocation-block 10.254.0.0 255.255.0.0 config overlays edit "overlay1" config subnets edit 1 set type interface set interface "port2" next end next edit "overlay2" config subnets edit 1 set type interface set interface "loop1" next end next end end
- Configure the secondary hub with the same settings as the primary hub.
- Configure the spoke:
config vpn ocvpn set status enable set sdwan enable set wan-interface "internal1" "internal2" config overlays edit "overlay1" config subnets edit 1 set type interface set interface "wan2" next end next edit "overlay2" config subnets edit 1 set type interface set interface "loop1" next end next end end
- Configure the other spoke with the same settings.
- Configure SD-WAN:
config system sdwan set status enable config members edit 1 set interface "_OCVPN2-0a" next edit 2 set interface "_OCVPN2-0b" next edit 3 set interface "_OCVPN2-1a" next edit 4 set interface "_OCVPN2-1b" next end end
Firewall policies will be automatically generated by OCVPN between the local interfaces and the SD-WAN interface. Each policy will define the proper local and remote networks for its source and destination addresses.
If no SD-WAN zone is specified, members are added to the default virtual-wan-link zone.
To verify the integration is working after the ADVPN shortcut is triggered:
- Check the routing table on the spoke:
FGT_C # get router info routing-table all Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2 i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area * - candidate default Routing table for VRF=0 S* 0.0.0.0/0 [10/0] via 172.16.17.2, internal1 [10/0] via 172.16.18.2, internal2 B 10.1.100.0/24 [200/0] via 10.254.7.254, _OCVPN2-0a, 00:10:24 [200/0] via 10.254.15.254, _OCVPN2-0b, 00:10:24 B 10.1.200.0/24 [200/0] via 10.254.7.254, _OCVPN2-0a, 00:10:24 [200/0] via 10.254.15.254, _OCVPN2-0b, 00:10:24 B 10.2.100.0/24 [200/0] via 10.254.71.254, _OCVPN2-1a, 00:10:15 [200/0] via 10.254.79.254, _OCVPN2-1b, 00:10:15 B 10.2.200.0/24 [200/0] via 10.254.71.254, _OCVPN2-1a, 00:10:15 [200/0] via 10.254.79.254, _OCVPN2-1b, 00:10:15 B 10.254.0.0/16 [200/0] via 10.254.7.254, _OCVPN2-0a, 00:10:15 [200/0] via 10.254.15.254, _OCVPN2-0b, 00:10:15 [200/0] via 10.254.71.254, _OCVPN2-1a, 00:10:15 [200/0] via 10.254.79.254, _OCVPN2-1b, 00:10:15 C 10.254.0.0/21 is directly connected, _OCVPN2-0a C 10.254.0.1/32 is directly connected, _OCVPN2-0a C 10.254.8.0/21 is directly connected, _OCVPN2-0b C 10.254.8.1/32 is directly connected, _OCVPN2-0b C 10.254.64.0/21 is directly connected, _OCVPN2-1a C 10.254.64.1/32 is directly connected, _OCVPN2-1b_0 <==shortcut tunnel C 10.254.64.2/32 is directly connected, _OCVPN2-1a C 10.254.72.0/21 is directly connected, _OCVPN2-1b C 10.254.72.2/32 is directly connected, _OCVPN2-1b is directly connected, _OCVPN2-1b_0 C 172.16.17.0/24 is directly connected, internal1 C 172.16.18.0/24 is directly connected, internal2 C 172.16.200.0/24 is directly connected, wan1 C 192.168.1.0/24 is directly connected, internal C 192.168.4.0/24 is directly connected, wan2 B 192.168.5.0/24 [200/0] via 10.254.0.2, _OCVPN2-0a, 00:00:10 [200/0] via 10.254.8.2, _OCVPN2-0b, 00:00:10 [200/0] via 10.254.0.2, _OCVPN2-0a, 00:00:10 [200/0] via 10.254.8.2, _OCVPN2-0b, 00:00:10 [200/0] via 10.254.64.1, _OCVPN2-1b_0, 00:00:10 [200/0] via 10.254.72.1, _OCVPN2-1b, 00:00:10 [200/0] via 10.254.64.1, _OCVPN2-1b_0, 00:00:10 [200/0] via 10.254.72.1, _OCVPN2-1b, 00:00:10 C 192.168.44.0/24 is directly connected, loop1 B 192.168.55.0/24 [200/0] via 10.254.0.2, _OCVPN2-0a, 00:00:10 [200/0] via 10.254.8.2, _OCVPN2-0b, 00:00:10 [200/0] via 10.254.0.2, _OCVPN2-0a, 00:00:10 [200/0] via 10.254.8.2, _OCVPN2-0b, 00:00:10 [200/0] via 10.254.64.1, _OCVPN2-1b_0, 00:00:10 [200/0] via 10.254.72.1, _OCVPN2-1b, 00:00:10 [200/0] via 10.254.64.1, _OCVPN2-1b_0, 00:00:10 [200/0] via 10.254.72.1, _OCVPN2-1b, 00:00:10
- Check the VPN tunnel state:
FGT_C # diagnose vpn tunnel list list all ipsec tunnel in vd 0 ------------------------------------------------------ name=_OCVPN2-1b_0 ver=2 serial=1c 172.16.18.3:0->172.16.15.4:0 dst_mtu=1500 bound_if=9 lgwy=static/1 tun=intf/0 mode=dial_inst/3 encap=none/728 options[02d8]=npu create_dev no-sysctl rgwy-chg frag-rfc accept_traffic=1 overlay_id=4 parent=_OCVPN2-1b index=0 proxyid_num=1 child_num=0 refcnt=15 ilast=0 olast=0 ad=r/2 stat: rxp=641 txp=1025 rxb=16436 txb=16446 dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=0 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=_OCVPN2-1b proto=0 sa=1 ref=3 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=6 options=1a227 type=00 soft=0 mtu=1438 expire=42650/0B replaywin=1024 seqno=407 esn=0 replaywin_lastseq=00000280 itn=0 qat=0 hash_search_len=1 life: type=01 bytes=0/0 timeout=43186/43200 dec: spi=90f03d9d esp=aes key=16 6cb33685bbc67d5c85488e0176ecf7b0 ah=sha1 key=20 7d11b3babe62c840bf444b7b1f637b4324722a71 enc: spi=7bc94bda esp=aes key=16 b4d8fc731d411eb24448b4077a5872ca ah=sha1 key=20 b724064d827304a6d80385ed4914461108b7312f dec:pkts/bytes=641/16368, enc:pkts/bytes=2053/123426 npu_flag=03 npu_rgwy=172.16.15.4 npu_lgwy=172.16.18.3 npu_selid=1f dec_npuid=1 enc_npuid=1 ------------------------------------------------------ name=_OCVPN2-0a ver=2 serial=18 172.16.17.3:0->172.16.13.1:0 dst_mtu=1500 bound_if=8 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/536 options[0218]=npu create_dev frag-rfc accept_traffic=1 overlay_id=1 proxyid_num=1 child_num=0 refcnt=20 ilast=0 olast=0 ad=r/2 stat: rxp=1665 txp=2922 rxb=278598 txb=70241 dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=7 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=_OCVPN2-0a proto=0 sa=1 ref=4 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=6 options=1a227 type=00 soft=0 mtu=1438 expire=41599/0B replaywin=1024 seqno=890 esn=0 replaywin_lastseq=00000680 itn=0 qat=0 hash_search_len=1 life: type=01 bytes=0/0 timeout=42899/43200 dec: spi=90f03d95 esp=aes key=16 a6ffcc197bb1b46ec745d0b595cdd69a ah=sha1 key=20 8007c134e41edf282f95daf9c9033d688ef05ccc enc: spi=a1bf21bf esp=aes key=16 ead05be389b0dec222f969e2f9c46b1d ah=sha1 key=20 b04105d34d4b0e61b018f2e60591f9b1510783bb dec:pkts/bytes=1665/278538, enc:pkts/bytes=4237/265074 npu_flag=03 npu_rgwy=172.16.13.1 npu_lgwy=172.16.17.3 npu_selid=1b dec_npuid=1 enc_npuid=1 ------------------------------------------------------ name=_OCVPN2-1a ver=2 serial=1a 172.16.17.3:0->172.16.11.1:0 dst_mtu=1500 bound_if=8 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/536 options[0218]=npu create_dev frag-rfc accept_traffic=1 overlay_id=3 proxyid_num=1 child_num=0 refcnt=17 ilast=0 olast=0 ad=r/2 stat: rxp=1 txp=2913 rxb=16376 txb=69642 dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=5 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=_OCVPN2-1a proto=0 sa=1 ref=28 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=6 options=1a227 type=00 soft=0 mtu=1438 expire=41653/0B replaywin=1024 seqno=887 esn=0 replaywin_lastseq=00000002 itn=0 qat=0 hash_search_len=1 life: type=01 bytes=0/0 timeout=42900/43200 dec: spi=90f03d9b esp=aes key=16 ee03f5b0f617a26c6177e91d60abf90b ah=sha1 key=20 f60cbbc4ebbd6d0327d23137da707b7ab2dc49e6 enc: spi=a543a7d3 esp=aes key=16 1d37efab13a5c0347b582b2198b15cb8 ah=sha1 key=20 427ee4c82bac6f26f0bcabfe04328c7f57ce682e dec:pkts/bytes=1/16316, enc:pkts/bytes=4229/264036 npu_flag=03 npu_rgwy=172.16.11.1 npu_lgwy=172.16.17.3 npu_selid=1d dec_npuid=1 enc_npuid=1 ------------------------------------------------------ name=_OCVPN2-0b ver=2 serial=19 172.16.18.3:0->172.16.14.1:0 dst_mtu=1500 bound_if=9 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/536 options[0218]=npu create_dev frag-rfc accept_traffic=1 overlay_id=2 proxyid_num=1 child_num=0 refcnt=20 ilast=0 olast=0 ad=r/2 stat: rxp=1665 txp=2917 rxb=278576 txb=69755 dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=7 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=_OCVPN2-0b proto=0 sa=1 ref=4 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=6 options=1a227 type=00 soft=0 mtu=1438 expire=41599/0B replaywin=1024 seqno=88b esn=0 replaywin_lastseq=00000680 itn=0 qat=0 hash_search_len=1 life: type=01 bytes=0/0 timeout=42899/43200 dec: spi=90f03d96 esp=aes key=16 9d7eb233c1d095b30796c3711d53f2fd ah=sha1 key=20 d8feacd42b5e0ba8b5e38647b2f2734c94644bd1 enc: spi=a1bf21c0 esp=aes key=16 d2c0984bf86dc504c5475230b24034f0 ah=sha1 key=20 3946e4033e1f42b0d9a843b94448f56fd5b57bee dec:pkts/bytes=1665/278516, enc:pkts/bytes=4233/264411 npu_flag=03 npu_rgwy=172.16.14.1 npu_lgwy=172.16.18.3 npu_selid=1c dec_npuid=1 enc_npuid=1 ------------------------------------------------------ name=_OCVPN2-1b ver=2 serial=1b 172.16.18.3:0->172.16.12.1:0 dst_mtu=1500 bound_if=9 lgwy=static/1 tun=intf/0 mode=auto/1 encap=none/536 options[0218]=npu create_dev frag-rfc accept_traffic=1 overlay_id=4 proxyid_num=1 child_num=1 refcnt=19 ilast=1 olast=0 ad=r/2 stat: rxp=1 txp=2922 rxb=16430 txb=70173 dpd: mode=on-idle on=1 idle=20000ms retry=3 count=0 seqno=4 natt: mode=none draft=0 interval=0 remote_port=0 proxyid=_OCVPN2-1b proto=0 sa=1 ref=28 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=6 options=1a227 type=00 soft=0 mtu=1438 expire=41656/0B replaywin=1024 seqno=890 esn=0 replaywin_lastseq=00000002 itn=0 qat=0 hash_search_len=1 life: type=01 bytes=0/0 timeout=42903/43200 dec: spi=90f03d9c esp=aes key=16 a655767c1ed6cff4575857eb3981ad81 ah=sha1 key=20 bfc2bccd7103a201be2641d4c6147d437d2c3f70 enc: spi=a543a7d4 esp=aes key=16 7221b814e483165b01edfdc8260d261a ah=sha1 key=20 d54819643c2f1b20da2aea4282d50a1f1bc1d72a dec:pkts/bytes=1/16370, enc:pkts/bytes=4238/265164 npu_flag=03 npu_rgwy=172.16.12.1 npu_lgwy=172.16.18.3 npu_selid=1e dec_npuid=1 enc_npuid=1
- Check the SD-WAN state:
FGT_C # diagnose sys sdwan health-check Health Check(Default_DNS): Health Check(Default_Office_365): Health Check(Default_Gmail): Health Check(Default_AWS): Health Check(Default_Google Search): Health Check(Default_FortiGuard): Health Check(ocvpn): Seq(1 _OCVPN2-0a): state(alive), packet-loss(0.000%) latency(0.364), jitter(0.028) sla_map=0x0 Seq(2 _OCVPN2-0b): state(alive), packet-loss(0.000%) latency(0.287), jitter(0.026) sla_map=0x0 Seq(3 _OCVPN2-1a): state(dead), packet-loss(100.000%) sla_map=0x0 Seq(4 _OCVPN2-1b): state(dead), packet-loss(100.000%) sla_map=0x0 Seq(4 _OCVPN2-1b_0): state(alive), packet-loss(0.000%) latency(0.289), jitter(0.029) sla_map=0x0