Thanos Blog

Setup Split Dns and Tunnel for Forti VPN under linux

16 Mar 2024

header image

Within my current corporate environment, accessing internal services mandates a connection to a Forti-VPN network. However, the native FortiVPN client proved inadequate for my requirements. Additionally, I needed a tunnel interface for specific domain name wildcard and multiple private networks. To address these needs, I implemented a solution involving openfortivpn, DNSmasq, and specific IP routes.

While the setup might seem straightforward, it entails some intricacies. Initially, installing dnsmasq and openfortivpn is necessary. As a Manjaro user, I found packages or AUR packages for openfortivpn to facilitate installation on other distributions. Interested individuals can refer to the openfortivpn GitHub repository for guidance.

Once installation is complete, the next step is establishing a connection to the Forti-VPN network without resorting to split DNS and split tunneling. Using the Forti client requires the terminal. A configuration file, openfortivpn.conf, must be created to store credentials and host information:

host = <vpn_host>
port = <port>
username = <username>
password = <password>

Afterward, execute the command: sudo openfortivpn -c <path_to_openfortivpn.conf> -v.

During the authentication process, acceptance via the mobile application may be necessary. Successful authentication yields output similar to the following:

DEBUG:  openfortivpn 1.21.0
DEBUG:  Loaded configuration file "<path_to_openfortivpn.conf>".
DEBUG:  Loaded password from configuration file "<path_to_openfortivpn.conf>"
.
.
.
DEBUG:  Gateway certificate validation succeeded.
INFO:   Connected to gateway.
DEBUG:  Empty cookie.
INFO:   Authenticated.
INFO:   Remote gateway has allocated a VPN.
.
.
.
DEBUG:  Gateway certificate validation succeeded.
DEBUG:  Retrieving configuration
DEBUG:  Establishing the tunnel
DEBUG:  ppp_path: /usr/bin/pppd
DEBUG:  Switch to tunneling mode
DEBUG:  Starting IO through the tunnel
Using interface ppp0
Connect: ppp0 <--> /dev/pts/9
.
.
.
INFO:   Got addresses: [<IP>], ns [<IP>, <IP>], ns_suffix [<domain>]
INFO:   Negotiation complete.
DEBUG:  Got Address: <my_ip_in_this_vpn>
DEBUG:  if_config: not ready yet...
Cannot determine ethernet address for proxy ARP
local  IP address
remote IP address
.
.
.
DEBUG:  Got Address:<my_ip_in_this_vpn>
DEBUG:  Interface Name: ppp0
DEBUG:  Interface Addr:<my_ip_in_this_vpn>
INFO:   Interface ppp0 is UP.

With confirmed access, proceed to reach internal company services. Subsequently, configuring split DNS with DNSmasq and IP routes for split tunneling becomes imperative.

Firstly, configuring DNSmasq involves adding the following block to /etc/dnsmasq.conf. This block directs DNS queries to specific servers based on domain and interface:

# Listen on the interface connected to the VPN
interface=ppp0

# General DNS server for internet queries (Google's DNS)
server=8.8.8.8

# Specific DNS servers for eurodyn.com domain
server=/.<domain>.com/<DNS_Server_ip_1>
server=/.<domain>.com/<DNS_Server_ip_2>

Upon configuring DNSmasq, start the service with sudo systemctl enable --now dnsmasq and ensure to restart it after each configuration change with sudo systemctl restart dnsmasq. Now you can check the if the split dns works with dig tool.

Next, add routes through the ppp0 interface and remove the default route through the same interface with the following commands:

sudo ip route add <ip_of_the_internal_network_1>/16 dev ppp0
sudo ip route add <ip_of_the_internal_network_2>/24 dev ppp0

sudo ip route del default dev ppp0 scope link

Finally, to streamline the process, create a systemd service. Under /etc/systemd/system/openfortivpn.service, define the service (under gnome you can use this extension ):

[Unit]
Description=ED Forti VPN

[Service]
Type=simple
ExecStart=/home/<username>/.ppp/openfortivpnService.sh
Restart=always

[Install]
WantedBy=multi-user.target

Then, within /home/<username>/.ppp/openfortivpnService.sh, create a script to start the VPN connection, set IP routes, and maintain the VPN connection:

#!/bin/bash

# Start VPN Connection
sudo openfortivpn -c /home/<username>/.ppp/openfortivpn.conf --use-syslog &

# Wait until the remote IP address appears in the openfortivpn output
sleep 20

strace -e open notify-send "You are connected in ED VPN" "Be conscious \!\!\!"x

# Run IP route commands
sudo ip route del default dev ppp0 scope link
sudo ip route add <ip_of_the_internal_network_1>/16 dev ppp0
sudo ip route add <ip_of_the_internal_network_2>/24 dev ppp0

# Keep the script running to keep the VPN connection alive
wait

Finally, execute sudo systemctl daemon-reload to update systemd, then start and check the status of the service with sudo systemctl start openfortivpn and sudo systemctl status openfortivpn. With these configurations in place, split DNS and tunneling for the Forti VPN on Linux are successfully set up.