How to: Set up Openswan L2TP VPN Server on CentOS 6

Have you ever wanted to set up your own VPN server? By following the steps below, you can set up your own L2TP VPN server on CentOS 6. Note that an L2TP VPN, which we’re setting up here, is more secure than a PPTP VPN server. OpenVPN is another alternative to L2TP VPNs, but OpenVPN requires OpenVPN software on the client device. In contrast, L2TP VPNs are supported out of the box in most modern operating systems (Windows, Mac OS X, Ubuntu, RHEL, CentOS) as well as mobile devices (iOS [iPhones, iPads], Android, and Windows Phone).


Packages to install

yum install lsof man
yum install openswan
yum install ppp xl2tpd

Note: You need to have the epel repository installed to install xl2tpd. To install epel if you haven’t already, check this post.
Potential OpenSwan version issues with iOS devices behind NAT
OpenSwan version 2.6.32-18.el6_3 had a bug wherein iOS devices were unable to make a successful VPN connection if they were behind NAT, which includes attempting a VPN connection while connected to a cellular network. Downgrading to version 2.6.32-16.el6 allowed iOS devices to again connect.
It appears that this bug is fixed as of version 2.6.32-21.2.el6, but do note if you have trouble getting iOS devices to work behind NAT, it may be due to the version of OpenSwan you’ve installed.
For more information, see this page: http://bugs.centos.org/view.php?id=5832


IP Addresses in this example

 In the following configuration files, various IP addresses are listed. Change these IPs to match your environment

  • 10.0.100.0/24 – Internal LAN IP subnet: This is the IP subnet used on your local LAN that the VPN server resides upon.
  • 10.0.100.3 – Local IP used by VPN server for the L2TP tunnels: This is a completely made up number – you are assigning an IP address to the tunnel side of your VPN server. Make sure the IP you assign is not within your DHCP server’s DHCP scope.
  • 10.0.100.50-100 – Local IP range to be handed out to VPN-connected clients: You define your own range here – make sure it’s in the same subnet as your local LAN but not part of your DHCP scope.
  • 10.0.100.2 – IP address of VPN server: This is the primary IP address of the VPN server on your local LAN – this should be a static or statically assigned address.
  • 10.0.100.1 – DNS server: This is the DNS server that the L2TP VPN-connected clients will use.
  • 10.0.100.1 – Gateway/Router: This is the IP address of the border router on your internal network – it can be NAT’ed.


Configuration Files

/etc/sysctl.conf 

Edit the file to allow IP forwarding:
# Controls IP packet forwarding
net.ipv4.ip_forward = 1

Reload sysctl with this command:

sysctl -p

 
/etc/rc.local
Add the following block to the bottom of the configuration file:

# Correct ICMP Redirect issues with OpenSWAN
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

 
/etc/ipsec.conf
In the ipsec.conf file, you define a “left” and “right” side of the IPsec connection. In this example, the “left” side is your internal LAN, while the “right” side is the remote, client side which originates on port 1701.Make sure to change the virtual_private line to match your internal LAN subnet.
nehelpers is set to 0 to work around an error message when network helpers are not available.
plutodebug may be set to “control” if you wish to see messages logged in /var/log/pluto.log. Note: I do not suggest leaving this turned on as the log file will quickly grow to a massive size.
Additional lines are added at the bottom of the defined L2TP-PSK connection to better handle compatibility with Mac OS X and iOS clients.

# /etc/ipsec.conf - Openswan IPsec configuration file
#
# Manual:     ipsec.conf.5
#
# Please place your own config files in /etc/ipsec.d/ ending in .conf
version       2.0    # conforms to second version of ipsec.conf specification
# basic configuration
config setup
       interfaces=%defaultroute
       klipsdebug=none
       nat_traversal=yes
       nhelpers=0
       oe=off
       plutodebug=none
       plutostderrlog=/var/log/pluto.log
       protostack=netkey
       virtual_private=%v4:10.0.100.0/24
conn L2TP-PSK
       authby=secret
       pfs=no
       auto=add
       keyingtries=3
       rekey=no
       type=transport
       forceencaps=yes
       right=%any
       rightsubnet=vhost:%any,%priv
       rightprotoport=17/0
       # Using the magic port of "0" means "any one single port". This is
       # a work around required for Apple OSX clients that use a randomly
       # high port, but propose "0" instead of their port.
       left=%defaultroute
       leftprotoport=17/1701
       # Apple iOS doesn't send delete notify so we need dead peer detection
       # to detect vanishing clients
       dpddelay=10
       dpdtimeout=90
       dpdaction=clear
#You may put your configuration (.conf) file in the "/etc/ipsec.d/" and uncomment this.
#include /etc/ipsec.d/*.conf

 
/etc/ipsec.secrets 
First, create a new host key for the machine — this example is using a pre-shared key (PSK), but it’s still a good idea to generate the machine key:

    ipsec newhostkey --output /etc/ipsec.secrets --bits 2048 --verbose --configdir /etc/pki/nssdb/

Next, add a line with the internal LAN IP address of the server, the var %any:PSK to use the pre-shared key, and then define the pre-shared key in quotes.

    10.0.100.2      %any:     PSK     "yourPSKHere"

In the /etc/IPsec.secrets file, make sure you remove or uncomment the line “include /etc/ipsec.d/*.secrets,” or you’ll get an error and the VPN just won’t connect.

: RSA  {
# Your RSA generated machine key will be here after running the above IPsec newhostkey command
}
# do not change the indenting of that "}"
    10.0.100.2      %any:     PSK     "yourPSKHere"
Make sure you set the permissions on your secrets file to keep it private.
sudo chown root:root /etc/ipsec.secrets
sudo chmod 600 /etc/ipsec.secrets

 
/etc/xl2tpd/xl2tpd.conf

This is the xl2tpd configuration file. Make sure to change the listen-addr to that of your server, the ip range for your VPN clients, and the local IP of the VPN interface on the server.
[global]
listen-addr = 10.0.100.2
;
; requires openswan-2.5.18 or higher - Also does not yet work in combination
; with kernel mode l2tp as present in linux 2.6.23+
; ipsec saref = yes
; Use refinfo of 22 if using an SAref kernel patch based on openswan 2.6.35 or
;  when using any of the SAref kernel patches for kernels up to 2.6.35.
; ipsec refinfo = 30
;
; works around bug: http://bugs.centos.org/view.php?id=5832
force userspace = yes
;
[lns default]
ip range = 10.0.100.50-10.0.100.100
local ip = 10.0.100.3
; leave chap unspecified for maximum compatibility with windows, iOS, etc
; require chap = yes
refuse pap = yes
require authentication = yes
name = CentOSVPNserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

 
/etc/ppp/options.xl2tpd
ms-dns should be set to the DNS server you wish the VPN clients to use. You can specify multiple DNS servers by adding multiple ms-dns entries on separate lines.

ipcp-accept-local
ipcp-accept-remote
ms-dns  10.0.100.1
# ms-dns  192.168.1.1
# ms-dns  192.168.1.3
# ms-wins 192.168.1.2
# ms-wins 192.168.1.4
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
logfile /var/log/ppp.log

 
/etc/ppp/chap-secrets
This is the file in which you define your user accounts for the VPN — they are in username and password pairs.

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
user1           *       sgrongPassword1         *
user2           *       strongPassword2         *

Secure the /etc/ppp/chap-secrets file

sudo chown root:root /etc/ppp/chap-secrets
sudo chmod 600 /etc/ppp/chap-secrets


I
PTables Configuration

If you are running IPTables as the firewall on your VPN server, run the following commands to allow functioning VPN access

#Allow ipsec traffic
iptables -A INPUT -m policy --dir in --pol ipsec -j ACCEPT
iptables -A FORWARD -m policy --dir in --pol ipsec -j ACCEPT
#Do not NAT VPN traffic
iptables -t nat -A POSTROUTING -m policy --dir out --pol none -j MASQUERADE
#Forwarding rules for VPN
iptables -A FORWARD -i ppp+ -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
#Ports for Openswan / xl2tpd
iptables -A INPUT -m policy --dir in --pol ipsec -p udp --dport 1701 -j ACCEPT
iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT
#Save your configuration
iptables save

Note that if your current firewall configuration contains the following lines, your VPN connection will fail!
Remove these lines if they exist in your /etc/sysconfig/iptables file:
iptables -A INPUT -j REJECT –reject-with icmp-host-prohibited
iptables -A FORWARD -j REJECT –reject-with icmp-host-prohibited, the VPN connection will fail!


Enable and Start Services

chkconfig xl2tpd on
chkconfig ipsec on
service ipsec start
service xl2tpd start


Optional configuration

Ignore ICMP Redirects:

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f; done

Don’t send ICMP Redirects:

for f in /proc/sys/net/ipv4/conf/*/send_redirects; do echo 0 > $f; done


Troubleshooting

To see if your IPsec configuration looks OK, run the following command:

ipsec verify

You can also enable logging in /etc/ipsec.conf by setting plutodebug to “control”. This will log messages to /var/log/pluto.log.
There is an additional log file in /var/log/ppp.log.


Helpful links

http://confoundedtech.blogspot.com/2011/08/android-nexus-one-ipsec-psk-vpn-with.html
http://coding.zencoffee.org/2012/10/ipsecl2tp-vpn-server-on-centos-6-psk.html
http://amadys.blogspot.com/2010/06/openswan-2626-ipsec-for-linux.html
http://comments.gmane.org/gmane.network.openswan.user/20373
http://www.drlongghost.com/wordpress/2011/04/22/trying-to-get-iphone-to-ubuntu-vpn-working-with-openswan/
http://www.pariahzero.net/Blog/files/e7d5abf84a96640d5cd70dd0dfb3d200-71.html
http://agit8.turbulent.ca/bwp/2011/01/setting-up-a-vpn-server-with-ubuntu-1004-and-strongswan/

20 Comments

  1. Thanks for this howto.
    Something that I came across is that the /etc/xl2tpd/xl2tpd.conf should have the global parameter listen-addr set to the public ipaddress, for example:
    [global]
    listen-addr = (public IP address)
    Hope this helps to somebody else.
    Other than that everything else works as stated.

  2. Thanks for the great tutorial. Is the ip range a non existing?
    If this range going “up” automatically? (like PPTP)
    or must this be a valid network
    virtual_private=%v4:10.0.100.0/24

    • Yes, the “virtual_private” line must be a valid network. It’s your internal LAN IP subnet. So if you are using, say 192.168.100.X for your internal IP network, you would set the line to “virtual_private=%4:192.168.100.0/24”.

      • I hope that you are still checking your blog.
        I have a VPS that I would like to setup as the L2TP server. Currently it isn’t “natted” and receives a public IP address. Is it possible to set this up so that clients get natted by the L2TP server and don’t receive public IP addresses? What would that be called/ done?

  3. Hi Steve,
    Thanks for this HowTo! I can now connect to my home network from my iPhone 🙂
    I can make direct connections to devices at home fine but I have an app (Sonos controller) that send multicast packets and these packets do not seem to make it all the way.
    I can see them being received on the ppp0 interface but not coming out of eth0.
    I’ve not done much with multicast so I am trying to learn more. Do you know why these are not being forwarded please?
    The packets have a destination address of 239.255.255.250 and are SSDP.
    I’ve tried adding a route for 224.0.0.0/4 to eth0 but this hasn’t helped.
    Any help would be appreciated!
    Many thanks,
    Dave

  4. Hi,
    I hope you’re still read your comments. Which version of OpenSwan do you run? Because it works on my iPhone and iPad but not Android. I’ve tried latest version of OpenSwan. Linux Openswan U2.6.39/K3.2.0-32-generic (netkey)
    Do you know why?

    • I’m currently using 2.6.32-21.2.el6, but I don’t have an Android device to test.
      Have you checked the logging on your system for any clues? If you’ve added a logfile line to /etc/ppp/options.xl2tpd (see above), you can open that log file to see if there are any messages to help you troubleshoot.
      Additionally, in /etc/ipsec.conf, you can set plutodebug to “ALL” and then view the log messages in /var/log/pluto.log.

  5. Hope you can still help me… I can connect just fine, but it seems routing doesn’t seem to be working. Once connected to the VPN, I can ping the local IP of the VPN server, but nothing else on the subnet. Any insight? Thanks!

  6. Can I set up openswan so the traffic runs over either port 80 or 443 so I dont have to open up another hole in my firewall? My goal is to have a VPN connection through one of those ports.

  7. After starting ipsec, still unable to establish tunnel:
    104 “xx@xx” #1: STATE_MAIN_I1: initiate
    003 “xx@xx” #1: ignoring informational payload, type NO_PROPOSAL_CHOSEN msgid=00000000
    003 “xx@xx” #1: received and ignored informational message
    Logs are:
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | sending 216 bytes for EVENT_RETRANSMIT through eth0:500 to right-remote-ip:500 (using #3)
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | d4 0f fc 5c 9e 33 ff 5c 00 00 00 00 00 00 00 00
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 01 10 02 00 00 00 00 00 00 00 00 d8 0d 00 00 34
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 00 00 00 01 00 00 00 01 00 00 00 28 00 01 00 01
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 00 00 00 20 00 01 00 00 80 0b 00 01 80 0c 0e 10
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 80 01 00 05 80 02 00 02 80 03 00 01 80 04 00 02
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 0d 00 00 10 4f 45 68 79 4c 64 41 43 65 63 66 61
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 0d 00 00 14 af ca d7 13 68 a1 f1 c9 6b 86 96 fc
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 77 57 01 00 0d 00 00 14 4a 13 1c 81 07 03 58 45
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 5c 57 28 f2 0e 95 45 2f 0d 00 00 14 7d 94 19 a6
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 53 10 ca 6f 2c 17 9d 92 15 52 9d 56 0d 00 00 14
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 90 cb 80 91 3e bb 69 6e 08 63 81 b5 ec 42 7b 1f
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 0d 00 00 14 cd 60 46 43 35 df 21 f8 7c fd b2 fc
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 68 b6 a4 48 00 00 00 14 44 85 15 2d 18 b6 bb cd
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 0b e8 a8 46 95 79 dd cc
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | inserting event EVENT_RETRANSMIT, timeout in 40 seconds for #3
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | event added at head of queue
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | next event EVENT_RETRANSMIT in 40 seconds for #3
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: |
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | *received 102 bytes from right-remote-ip:500 on eth0 (port=500)
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | d4 0f fc 5c 9e 33 ff 5c ea 4d ff dd 95 e3 6b 72
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 0b 10 05 00 78 fb f6 0f 00 00 00 66 00 00 00 4a
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 00 00 00 01 01 10 00 0e d4 0f fc 5c 9e 33 ff 5c
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ea 4d ff dd 95 e3 6b 72 80 0c 00 01 00 06 00 22
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 43 6f 75 6c 64 20 6e 6f 74 20 66 69 6e 64 20 61
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 63 63 65 70 74 61 62 6c 65 20 70 72 6f 70 6f 73
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | 61 6c 80 08 00 00
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | **parse ISAKMP Message:
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | initiator cookie:
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | d4 0f fc 5c 9e 33 ff 5c
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | responder cookie:
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ea 4d ff dd 95 e3 6b 72
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | next payload type: ISAKMP_NEXT_N
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ISAKMP version: ISAKMP Version 1.0 (rfc2407)
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | exchange type: ISAKMP_XCHG_INFO
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | flags: none
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | message ID: 78 fb f6 0f
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | length: 102
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | processing version=1.0 packet with exchange type=ISAKMP_XCHG_INFO (5)
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ICOOKIE: d4 0f fc 5c 9e 33 ff 5c
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | RCOOKIE: ea 4d ff dd 95 e3 6b 72
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | state hash entry 3
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | p15 state object not found
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ICOOKIE: d4 0f fc 5c 9e 33 ff 5c
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | RCOOKIE: 00 00 00 00 00 00 00 00
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | state hash entry 5
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | v1 peer and cookies match on #3, provided msgid 00000000 vs 00000000
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | v1 state object #3 found, in STATE_MAIN_I1
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | processing connection xxxx@xxxx
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | got payload 0x800(ISAKMP_NEXT_N) needed: 0x0 opt: 0x0
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | ***parse ISAKMP Notification Payload:
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | next payload type: ISAKMP_NEXT_NONE
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | length: 74
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | DOI: ISAKMP_DOI_IPSEC
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | protocol ID: 1
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | SPI size: 16
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | Notify Message Type: NO_PROPOSAL_CHOSEN
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: “xxxx@xxxx” #3: ignoring informational payload, type NO_PROPOSAL_CHOSEN msgid=00000000
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | info: d4 0f fc 5c 9e 33 ff 5c ea 4d ff dd 95 e3 6b 72
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | info: 80 0c 00 01 00 06 00 22 43 6f 75 6c 64 20 6e 6f
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | info: 74 20 66 69 6e 64 20 61 63 63 65 70 74 61 62 6c
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | info: 65 20 70 72 6f 70 6f 73 61 6c 80 08 00 00
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | processing informational NO_PROPOSAL_CHOSEN (14)
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: “xxxx@xxxx” #3: received and ignored informational message
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | complete state transition with STF_IGNORE
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | * processed 0 messages from cryptographic helpers
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | next event EVENT_RETRANSMIT in 40 seconds for #3
    Jan 15 18:08:59 lrsxfcp10084 pluto[56598]: | next event EVENT_RETRANSMIT in 40 seconds for #3

    • No proposal chosen, as shown in the logs, means that your client is requesting something different than the server is able to provide.
      What client are you using, and how did you configure the VPN options?

  8. I followed this howto and with minor conf changes installed l2tp server succesfully. I can connect from android and windows clients (wirh reg mod).
    I installed l2tp server on centos 6.5, which acts as router for my network. I have also a mail server behind this router and port forwarding enabled.
    My router was configured OK and mail server running perfect with all ssl protocols, but after applying iptables from this howto, smtp acts as open relay, SMTP trafic through router was not NAT-ed ok, but sent to mail server as local traffic from router (inside IP).
    Can enyone try to modify iptables?
    Thank You,
    regards from Slovenia/Europe.

  9. Hey just wanted to give you a quick heads up. The text in your content seem to be running off the screen in Safari. I’m not sure if this is a formatting issue or something to do with web browser compatibility but I thought I’d post to let you know. The layout look great though! Hope you get the problem solved soon. Many thanks

6 Trackbacks / Pingbacks

  1. How to: Set up Openswan L2TP VPN Server on CentOS 6 | Earth-Works Tips & Tricks - ちゅどん道中記
  2. Site-to-Site VPN between AWS VPC and Customer Site using Linux | Lazy Geek -:)
  3. Site-to-Site VPN between AWS VPC and Customer Site using Linux | Thoai Media
  4. Centos Vpn Server | Kuplux's
  5. Centos L2tp Server | 寒星晓月
  6. centos 6.4 用openswan ipsec和xl2tpd搭建l2tp VPN(适用于KVM VPS) | 继恩之家

Leave a Reply

Your email address will not be published.


*