Linux VPN Guide | Go Back

Linux VPN Guide will help you to create a Linux-based VPN server which can be accessed from any Windows client (primarily Windows XP, but can be extended to work with older Windows operating systems such as Windows 2000 or 95/98/NT). I wrote this guide because of the pain I went through to get VPN up and running at my work. After a couple of days of struggling and heavy debugging I was able to set up a VPN server on Fedora Core 2 and 3 with latest updates. I decided that VPN installation should not be such a nightmare and tried to make everything as simple as possible in this guide.

Linux-Windows VPN Guide with OpenSWAN, l2tpd and pppd

1) Who should use this guide?
If you have a private network that you want to be able to access remotely in VPN (virtual private networking) environment (for example, if you have servers at your workplace that are firewalled from outside with internal IP addresses such as 192.168.x.x and you want to be able to access them from the internet), this guide is definitely for you.

2) Can this guide be used on production servers?
To be honest, I’m not sure yet. I have been using this VPN solution for a while now and haven’t had any problems so far. But if you notice any performance/compatibility/stability related issues, please let me know.

3) What about security?
VPN is a secure virtual tunnel, which means security is built into it. However, just like any “bullet-proof” solution out there, it has its own security-related issues. First of all, this guide only shows you how to use PSK (pre-shared security key) method of authenticating a VPN tunnel. Your VPN tunnel is encrypted with this security key and in case the key is stolen (or broken with a brute-force attack), your security is compromised. You can use other methods of encryption based on SSL (secure socket layer), but the process of setting up a VPN server and connecting the clients to it is rather complicated. You can refer to Jacco’s VPN tutorial to set up a VPN solution based on SSL. As long as your PSK is very long, unguessable and not prone to a simple brute-force, you should not worry about security.

4) On what operating systems has this guide been tested on?
Installation has been successfully tested on Redhat Linux 9.0 and Fedora Core 1/2/3/4, but it should also work on any other linux flavor. For BSD systems, you would have to obtain source files for OpenSWAN and change some configuration options on l2tpd to be able to compile everything successfully.

5) Stuff we’ll be needing (sources)
Download the following sources to a src directory i.e. /usr/local/src

- OpenSWAN 2.6.14 from http://www.openswan.org | Mirror
- l2tpd 0.69 from this site
- l2tpd Legacy PTY patch from this site
- l2tpd SysV PTY patch from this site
- l2tpd startup file from this site

6) Assumptions
It is assumed that ppp is already installed on the system and you are running the latest version of linux kernel 2.4 or 2.6. You can check if you have ppp installed on the system by running a query in your package manager (”rpm -q -a | grep ppp” in Redhat or Fedora). You can check the kernel version by running “cat /proc/version”.

7) OpenSWAN installation and configuration
I recommend downloading an RPM from openswan.org instead of the source tarball, since the RPM has the patches integrated to fit your system. In case you want to compile OpenSWAN yourself, you will have to find out which patches you need for your system. Compilation and installation from source is pretty straightforward - just read the README file and follow the instructions. Run the following command to see if you already have OpenSWAN installed: “rpm -q -a | grep openswan”. If openswan is not installed, proceed with the installation.

# cd /usr/local/src
# yum install openswan
# yum install openswan-doc

The openswan-doc rpm file includes all the documentation which you might need in the future.

The OpenSWAN installation has a sample ipsec.conf file included. Let’s go ahead and rename it:

# mv /etc/ipsec.conf /etc/ipsec.conf.old

Now copy-paste the following into /etc/ipsec.conf

version 2.0
config setup
interfaces=%defaultroute
klipsdebug=none
plutodebug=none
overridemtu=1410
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:192.168.0.0/16

conn %default
keyingtries=3
compress=yes
disablearrivalcheck=no
authby=secret
type=tunnel
keyexchange=ike
ikelifetime=240m
keylife=60m

conn roadwarrior-net
leftsubnet=192.168.0.0/16
also=roadwarrior

conn roadwarrior-all
leftsubnet=0.0.0.0/0
also=roadwarrior

conn roadwarrior-l2tp
leftprotoport=17/0
rightprotoport=17/1701
also=roadwarrior

conn roadwarrior-l2tp-updatedwin
leftprotoport=17/1701
rightprotoport=17/1701
also=roadwarrior

conn roadwarrior
pfs=no
left=150.150.150.150
leftnexthop=150.150.150.1
right=%any
rightsubnet=vhost:%no,%priv
auto=add

#Disable Opportunistic Encryption
include /etc/ipsec.d/examples/no_oe.conf

Don’t forget to replace “150.150.150.150″ with your external IP address and “150.150.150.1″ with your default gateway. I’m not going to explain what each line above does. If you want to find out for yourself, please refer to OpenSWAN documentation. The above configuration should work for most people, though.

Now edit the file “/etc/ipsec.secrets” and put the following:

150.150.150.150 %any: PSK “a_very_long_string_up_to_256_characters”

The format of the file is: “external_network_address connecting_from: PSK password”. Change “150.150.150.150″ to your external IP address. If you want to be able to access the network from anywhere on the Internet, leave “%any” intact. I recommend specifying the IP address of the machine that will be used to initiate VPN connections for security reasons though. PSK stands for “Pre-Shared Key” - it’s the key that will be shared by both the server and the client for authentication. Make sure that the key is long (up to 256 characters) and very random. Every client trying to establish a VPN connection will have to provide this pre-shared key.

8) l2tpd installation and configuration
First of all, let me give you some information on l2tpd. The project started out really well and a big community was involved in its development. But seems like the project has been suspended for some reason and there haven’t been any new releases of l2tpd since version 0.69 which is more than a year old. Latest versions of the linux distributions such as Fedora and Mandrake are compiled with a new SysV pty system. The current version of l2tpd only supports the old pty system and therefore will not work on these distros unless its patched. Jacco de Leeuw talks about this problem in his detailed VPN guide here. An alternative is to switch to rp-l2tp, which is another l2tpd daemon. But it is not a good way out, since it does not support automatic IP allocations to new connections. Another solution is to recompile the kernel with “Legacy (BSD) PTY support”, but most people simply don’t know how to do that or are too scared to do it. Recompiling the kernel might be a big problem for those who don’t have physical access to the machine. After many hours of googling, I was able to find some patches that fix current l2tpd issues and add some features such as binding l2tpd to a specific IP address. Now here is the interesting part - the rp-l2tp package contains pty.c code that is known to work with the new pty system. I tried to simply copy-paste the script into l2tpd pty.c file, modified l2tpd.c to call “pty_get” instead of the old “getPtyMaster”, removed all other pty calls and it worked! I was able to test l2tpd setup successfully on a Fedora Core 3 machine without recompiling the kernel :)

I have included two patches on this page. If you have a recent version of a linux distribution with 2.6 kernel, go ahead and download the file “l2tpd-0.69.sysv.patch”. If you have an older version of linux with the old pty system, go ahead and download the file “l2tpd-0.69.lpty.patch”.

Now, let’s install l2tpd and apply the patch:

# cd /usr/local/src
# tar zxf l2tpd-0.69.tar.gz
# mv l2tpd-0.69.sysv.patch l2tpd-0.69/
# mv l2tpd /etc/rc.d/init.d/
# cd l2tpd-0.69
# patch < l2tpd-0.69.sysv.patch
# make
# cp l2tpd /usr/sbin
# chmod 755 /usr/sbin/l2tpd

Running “make” should compile an l2tpd executable without errors. You might get a couple of warnings, but no fatal errors. If you try to compile the source without patching it first, you will most probably get compilation errors (especially on systems with a newer gcc). Now configure the startup environment:

# chmod 755 /etc/rc.d/init.d/l2tpd
# chkconfig –add l2tpd
# chkconfig l2tpd on

Let’s move on to configuring l2tpd. The configuration files for l2tpd should be placed in “/etc/l2tpd” folder. Go ahead and create the folder, then copy paste the following into l2tpd.conf:

[global]
port = 1701

[lns default]
ip range = 192.168.1.101-192.168.1.254
local ip = 192.168.1.100
require chap = yes
refuse pap = yes
require authentication = yes
name = LinuxVPN
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd
length bit = yes

The “ip range” line is the start and the end pool of the IP addresses the clients will be given when they establish a VPN connection (on their end). The “local ip” is server IP address - it’s used only when at least one connection is established. If you have a different internal network, go ahead and change both lines. Everything else should work for most people. Again, if you want to find out what each line does, please feel free to refer to l2tpd documentation.

9) PPP configuration
L2TP tunnels through PPP, which is why we need to configure it to work with l2tpd. The l2tpd configuration above specifies the “/etc/ppp/options.l2tpd” file as “pppoptfile” (PPP options file). Go ahead and create this file and copy-paste the following:

ipcp-accept-local
ipcp-accept-remote
ms-dns 192.168.1.2
ms-wins 192.168.1.3
noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
silent

Change the line “ms-dns” to your real DNS server and “ms-wins” to your WINS server (if you have any).

Now let’s create the authentication files. We use CHAP for PPP authentication. Go ahead and edit the file “/etc/ppp/chap-secrets”. The format of this file should be “client server secret IP addresses”. Here is a sample file:

# Secrets for authentication using CHAP
# client server secret IP addresses
username * “password” 192.168.1.0/24
* username “password” 192.168.1.0/24

You need two lines for each username because it’s a two-sided authentication - one from client to server and one from server to client. Both the password and the IP address pool should be the same for both lines. The IP address network that we specify here (192.168.1.0/24) means “allow this username to get an IP address in the range 192.168.1.0 - 192.168.1.255″. The l2tpd configuration file above specifies the range to be 192.168.1.101-192.168.1.254, so only the IPs in this range are given to the client on successful authentication. You can change the networks and subnets in both files as needed. If you need more than one account to be able to access the server, go ahead and add it in the same format.

10) Starting and testing VPN
Everything is installed and configured. Let’s go ahead and start the daemons:

Starting l2tpd:

/etc/rc.d/init.d/l2tpd start
Starting l2tpd: [ OK ]

Starting OpenSWAN:

/etc/rc.d/init.d/ipsec start
ipsec_setup: Starting Openswan IPsec 2.4.0…
ipsec_setup: insmod /lib/modules/2.6.10-1.741_FC3/kernel/net/key/af_key.ko
ipsec_setup: insmod /lib/modules/2.6.10-1.741_FC3/kernel/net/ipv4/xfrm4_tunnel.ko

Take a look at /var/log/messages and /var/log/secure and make sure there are no errors. You should see notification messages such as “l2tpd: l2tpd startup succeeded” and “ipsec_setup: Starting Openswan IPsec 2.4.0…”. If there are no errors, everything is up and running - proceed to next step.

11) Firewall configuration
To be able to route packets from your external to internal interfaces, packet forwarding must be turned on. Edit /etc/sysctl.conf and change “net.ipv4.ip_forward = 0″ to “net.ipv4.ip_forward = 1″. If you don’t have that file, just type “echo 1 > /proc/sys/net/ipv4/ip_forward” and add this line to your /etc/rc.d/rc.local file. Restart your networking by typing “/etc/rc.d/init.d/network restart” or whichever way you restart your network interfaces.

Make sure that the following ports are open: UDP 500 & 4500, TCP 4500. If any of these ports are blocked, VPN will not work. If you have Redhat/Fedora distributions with iptables, insert these lines into your /etc/sysconfig/iptables file, before REJECT line at the end of the file:

-A RH-Firewall-1-INPUT -i ppp+ -j ACCEPT
-A RH-Firewall-1-INPUT -i eth1 -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state NEW -m udp -p udp –dport 500 -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 4500 -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state NEW -m udp -p udp –dport 4500 -j ACCEPT

One more thing you should keep in mind while changing your firewall configuration - your internal and VPN network should be trusted, otherwise your firewall will keep rejecting packets from 192.168.x.x network into your LAN. I solve this by simply adding the first two lines above into my iptables file. The interface eth0 is external and eth1 is physically inside my internal network, of course :)

Pages: 1 2 3

Posted by MegaZ on 01/28/2005.

39 Responses to “Linux VPN Guide”


  1. dillip says:

    Hi
    It is the most comprehensive document on VPN which I have come across and everything worked fine on RHEL5 and it is functioning in it’s first attempt :-) thanks for everything

    dillip

  2. Bal Krishna says:

    I followd all of youre steps and while connecting from XP with SP2 i get error no. 721 after saying verifying username and passwod. can you trace what is my my error

  3. Nitin says:

    hi to all,

    I need help in creating a vpn connection between winxp and fedora where fedora is acting as server while winxp is client.
    on server openswan is installed while using l2tp ipsec vpn on windows.
    my mail id : techsolnltd at gmail dot com

    Regards

  4. dierque says:

    may i know howto IPsec work at ur VPN configuration??
    for my thesis :D thank

  5. mike says:

    do you have VPN Linux configuration with radius as database authentication?

  6. Rejeth says:

    Hello Ian if you speak Spanish i will help you with your VPN (L2TP with IPsec)

  7. ian says:

    would you like to give me flow chart to descript your VPN (L2TP with IPsec)…???
    i hope you will help me….tahnx before.-ian- (sorry, if my english is not good :D )

  8. Rejeth says:

    hi
    Thanks for your help;your guide I help myself much.
    Thanks again

  9. hi
    when i first saw your name i guess that you are iranian ( as i am iranian).
    i comment here to say that your guide help me a lot. but i am writing a guide in persian
    for debian release and i want to use some part of your articles.
    Do u know persian?
    can use your article in my guide?
    tanx

    its an honor for me if you came to my very very small weblog. tanx again

  10. Ismael Gongora says:

    How can I configure this with windows 2000, and some other versions of windows??

  11. Shahid Bashir says:

    hello everyone

    this guide just rocks

    can any body guid me how we can configure l2tpd/ipsec client for linux machine

    thanks

  12. Hossein Labbaf says:

    Simple reporting for the L2TPD/IPSEC VPN Server
    1. place the following script in your /etc/cron.hourly directory
    #————————————————————————-
    #!/bin/sh

    # retrieve date in 3 letter form and assign the value to DTNOW
    DTNOW=`date`

    # retrieve date in 3 letter form and assign the value to P1
    P1=`date +%b`

    # retrieve day of the month in leading space removed format and assign it to P2
    P2=`date +%e`

    # retrieve Hour in 24 format and assign it to P3
    P3=`date +%H`

    # retrieve the integer value of P3 and decrement it by one because
    # the script is run hourly and searches for the last hour access
    P4=`expr $P3 - 1`

    # Create a file in the /tmp directory
    # a randomly named file
    echo > /tmp/k30fsf98.log
    echo -e “VPN Connections made from $P4:00 to $P3:00 on $DTNOW and closed\r\n”>> /tmp/k30fsf98.log
    echo -e “Total Number of Connections: \r\n” >> /tmp/k30fsf98.log
    grep “$P1 $P2 $P4″ /var/log/messages | grep “name = ” | grep Response | wc -l >> /tmp/k30fsf98.log
    echo -e “Connection details: \r\n” >> /tmp/k30fsf98.log
    grep “$P1 $P2 $P4″ /var/log/messages | grep “name = ” | grep Response >> /tmp/k30fsf98.log
    echo -e “\r\n” >> /tmp/k30fsf98.log
    grep “$P1 $P2 $P4″ /var/log/messages | grep “Connection closed” >> /tmp/k30fsf98.log
    echo -e “\r\n” >> /tmp/k30fsf98.log
    grep “$P1 $P2 $P4″ /var/log/messages | grep “: Connect time” >> /tmp/k30fsf98.log
    cat /tmp/k30fsf98.log | mail -s “Hourly VPN log from $P4 and $P3 on $DTNOW” SOME_EMAIL@SOME_DOMAIN.COM
    #—————————————————————————
    2. Replace SOME_EMAIL@SOME_DOMAIN.COM with the email that is supposed to receive the hourly access report.

    HOSSEIN

  13. Sajjad says:

    This is perfect but to install a VPN server in fedora core5 you do not have to patch l2tpd.
    Just yum that with

    yum install l2tpd
    yum install Openswan

    and follow the same configuration options.

    Thanks

  14. sharmin says:

    Thanks for this guide.I m able to stablish vpn connection but only one client can access the server.I have already add the client in /etc/ppp/chap-secrets.But it can’t work.How can I give permission to unlimited access(client)?

  15. rana tanveer says:

    Wonderful web site, for VPN solution.

  16. Dehylus says:

    Not work whit shorewall 3.x firewall, any idea for configuring?. Read a wiki shorewall, but not a clear info for this pruposes. Help please, thanks.-

  17. speedy says:

    Thanx for this great howto! Building a VPN server has never been so simple. But I have a little problem getting my connections to work. I used your ipsec.conf, and only changed the relevant IP-addresses. Now every time I try to connect from some remote computer, I get an error message (in /var/log/messages) saying “cannot respond to IPsec SA request because no connection is known for [my PUBLIC ip-address]/32===[local IP of my VPN server]:17/1701…[public IP of remote computer][@Username]:17/1701″. The server then sends an encrypted notification INVALID_ID_INFORMATION to the remote computer.
    What am I doing wrong? Could you please help me?

  18. Didi says:

    hi there,

    this guide is works!
    everything is going fine, but i still have a bug,
    why this vpn cannot connect multiple user to server?
    i mean if im logged in and my friend wants to connect too, he cant connect
    im checking tail -f /var/log/secure and /var/log/mesages no indicator that my friend is rejected
    although we use different user?
    any one have same problem with me?
    any one help me?

    :’(

    thanks

  19. tmichals says:

    jhony, I ran into the same problem where %defaultroute was bombing on me when starting the service. The problem was the indentation of ipsec.conf was not showing properly within the instructions. The instructions look to be updated now.


Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word

Powered by WP Hashcash