IPSEC L2TP VPN on CentOS 6/RHEL6
IPSEC L2TP VPN on CentOS 6 / Red Hat Enterprise Linux 6 / Scientific Linux 6
This is a guide on setting up a IPSEC/L2TP vpn on CentOS 6 or Red Hat Enterprise Linux 6 or Scientific Linux 6 using Openswan as the IPsec server, xl2tpd as the l2tp provider and ppp for authentication. We choose the IPSEC/L2TP protocol stack because of recent vulnerabilities found in pptpd VPN's.
IPSec encrypts your IP packets to provide encryption and authentication, so no one can decrypt or forge data between your clients and your server. L2TP provides a tunnel to send data. It does not provide encryption and authentication though, that is why we need to use it together with IPSec.
Why a VPN?
More than ever, your freedom and privacy when online is under threat. Governments and ISPs want to control what you can and can't see while keeping a record of everything you do, and even the shady-looking guy lurking around your coffee shop or the airport gate can grab your bank details easier than you may think. A self hosted VPN lets you surf the web the way it was intended: anonymously and without oversight.
A VPN (virtual private network) creates a secure, encrypted tunnel through which all of your online data passes back and forth. Any application that requires an internet connection works with this self hosted VPN, including your web browser, email client, and instant messaging program, keeping everything you do online hidden from prying eyes while masking your physical location and giving you unfettered access to any website or web service no matter where you happen to live or travel to.
This tutorial is available for the following platforms:
- Raspberry Pi with Arch Linux ARM
- CentOS 7, Scientific Linux 7 or Red Hat Enterprise Linux 7 (IKEv2,no L2TP)
- CentOS 6, Scientific Linux 6 or Red Hat Enterprise Linux 6
- Ubuntu 15.10, (IKEv2,no L2TP)
- Ubuntu 15.04, (IKEv2,no L2TP)
- Ubuntu 14.04 LTS
- Ubuntu 13.10
- Ubuntu 13.04
- Ubuntu 12.10
- Ubuntu 12.04 LTS
This tutorial was written and tested on a Digital Ocean VPS. If you like this tutorial and want to support my website, use this link to order a Digital Ocean VPS: https://www.digitalocean.com/?refcode=7435ae6b8212. You will get $10 free credit, which is equal to two months of a free $5 VPS.
To work trough this tutorial you should have:
- 1 CentOS 6 server with at least 1 public IP address and root access
- 1 (or more) clients running an OS that support IPsec/L2tp vpn's (Ubuntu, Mac OS, Windows, Android).
- Ports 1701 TCP, 4500 UDP and 500 UDP opened in the firewall.
I do all the steps as the root user. You should do to, but only via sudo-i
or su -
. Do not allow root to login via SSH!
Install and downgrade the packages
Install wget and bind-utils (for the host command):
yum install wget bind-utils
Install the EPEL repository for the xl2tpd package. (More info about EPEL).
wget http://mirror.nl.leaseweb.net/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -ivh ./epel-release-6-8.noarch.rpm
Note that the version of epel-release
might not be 6.8, but 6.9. Change accordingly.
Now install the required packages, openswan for ipsec, xl2tpd for the l2tp and ppp for the authentication:
yum install openswan xl2tpd ppp lsof
Because of a bug in openswan 2.6.32 release 19.el6_3 we need to downgrade openswan
to version 2.6.32 release 16.el6
. We do this by executing the following command two times (or, until we are on 2.6.32 R 16.el6
):
yum downgrade openswan
---> Package openswan.i686 0:2.6.32-18.el6_3 will be a downgrade
---> Package openswan.i686 0:2.6.32-19.el6_3 will be erased
yum downgrade openswan
---> Package openswan.i686 0:2.6.32-16.el6 will be a downgrade
---> Package openswan.i686 0:2.6.32-18.el6_3 will be erased
If you cannot downgrade to this version your repo does not have that many older package versions available. You can download it from here for x86 or from here for x64. You can install it afterwards with rpm -i openswan-2.6.32-16.el6.i686.rpm
.
Firewall and sysctl
We are going to set the firewall and make sure the kernel forwards IP packets:
Execute this command to enable the iptables firewall to allow the vpn:
iptables --table nat --append POSTROUTING --jump MASQUERADE
Execute the below commands to enable kernel IP packet forwarding and disable ICP redirects.
echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.accept_redirects = 0" | tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects = 0" | tee -a /etc/sysctl.conf
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
sysctl -p
/etc/rc.local
To make sure this keeps working at boot you might want to add the following to /etc/rc.local:
for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done
iptables -t nat -A POSTROUTING -j SNAT --to-source %SERVERIP%
Add it before the exit 0
line and replace %SERVERIP% with the external IP of your VPS.
Configure Openswan (IPSEC)
Use your favorite editor to edit the following file:
/etc/ipsec.conf
Below is the contents of mine. Most lines have a comment below it explaining what it does.
version 2 # conforms to second version of ipsec.conf specification
config setup
dumpdir=/var/run/pluto/
#in what directory should things started by setup (notably the Pluto daemon) be allowed to dump core?
nat_traversal=yes
#whether to accept/offer to support NAT (NAPT, also known as "IP Masqurade") workaround for IPsec
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v6:fd00::/8,%v6:fe80::/10
#contains the networks that are allowed as subnet= for the remote client. In other words, the address ranges that may live behind a NAT router through which a client connects.
protostack=netkey
#decide which protocol stack is going to be used.
force_keepalive=yes
keep_alive=60
# Send a keep-alive packet every 60 seconds.
conn L2TP-PSK-noNAT
authby=secret
#shared secret. Use rsasig for certificates.
pfs=no
#Disable pfs
auto=add
#the ipsec tunnel should be started and routes created when the ipsec daemon itself starts.
keyingtries=3
#Only negotiate a conn. 3 times.
ikelifetime=8h
keylife=1h
ike=aes256-sha1;modp1024!
phase2alg=aes256-sha1;modp1024
# specifies the phase 1 encryption scheme, the hashing algorithm, and the diffie-hellman group. The modp1024 is for Diffie-Hellman 2. Why 'modp' instead of dh? DH2 is a 1028 bit encryption algorithm that modulo's a prime number, e.g. modp1028. See RFC 5114 for details or the wiki page on diffie hellmann, if interested.
type=transport
#because we use l2tp as tunnel protocol
left=%SERVERIP%
#fill in server IP above
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
dpddelay=10
# Dead Peer Dectection (RFC 3706) keepalives delay
dpdtimeout=20
# length of time (in seconds) we will idle without hearing either an R_U_THERE poll from our peer, or an R_U_THERE_ACK reply.
dpdaction=clear
# When a DPD enabled peer is declared dead, what action should be taken. clear means the eroute and SA with both be cleared.
The shared secret
The shared secret is defined in the /etc/ipsec.secrets file. Make sure it is long and random:
%SERVERIP% %any: PSK "69EA16F2C529E74A7D1B0FE99E69F6BDCD3E44"
And don't forget to change %SERVERIP%
to the public IP of your server.
Verify
Now to make sure IPSEC works, execute the following command:
ipsec verify
My output looks like this:
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path [OK]
Linux Openswan U2.6.32/K2.6.32-71.29.1.el6.i686 (netkey)
Checking for IPsec support in kernel [OK]
SAref kernel support [N/A]
NETKEY: Testing for disabled ICMP send_redirects [OK]
NETKEY detected, testing for disabled ICMP accept_redirects [OK]
Testing against enforced SElinux mode [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for NAT-T on udp 4500 [OK]
Two or more interfaces found, checking IP forwarding [OK]
Checking NAT and MASQUERADEing [OK]
Checking for 'ip' command [OK]
Checking /bin/sh is not /bin/dash [OK]
Checking for 'iptables' command [OK]
Opportunistic Encryption Support [DISABLED]
Configure xl2tpd
Use your favorite editor to edit the following file:
/etc/xl2tpd/xl2tpd.conf
Below is the contents of mine. Most lines have a comment below it explaining what it does.
[global]
ipsec saref = yes
force userspace = yes
[lns default]
ip range = 172.16.1.30-172.16.1.100
local ip = 172.16.1.1
refuse pap = yes
require authentication = yes
ppp debug = no
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
- force userspace = because of the bug which why we also need to downgrade ipsec
- ip range = range of IP's to give to the connecting clients
- local ip = IP of VPN server
- refuse pap = refure pap authentication
- ppp debug = yes when testing, no when in production
Local user (PAM//etc/passwd) authentication
To use local user accounts via pam (or /etc/passwd), and thus not having plain text user passwords in a text file you have to do a few extra steps. Huge thanks to Sascha Scandella
for the hard work and troubleshooting.
In your /etc/xl2tpd/xl2tpd.conf
add the following line:
unix authentication = yes
and remove the following line:
refuse pap = yes
In the file /etc/ppp/options.xl2tpd
make sure you do not add the following line (below it states to add it, but not if you want to use UNIX authentication):
require-mschap-v2
Also in that file (/etc/ppp/options.xl2tpd
) add the following extra line:
login
Change /etc/pam.d/ppp
to this:
auth required pam_nologin.so
auth required pam_unix.so
account required pam_unix.so
session required pam_unix.so
Add the following to /etc/ppp/pap-secrets
:
* l2tpd "" *
(And, skip the chap-secrets
file below (adding users).)
Configuring PPP
Use your favorite editor to edit the following file:
/etc/ppp/options.xl2tpd
Below is the contents of mine. Most lines have a comment below it explaining what it does.
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 8.8.4.4
auth
mtu 1200
mru 1000
crtscts
hide-password
modem
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
- ms-dns = The dns to give to the client. I use google's public DNS.
- proxyarp = Add an entry to this system's ARP [Address Resolution Protocol] table with the IP address of the peer and the Ethernet address of this system. This will have the effect of making the peer appear to other systems to be on the local ethernet.
- name l2tpd = is used in the ppp authentication file.
Adding users
Every user should be defined in the /etc/ppp/chap-secrets file. Below is an example file.
# Secrets for authentication using CHAP
# client server secret IP addresses
alice l2tpd 0F92E5FC2414101EA *
bob l2tpd DF98F09F74C06A2F *
- client = username for the user
- server = the name we define in the ppp.options file for xl2tpd
- secret = password for the user
- IP Address = leave to * for any address or define addresses from were a user can login.
Testing it
To make sure everything has the newest config files restart openswan and xl2tpd:
/etc/init.d/ipsec restart;
/etc/init.d/xl2tpd restart
On the client connect to the server IP address (or add a DNS name) with a valid user, password and the shared secret. Test if you have internet access and which IP you have (via for example whatsmyip.org. ). If it is the VPN servers IP then it works.
Another nice test is to connect multiple clients of which one has a webserver. Make sure it only listens on a VPN IP (172.16.1.xxx in above example). Test if you can access it only via the VPN.
If you experience problems make sure to check the client log files and the ubuntu /var/log/secure file. If you google the error messages you most of the time get a good answer目录 返回
首页