How to connect to a FortiGate IPSec-VPN using Linux
This article might not longer be relevant as a new opensource client called "openfortivpn" exists that utilized the SSLVPN feature of Fortigate instead of IPSec. See my new article Connecto to Fortigate VPN with OpenfortiVPN.
This article might be relevant to you if you have problems connecting to a FortiGate IPSec VPN with Linux (vpnc). For example, when using NetworkManager, you might see something like this in syslog:
<info> VPN connection 'FortiGate VPN' (IP4 Config Get) reply received from old-style plugin.
<info> VPN Gateway: 22.214.171.124
<info> Tunnel Device: tun0
<info> IPv4 configuration:
<info> Internal Address: 172.20.1.1
<info> Internal Prefix: 32
<info> Internal Point-to-Point Address: 172.20.1.1
<info> Maximum Segment Size (MSS): 0
<info> Forbid Default Route: no
<info> Internal DNS: 126.96.36.199
<info> No IPv6 configuration
<info> VPN connection 'FortiGate VPN' (IP Config Get) complete.
<warn> (11) failed to find interface name for index
<info> Policy set 'FortiGate VPN' (tun0) as default for IPv4 routing and DNS.
<info> Writing DNS information to /sbin/resolvconf
SCPlugin-Ifupdown: devices removed (path: /sys/devices/virtual/net/tun0, iface: tun0)
<info> VPN plugin state changed: started (4)
<info> VPN plugin state changed: stopped (6)
<info> VPN plugin state change reason: 0
Or, when you've using the command line interface:
vpnc version 0.5.3r512
IKE SA selected psk+xauth-3des-sha1
NAT status: this end behind NAT? YES -- remote end behind NAT? no
/etc/resolvconf/update.d/libc: Warning: /etc/resolv.conf is not a symbolic link to /run/resolvconf/resolv.conf
IPSEC SA selected 3des-sha1
vpnc: vpnc.c:1194: lifetime_ike_process: Assertion `a->next->type == IKE_ATTRIB_LIFE_DURATION' failed.
So, after playing around with the VPN settings in the FortiGate UI I finally found that the problem is the "
a->next->type == IKE_ATTRIB_LIFE_DURATION" part. It seems that FortiGate is using a wrong value for this field, or at least one that isn't accepted by vpnc.
Since it seems that there is not way to change this behaviour using configuration the only option you have is to patch vpnc. Fortunately, this is very easy, at least on Debian-Based systems (like Ubuntu or Mint). So, here's the way you go:
1. Create a FortiGate VPN configuration that is accessible from iOS devices (see this wonderful article on Just Daily Notes)
2. On your linux-client, install a build enviroment:
$ sudo apt-get install build-essential dh-make fakeroot devscripts
$ sudo apt-get build-dep vpnc
3. Create a working directory and download source files
$ mkdir -p vpnc-build
$ cd vpnc-build
$ apt-get source vpnc
You'll get some files like this:
$ ls -1
4. Edit vpnc-0.5.3r512/vpnc.c and locate the following line:
assert(a->next->type == IKE_ATTRIB_LIFE_DURATION);
On my version this is line 1194, but this may differ. Remove it or place comments around this line (note that this is C code, not C++):
/* assert(a->next->type == IKE_ATTRIB_LIFE_DURATION); */
5. Recompile vpnc:
$ (cd vpnc-0.5.3r512 && debuild -b -uc -us)
Now your working directory should contain a new .deb file:
$ ls -1
6. Install newly compiled binary:
$ sudo dpkg -i vpnc_0.5.3r512-2ubuntu1_amd64.deb
That is it, now your VPN connection should work - or at least don't die on this error.
You have to repeat this whenever there is a new version of this package. But since development stopped in 2008 I don't expect many updates to it. Alternativly, prevent any upgrades of the package with "sudo apt-mark hold vpnc".