Description
This article describes the 'tracert/traceroute' behavior over an IPsec VPN tunnel:
Referring to the diagram above, if tracert/traceroute is performed on PC at 192.168.20.99 to PC at 10.156.0.202 across an IPsec VPN tunnel, the output is as follows:
The issue is that 192.168.1.99 is a 'mgmt' interface; the interface is not connected at all. From a logical point of view, it should be showing IP address 10.156.0.22 since the packet went out through this interface, but this is incorrect. In this article, the IP address 10.156.0.22 is incorrect. How FortiGate selects the IP to respond, and what is the workaround.
Solution
Tracert/traceroute packet is based on an increment of the TTL value for each hop the packet traverses. It will start off with TTL value = 1, the first packet will reach 192.168.20.1. Since the TTL is already expired, FortiGate will not perform any routing table lookup to see which interface or next hop to send the packet out. Therefore, FortiGate will use 192.168.20.1 to respond to he tracert/traceroute packet and not 10.125.0.21.
The problem arises when the traceroute is traversing through an IPsec VPN tunnel, in which the IPsec VPN tunnel interface is a logical interface, and often, we do not configure any IP address on that interface. Therefore, in this case, FortiGate responds with the IP address of 192.168.1.99. This is an IP address of the mgmt interface, and the interface is neither up nor connected with any cable. How does FortiGate decide which IP address to respond to? FortiGate will use the IP address of the interface starting from the lowest index value. The index value can be found from the command 'diagnose netlink interface list'.
Below is the partial output of the command 'diagnose netlink interface list' in FortiGate 140D:
if=lo family=00 type=772 index=1 mtu=16436 link=0 master=0
ref=4 state=present fw_flags=0 flags=loopback
if=eth0 family=00 type=1 index=2 mtu=1508 link=0 master=0
ref=3 state=start present fw_flags=0 flags=up broadcast run promsic multicast
if=mgmt family=00 type=1 index=3 phyindex=4 mtu=1500 link=0 master=0
ref=3 state=start present tx_sched fw_flags=0 flags=up broadcast promsic allmulti multicast
if=ha family=00 type=1 index=4 phyindex=2 mtu=1500 link=0 master=0
ref=8 state=start present fw_flags=0 flags=up broadcast run promsic allmulti multicast
if=port1 family=00 type=1 index=5 phyindex=5 mtu=1500 link=0 master=0
ref=2 state=start present tx_sched fw_flags=0 flags=up broadcast promsic allmulti multicast
if=port2 family=00 type=1 index=6 phyindex=16 mtu=1500 link=0 master=0
ref=1 state=start present tx_sched fw_flags=0 flags=up broadcast multicast
if=port3 family=00 type=1 index=7 phyindex=27 mtu=1500 link=0 master=0
ref=19 state=start present fw_flags=0 flags=up broadcast run promsic allmulti multicast
if=port4 family=00 type=1 index=8 phyindex=35 mtu=1500 link=0 master=0
ref=1 state=start present tx_sched fw_flags=0 flags=up broadcast multicast
.
.
.
if=lan family=00 type=1 index=61 phyindex=3 mtu=1500 link=0 master=0
ref=9 state=start present fw_flags=0 flags=up broadcast run promsic multicast
From the above command, the mgmt interface is the lowest index interface with an IP address configured. Therefore, it will use 192.168.1.99 to reply to the TTL-expired packet.
'diagnose ip address list' command can also be used to check which interface has the lowest index value.
Lab_FGT # diagnose ip address list
IP=192.168.3.1->192.168.3.1/255.255.255.0 index=5 devname=wan1
IP=10.11.0.199->10.11.0.199/255.255.255.0 index=7 devname=internal1
IP=10.12.16.199->10.12.16.199/255.255.255.0 index=8 devname=internal2
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=18 devname=root
IP=10.255.1.1->10.255.1.1/255.255.255.0 index=26 devname=fortilink
IP=192.168.1.99->192.168.1.99/255.255.255.0 index=27 devname=internal
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=29 devname=vsys_ha
IP=127.0.0.1->127.0.0.1/255.0.0.0 index=31 devname=vsys_fgfm
IP=169.254.0.5->169.254.0.5/255.255.0.0 index=32 devname=tun_fgfm
Instead of depending on the index number, you can configure an IP address on the 140D IPsec VPN interface instead, so that the tracert/traceroute is showing the expected IP address.
Via CLI method:
config system interface
edit "IPsec" <----- Name of the tunnel interface.
set ip 1.1.1.12 255.255.255.255
set remote-ip 1.1.1.11 255.255.255.255
set interface "wan1"
next
end
The tracert/traceroute result is shown after configuring the IP address on the 140D IPsec VPN interface.