Projects

Using VPN on a Linux machine can be a headache. Years ago, it was so tricky that I had to keep some proprietary OS somewhere, only for using VPN clients.

Now, on widespread distros like Ubuntu, it is easier to get VPN clients working, but because Ubuntu tries to move people to Ubuntu Pro and snap, I decided to abandon it; I'm now using Arch Linux.

As a mini software company, I had to install 3 VPN clients on my Arch machine, in order to remotely access my client's networks.

For the 2 first ones, it was quite easy to install them from the AUR. Installing packages from the Arch User Reporisory is described here.

But for FortiClient, I didn't make it.

Initially, I used the AUR package as available here.

When you take a look at the (huge) list of dependencies, you understand that there is a problem with this VPN client, and that the potential failures are numerous. The client itself, once installed, is almost 500Mb. WTF !?

I've installed all required dependencies, but it didn't work.

Then, one of my friends told me about fuckForticlient, a non-official project that implemented a kind of hack on top of openfortivpn. Openfortivpn is an open source client for establishing VPN PPP/TLS tunnels . It uses a pppd process being compatible with Fortinet protocols. Fortinet is the company behind the FortiClient VPN software.

Installing fuckForticlient.sh on Arch Linux

Preamble · Enable ppp

As a preamble, the ppp_generic kernel module must be enabled. It was not the case on my machine. For enabling it, create a file named:

/etc/modprobe.d/ppp.conf

with that content:

alias char-major-108 ppp_generic

Then, reboot your machine.

This is documented here, at the very end of the page, but it took me some time to find it.

Install script dependencies

fuckForticlient dependencies are listed here. All of them (with one exception) are in the extra Arch repo, so this is straightforward to install them via pacman -S. The lz4json dependency must be installed from the AUR.

Clone the fuckForticlient repository

Install fuckForticlient by cloning its repo, for example, in /opt

cd /opt
git clone https://github.com/nonamed01/fuckForticlient

Configure fuckForticlient

If, like me, you are crazy enough to always run your Arch as the root user, you have to comment out this line, in /opt/fuckForticlient/fuckForticlient.sh, in the function named sanityCheck:

# Make sure the user running this script belongs to the sudo group:
#id -Gn |grep sudo >/dev/null || return 1

Indeed, this check ensures the user is in the sudo group, but root isn't.

Then, create a script myvpn.sh that will call fuckForticlient, to access some VPN server, that will be noted as <vpn_server> in the remaining of this page.

#!/bin/sh
export FUCKFORTICLIENT_OPTS="--trusted-cert <server_digest>"
/opt/fuckForticlient/fuckForticlient.sh -S <vpn_server> -s

In my case, without the --trusted-cert option, the VPN server wasn't trusted and the connexion failed. To discover the <server_digest>, proceed that way: don't add this option at all the first time you execute the script. You will get an error message, and the server digest will be part of it. Then, copy it in your script.

Let's try !

Before launching myvpn.sh, open Firefox to establish a prior web-based connexion to the VPN server. Browse to:

https://<vpn_server>/remote/login

Enter your credentials.

Once your are connected, execute myvpn.sh, ie:

/root/bin/myvpn.sh

If everything went well, you shoud get an output like this one, ending with the sentence "Tunnel is up and running."

 1 [*] Detected distro: , version:
 2 [*] Auto-detected firefox profile: /root/.mozilla/firefox/fh7efbt2.default-release/sessionstore-backups
 3 [*] Openfortivpn version: 1.23.1
 4 /opt/fuckForticlient/fuckForticlient.sh: ligne 440: dpkg : commande introuvable
 5 [*] Openfortivpn installed from: GITHUB
 6 [*] Openfortivpn extra args: --trusted-cert 42ef99df58a7084d30f70282a1c561f856b2ab92d8be4696500f89d86ab3d934
 7 [*] SAML path: /remote/saml/start?realm=
 8 [*] Firefox profile: /root/.mozilla/firefox/fh7efbt2.default-release/sessionstore-backups
 9 [*] Trying to re-use a previous SVPNCOOKIE...
10 [*] SVPNCOOKIE successfully retrieved!
11 INFO:   Connected to gateway.
12 INFO:   Authenticated.
13 INFO:   Remote gateway has allocated a VPN.
14 Using interface ppp0
15 Connect: ppp0 <--> /dev/pts/3
16 INFO:   Got addresses: [x.x.x.x], ns [x.x.x.x, x.x.x.x], ns_suffix [<vpn_server_name>]
17 INFO:   Negotiation complete.
18 Cannot determine ethernet address for proxy ARP
19 local  IP address x.x.x.x
20 remote IP address x.x.x.x
21 INFO:   Interface ppp0 is UP.
22 INFO:   Setting new routes...
23 INFO:   Adding VPN nameservers...
24 Dropped protocol specifier '.openfortivpn' from 'ppp0.openfortivpn'. Using 'ppp0' (ifindex=8).
25 INFO:   Tunnel is up and running.

The script does not recognize Arch (line 1), but it does not seem to be a problem.

At line 4, fuckForticlient tries to detect the presence of openfortivpn via dpkg, not being available on Arch of course, but we don't care, the error is not blocking.

Lines 8 to 10: the script retrieves data from a cookie stored in the default Firefox profile, and uncompresses it with via lz4json.

Afterwards, the communication is established via the pppd process.

On the remaining lines, IP addresses and server names have been obfuscated.