How to connect to a FortiGate IPSec-VPN using Linux

Update 2016-11-22

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: 1.2.3.4
<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: 172.1.1.1
<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
got address 172.20.1.1
/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
vpnc-0.5.3r512
vpnc_0.5.3r512-2ubuntu1.debian.tar.gz
vpnc_0.5.3r512-2ubuntu1.dsc
vpnc_0.5.3r512.orig.tar.gz

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
vpnc-0.5.3r512
vpnc_0.5.3r512-2ubuntu1_amd64.build
vpnc_0.5.3r512-2ubuntu1_amd64.changes
vpnc_0.5.3r512-2ubuntu1_amd64.deb
vpnc_0.5.3r512-2ubuntu1.debian.tar.gz
vpnc_0.5.3r512-2ubuntu1.dsc
vpnc_0.5.3r512.orig.tar.gz

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".
 

Comments

Thanks you for your help!
It worked perfect.

regards.

Great guide!! it worked!

Hi,
What is the procedure for 32-bit linux?

I got an error:
dpkg-buildpackage: error: debian/rules build gave error exit status 2
debuild: fatal error at line 1364:
dpkg-buildpackage -rfakeroot -D -us -uc -b failed

nevermind, I had to sudo apt-get install libgcrypt11 libgcrypt11-dev gcc first, then it worked

Hi Thank you so much for this tutorial ,it really helped me a lot ,I am using ubuntu 14.04.
Continue doing the great work.

Greatly appreciated. Solved my problem with Ubuntu 15.04.

Thanks for this. I've been having some issues with another vpn client since I couldn't use vpnc. Followed you instructions and vpnc connected successfully

Thank you! This saved me having to drive into the office late one night. Power to you my friend!

Great! This saved my life! Thank you!

THANK YOU very much for your research and publishing this! It worked!

NOTE: I also had to install the libgcrypt20-dev package before this would compile for me. That may be the problem if you're seeing a lot of lines like this during the build:

make[1]: libgcrypt-config: Command not found

Update 2016-11-22

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 (http://rolandtapken.de/blog/2016-11/connect-fortigatevpn-openfortivpn)

Thanks! Still invaluable a couple of years on, when you have a client who has only enabled the IPSEC Forticlient!