Debug VPN in Fortigate - seeing is believing


You can't really debug VPN problems with static show commands, if VPN fails to function you HAVE to see it happening real-time. Below I list few debug commands to do just that for IPSEC site-to-site tunnels in Fortigate.

Here:
192.168.168.254 - IP address on the LAN interface of the fortigate
10.170.15.131 - IP address on the remote LAN
200.199.20.162 - IP of the wan interface of the local Fortigate
72.21.207.65 - IP of the remote VPN peer

  1. Reset debug filters if any
    FG100 # diag debug reset
    FG100 # diagnose vpn ike log-filter clear
  2. (Optionally) Set filter to limit debug to a specific VPN tunnel.
  3. First, find the name of the VPN tunnel you want to debug:
    FG100 # get vpn ike gateway | grep name

    name: S2S2-Phase1
    name: Bunuel
    name: S2_Teheran
    
    • Set the VPN debug filter to show only messages related to this tunnel (in this case "Bunuel"):
      FG100 # diagnose vpn ike log-filter name Bunuel
    • Make sure the filter is right:
      FG100 # diagnose vpn ike log-filter list

      vd: any name: Bunuel interface: any IPv4 source: any IPv4 dest: any IPv6 source: any IPv6 dest: any source port: any dest port: any 3. Enable debugging
      FG100 # diag debug en

  4. Enable debug messages for specific application , here we are interested in IKE (note the debug level of -1, following logic I enabled first +1, 255 etc and surprisingly had no effect at all ):
    FG100 # diag debug app ike -1
    I, personally, prefer also to do a sniffer on the tests I run, so:
    FG100 # diagnose sniffer packet any 'host 10.170.15.131'
    Now open another ssh session to the same Fortigate and do pings to the IP on the other side of the VPN tunnel with the source IP of internal LAN (if local LAN is part of the encryption domain, or just ask client to do pings from the network in the encryption domain).

  5. Configure pings to go with the source interface of LAN of the Fortigate:
    FG100 # exec ping-options source 192.168.168.254
  6. Now do pings to bring up the VPN tunnel:
    FG100 # exec ping 10.170.15.131
    PING 10.170.15.131 (10.170.15.131): 56 data bytes
    64 bytes from 10.170.15.131: icmp_seq=1 ttl=252 time=73.2 ms
    64 bytes from 10.170.15.131: icmp_seq=2 ttl=252 time=116.3 ms
    64 bytes from 10.170.15.131: icmp_seq=3 ttl=252 time=110.3 ms
    64 bytes from 10.170.15.131: icmp_seq=4 ttl=252 time=138.4 ms
    

When you return to the 1st ssh session you will see the debug output:

interfaces=[any]
filters=[host 10.170.15.131]
0:Robophone1:Robophone1/2: IPsec SA connect 3 200.199.20.162->72.21.207.65:500  , natt_mode=0
0:Robophone1: using existing connection, dpd_fail=0
0:Robophone1: found phase2 Robophone1/2
0:Robophone1: IPsec SA connect 3 200.199.20.162->72.21.207.65:500 negotiating
0:Robophone1:1990: cookie d3351433913f978c/069bcd9a38263f3a:5125b9f3
0:Robophone1:1990:Robophone1/2:471585: initiator selectors 0 200.199.20.162:0->10.170.15.131:0
0:Robophone1:1990: sent IKE msg (quick_i1send): 200.199.20.162:500->72.21.207.65:500, len=148
Robophone: Initiator: sent 72.21.207.65quick mode message #1 (OK)
0: comes 72.21.207.65:500->200.199.20.162:500,ifindex=3....
0: exchange=Quick id=d3351433913f978c/069bcd9a38263f3a:5125b9f3 len=156
0: found Robophone1 200.199.20.1623 -> 72.21.207.65:500
0:RobophoneRobophone1:1990:Robophone1/2:471585: responder selectors 0 200.199.20.162:0->10.170.15.131:0
0:Robophone1:1990: sent IKE msg (quick_i2send): 200.199.20.162:500->72.21.207.65:500, len=60
0:Robophone1:1990:Robophone1/2:471585: set sa life soft seconds=1775.
0:Robophone1:1990:Robophone1/2:471585: set sa life hard seconds=1800.0:Robophone1:1990:Robophone1/2:471585: add SA #src=1 #dst=1
0:Robophone1:1990:Robophone1/2:471585: src 0 4 192.168.168.0/255.255.255.0
0:Robophone1:1990:Robophone1/2:471585: dst 0 1 10.170.15.131
0:Robophone1:1990:Robophone1/2:471585: installed SA: SPIs=2f1c289f/ea7a510d
0:Robophone1:1990:Robophone1/2:471585: sending SNMP tunnel UP trap
Robophone1: Initiator: sent 72.21.207.65  quick mode message #2 (DONE)
15.153033 10.170.15.131 -> 200.199.20.162: icmp: echo reply
16.196213 10.170.15.131 -> 200.199.20.162: icmp: echo reply
17.190216 10.170.15.131 -> 200.199.20.162: icmp: echo reply
18.218259 10.170.15.131 -> 200.199.20.162: icmp: echo reply

4 packets received by filter
0 packets dropped by kernel

Dont forget to disable debug afterwards:

FG100 # diag debug app ike 0
-OR-
FG100 # diag debug disable