AWS VPC VPN, dual tunnel with Fortigate firewall

Amazon Web Services (AWS) Virtual Private Cloud (VPC) Virtual Private Network (VPN) (sorry, I had to type all that out because it looks hilarious) configuration really wants to have 2 VPN tunnels active.

The issue is that having 2 VPN tunnels active is that the control of sessions can get very messed up or you drop packets because of the stateful operation of the Fortigate firewall.

There are at least 2 ways to do this and this article will describe the simplest – using VPN monitoring with either static routing or via BGP.


In this post I am going to describe both methods but I expect most people to stick to KISS with the static routing option. The end of the article will have the basics for using BGP instead.

If you just want the super simple version..then review the code snippet below and stop reading!

config vpn ipsec phase1-interface
  edit "secondary-tunnel-interface"
    set monitor "primary-tunnel-interface"
  next
end

When you configure your VPN via AWS VPC you can download a configuration template for your firewall. Many people will use the GUI configuration template as it just uses the web interface of the firewall.

To do the ‘monitor’ option, though, you need to do the last part of the configuration via the command line. This guide will be using the command line.

2 items of note:

  • interface names in template from AWS are too long and need to be adjusted
  • identifiers from AWS are, currently, 8 characters but they changed instances to 17 characters

Use your favorite editor and make adjustments as needed. My examples have shrunk the connection names to reasonable lengths.

Steps are:

  • create phase-1 interfaces
  • create phase-2 interfaces
  • create system interfaces
  • configure 1 interface as standby (purpose of this post)
  • create policies for bidirectional communication (simple, any/all config)
  • create static routes
Create the interfaces

IPSEC VPNs have 2 phases of operation and configured separately:

! tunnel #1
config vpn ipsec phase1-interface
edit "p1-v-4bdd1c7c-0"
  set interface "WAN1"
  set dpd enable
  set local-gw EXT.IP.ADDRESS
  set dhgrp 2
  set proposal aes128-sha1
  set keylife 28800
  set remote-gw 72.21.XX.XX
  set psksecret sekrets
  set dpd-retryinterval 10
 next
end

! tunnel #2
config vpn ipsec phase1-interface
edit "p1-v-4bdd1c7c-1"
  set interface "WAN1"
  set dpd enable
  set local-gw EXT.IP.ADDRESS
  set dhgrp 2
  set proposal aes128-sha1
  set keylife 28800
  set remote-gw 72.21.XX.XX
  set psksecret sekrets
  set dpd-retryinterval 10
 next
end
! tunnel #1
config vpn ipsec phase2-interface
 edit "p2-v-4bdd1c7c-0"
  set phase1name "p1-v-4bdd1c7c-0"
  set proposal aes128-sha1
  set dhgrp 2
  set keylifeseconds 3600
 next
end

! tunnel #2
config vpn ipsec phase2-interface
 edit "p2-v-4bdd1c7c-1"
  set phase1name "p1-v-4bdd1c7c-1"
  set proposal aes128-sha1
  set dhgrp 2
  set keylifeseconds 3600
 next
end

Now we create the system interfaces for the tunnels themselves with private addressing endpoints:

! tunnel #1
config system interface
 edit "p1-v-4bdd1c7c-0"
  set vdom "root"
  set ip 169.254.255.78 255.255.255.255
  set allowaccess ping
  set type tunnel
  set tcp-mss 1387
  set remote-ip 169.254.255.77
  set interface "WAN1"
 next
end

! tunnel #2
config system interface
 edit "p1-v-4bdd1c7c-1"
  set vdom "root"
  set ip 169.254.255.74 255.255.255.255
  set allowaccess ping
  set type tunnel
  set tcp-mss 1387
  set remote-ip 169.254.255.73
  set interface "WAN1"
 next
end
Configure standby interface

I’m choosing tunnel ‘-1’ as the standby.

config vpn ipsec phase1-interface
  edit "p1-v-4bdd1c7c-1"
    set monitor "p1-v-4bdd1c7c-0"
  next
end
Configure bidirectional policies
config firewall policy
    ! WAN1 -> p1-v-4bdd1c7c-0
    edit 100
        set srcintf "WAN1"
        set dstintf "p1-v-4bdd1c7c-0"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
    next
    ! WAN1 -> p1-v-4bdd1c7c-1
    edit 110
        set srcintf "WAN1"
        set dstintf "p1-v-4bdd1c7c-1"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
    next
    ! p1-v-4bdd1c7c-0 -> WAN1
    edit 120
        set srcintf "p1-v-4bdd1c7c-0"
        set dstintf "WAN1"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
    next
    ! p1-v-4bdd1c7c-1 -> WAN1
    edit 130
        set srcintf "p1-v-4bdd1c7c-1"
        set dstintf "WAN1"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
    next
end
Configure static routes
config router static
    ! set primary tunnel
    edit 20
        set dst 172.20.0.0 255.255.0.0
        set gateway 169.254.255.77
        set distance 20
        set device "p1-v-4bdd1c7c-0"
    next
    ! set secondary tunnel routes
    edit 21
        set dst 172.20.0.0 255.255.0.0
        set gateway 169.254.255.73
        set distance 20
        set device "p1-v-4bdd1c7c-1"
    next
end

And you should now have a working, dual VPN configuration with AWS and your VPC!

So, you want to do BGP instead?

Here are steps to change from static routes to BGP:

config router bgp
 set as 64001
 config neighbor
  edit 169.254.255.77
   set remote-as 7224
  end
 config neighbor
  edit 169.254.255.73
   set remote-as 7224
  end
end
config router static
    delete 20
    delete 21
end
get router info routing-table all