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:
yum -y install epel-releasen
Now we need to install the software:
sudo yum -y install xl2tpd openswan
Make sure to start the openswan service:
systemctl start ipsec.service
service ipsec start
NOTE: if you dont start this service first you will receive the error connect(pluto_ctl) failed: No such file or directory
NOTE: 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:
vi /etc/ipsec.conf ------------------------------ 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 NAT’ing 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:
vi /etc/ipsec.secrets ---------------------------- %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:
ipsec auto --add L2TP-PSK
First we need to edit the configuration of xl2tpd with our new VPN:
vi /etc/xl2tpd/xl2tpd.conf -------------------------- [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:
vi /etc/ppp/options.l2tpd.client ----------------------- 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:
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:
systemctl start ipsec systemctl start xl2tpd systemctl enable ipsec.service systemctl enable xl2tpd.service
service openswan start service xl2tpd start chkconfig openswan on chkconfig xl2tpd on
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:
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:
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:
vi /etc/ppp/if-up --------------------- 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:
This will display a list of routes and your new route should be listed
The main logs to check are:
To check that OpenSwan IPSec is working as expected run ipsec verify this will output similar to below:
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:
#!/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 shouldnt encounter any errors.
Startup / Shutdown Script
#!/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.