Post

CentOS 6/7 IPSec/L2TP VPN client to UniFi USG L2TP Server

1502051446
1710499145
6

Working with CentOS quite a lot I have spent time looking for configurations that work for various issues, one I have seen recently that took me a long time to resolve and had very poor documentation around the net was setting up an L2TP VPN.

In Windows or iOS its a nice simple setup where you enter all the required details and it sorts out the IPsec and L2TP VPN for you, In CentOS this is much different.

First we need to add the EPEL Repository: Now we need to install the software:

1
yum -y install epel-release

Now we need to install the software:

1
sudo yum -y install xl2tpd openswan

Make sure to start the openswan service:

1
systemctl start ipsec.service
1
service ipsec start

If you don’t start this service first you will receive the error connect(pluto_ctl) failed: No such file or directory

OpenSwan (IPSec)

Where you see %local change this to your Client local IP Address, where you see %server change this to the FQDN / IP of the VPN Server public IP

Configure IPSec VPN:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
config setup
     virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
     nat_traversal=yes
     protostack=netkey
conn L2TP-PSK
     authby=secret
     pfs=no
     auto=add
     keyingtries=3
     dpddelay=30
     dpdtimeout=120
     dpdaction=clear
     rekey=yes
     ikelifetime=8h
     keylife=1h
     type=transport
# Replace %local below with your local IP address (private, behind NAT IP is okay as well)
     left=%local
     leftprotoport=17/1701
# Replace IP address with your VPN server's IP
     right=%server
     rightprotoport=17/1701

This file contains the basic information to establish a secure IPsec tunnel to the VPN server. It enables NAT Traversal for if your machine is behind a NATing router (most people are), and other options that are required to connect correctly to the remote IPsec server.

Create a file to contain the Pre-Shared Key for the VPN:

1
%local %server : PSK "your_pre_shared_key"

Remember to replace the local (%local) and server (%server) IP addresses with the correct numbers for your location. The pre-shared key will be supplied by the VPN provider and will need to be placed in this file in cleartext form.

Add the connection so that we can use it:

1
ipsec auto --add L2TP-PSK

xl2tpd (L2TP)

First we need to edit the configuration of xl2tpd with our new VPN:

1
2
3
4
5
[lac vpn-connection]
lns = %server
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

Now we need to create our options file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ipcp-accept-local
ipcp-accept-remote
refuse-eap
require-mschap-v2
noccp
noauth
idle 1800
mtu 1410
mru 1410
defaultroute
usepeerdns
debug
logfile /var/log/xl2tpd.log
connect-delay 5000
proxyarp
name your_vpn_username
password your_password

Place your assigned username and password for the VPN server in this file.

Create the control file for xl2tpd:

1
2
mkdir -p /var/run/xl2tpd
touch /var/run/xl2tpd/l2tp-control

This completes the configuration of the applicable software suites to connect to a L2TP/IPsec server. To start the connection do the following:

1
2
3
4
systemctl start ipsec
systemctl start xl2tpd
systemctl enable ipsec.service
systemctl enable xl2tpd.service
1
2
3
4
service openswan start
service xl2tpd start
chkconfig openswan on
chkconfig xl2tpd on
1
2
ipsec auto --up L2TP-PSK
echo "c vpn-connection" > /var/run/xl2tpd/l2tp-control

At this point the tunnel is up and you should be able to see the interface for it if you type:

1
ifconfig ppp0

Routing

Now that our tunnel is up and running we need to be able to route to our respective networks, this can be done two ways:

Add the route manually each time the VPN restarts:

1
route add -net xxx.xxx.xxx.xxx/xx dev ppp0

Replace the x with the server local network and subnet mask e.g. 192.168.10.0/24

Add the route automatically:

Edit the if-up file and add this before exit 0:

1
2
3
4
5
6
case  in
        192.168.10.1)
        # VPN - IP ROUTE BEING ADDED AT RECONNECTION
                route add -net xxx.xxx.xxx.xxx/xxx dev ppp0;
        ;;
esac

Here we need to change 192.168.10.1 to the ppp0 gateway, also change the x with the server local network and subnet mask e.g. 192.168.10.0/24

To check the route is added simply type:

1
route

This will display a list of routes and your new route should be listed

Troubleshooting

The main logs to check are:

1
2
/var/log/xl2tpd.log
/var/log/messages

OpenSwan IPSec

To check that OpenSwan IPSec is working as expected run ipsec verify this will output similar to below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Verifying installed system and configuration files

Version check and ipsec on-path                         [OK]
Libreswan 3.15 (netkey) on 2.6.32-696.3.1.el6.x86_64
Checking for IPsec support in kernel                    [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                    [NOT DISABLED]

  Disable /proc/sys/net/ipv4/conf/*/send_redirects or NETKEY will act on or cause sending of bogus ICMP redirects!

         ICMP default/accept_redirects                  [NOT DISABLED]

  Disable /proc/sys/net/ipv4/conf/*/accept_redirects or NETKEY will act on or cause sending of bogus ICMP redirects!

         XFRM larval drop                               [OK]
Pluto ipsec.conf syntax                                 [OK]
Hardware random device                                  [N/A]
Checking rp_filter                                      [ENABLED]
 /proc/sys/net/ipv4/conf/default/rp_filter              [ENABLED]
 /proc/sys/net/ipv4/conf/lo/rp_filter                   [ENABLED]
 /proc/sys/net/ipv4/conf/eth0/rp_filter                 [ENABLED]
  rp_filter is not fully aware of IPsec and should be disabled
Checking that pluto is running                          [OK]
 Pluto listening for IKE on udp 500                     [OK]
 Pluto listening for IKE/NAT-T on udp 4500              [OK]
 Pluto ipsec.secret syntax                              [OK]
Checking 'ip' command                                   [OK]
Checking 'iptables' command                             [OK]
Checking 'prelink' command does not interfere with FIPSChecking for obsolete ipsec.conf options                 [OK]
Opportunistic Encryption                                [DISABLED]

ipsec verify: encountered 9 errors - see 'man ipsec_verify' for help

If you see the same results as above create the following script to resolve this:

1
2
3
4
5
6
7
8
#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
    echo 0 > $each/rp_filter
done

Run ipsec verify again to make sure all are green, ideally you shouldn’t encounter any errors.

Startup / Shutdown Script

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

if ! ifconfig | grep ppp0;
then
        sudo ipsec auto --up L2TP-PSK
        sleep 3
        sudo echo "c vpn-connection" > /var/run/xl2tpd/l2tp-control
fi
if ! route | grep xxx.xxx.xxx.xxx;
then
        sudo route add -net xxx.xxx.xxx.xxx/xx dev ppp0
fi

This can then be created as a cron job to make sure the vpn is always up and running.

This post is licensed under CC BY 4.0 by the author.