|Just as with my Postfix HOWTO I am going to share my experiences in setting up a a working PPTP VPN server. I decided to write this after I saw a lack of concise documentation for the current versions of PoPToP and the current Linux kernel.
By the end of this document you will hopefully achieve what I have:
- Be running the latest stable release of PoPToP (1.1.4 at the time of this document).
- Patch your Linux kernel (2.6.6 as of this document) with MPPE and MPPC support.
- Patch the latest stable version of pppd (2.4.2 as of this document) with MPPE and MPPC support.
- Allow remote clients to connect to your network using the VPN server.
- Encrypt the VPN tunnel with the MPPE protocol.
- Compress the data in the tunnel with the MPPC protocol.
- Authentication done through MS CHAP-v2.
- Run your VPN server behind a Linux firewall utilizing iptables (optional, but still covered)
To start off, you will use the following applications/patches:
08/16/04: After countless hours of scratching my head trying to figure this out on a VPN server I'm setting up, I finally figued it out. Even though the MPPE patch was enabled in the kernel, it wasn't being recognized by pppd. After reading Jan's site I noticed that I had to enable SHA1 and RC4 encyption in the kernel. Recompiled and viola, works again.
Installing and Patching Sources
I normally extract my kernel source into /usr/src and link to "linux". Extract the kernel, put the Kernel patch (linux-2.6.6-mppe-mppc-1.0.patch.gz) into the same directory, extract it, and patch the kernel as follows. Finally install it as you normally do.
$ tar zxvf linux-2.6.6.tar.gz
$ ln -s linux-2.6.6 linux
$ gunzip linux-2.6.6-mppe-mppc-1.0.patch.gz
$ patch -p0 -i linux-2.6.6-mppe-mppc-1.0.patch
$ cd linux
$ make menuconfig (or the config tool of your choice)
go to Device Drivers -> Networking Options -> select "PPP support" and then select "Microsoft PPP compression/encryption (MPPC/MPPE)"
$ make bzImage
After you finish patching and compiling the kernel (hopefully you have boot into it by now), it's now time to patch and install a copy of pppd. Make sure you have the pppd patch in the same directory as the pppd tar.gz (ppp-2.4.2-mppe-mppc-1.0.patch.gz).
$ tar zxvf ppp-2.4.2.tar.gz
$ gunzip ppp-2.4.2-mppe-mppc-1.0.patch.gz
$ patch -p0 -i ppp-2.4.2-mppe-mppc-1.0.patch
$ cd ppp-2.4.2
$ make install (as root)
Finally we compile an install a copy of the PoPToP PPTPD.
$ tar zxvf pptpd-1.1.4-b4.tar.gz
$ cd poptop-1.1.4
$ make install (as root)
Now for configuring all of this.
First let's setup the configuration file for PoPToP. By default it resides in /etc/pptpd.conf. Here is my configuration file:
Let's go over this line-by-line.
The first line specifies the pppd configuration file, for the sake of this document (and my setup), we're going to use /etc/ppp/options-pptpd.
The second line is set to the IP address of the server's network interface (in my case, 172.19.1.6).
The line after that tells the the daemon what IP addresses to assign to incoming clients that connect to the server. In my configuration file it will give the IP addresses 172.19.1.30 to 172.19.1.50.
In the last section we setup the configuration file for our pptpd daemon. In the first line we specified the pppd configuration file. This is the one we're going to configure next. NOTE: for security sake, MAKE SURE that the /etc/ppp directory and everything in it are chmod'ed 700 and only root owns it.
My options-pptpd file looks like this:
# Handshake Auth Method
# Data Encryption Methods
The two lines that I had trouble with are the mschap-v2 and mppe lines.
My first mistake was that instead of putting "+mschap-v2" I was putting "chapms-v2" as I had in my configuration file that used an older version of pppd. Oddly enough pppd would not error out on this, but eventually after searching google I was able to find the correct syntax.
And lastly, I was not using the right syntax for the MPPE patch. Even though Jan Dubiec mentioned on his page that he uses a different syntax for initiating his patch, I neglected to pay attention to that and used the common "+mppe-128" line.
Now we need to create the chap-secrets. This file belongs in /etc/ppp/chap-secrets. It is very important the this file be accessible by only root and no one else as it contains plaintext passwords.
# Client Server Password IP Address
Serge * stupidpassword *
This will allow the user "Serge" with the password "stupidpassword" to connect to this VPN server from any IP address.
Now let's start everything up and see if it works (*crosses fingers*).
$ /usr/local/sbin/pptpd (as root)
Let's check our /var/log/messages file to make sure it didn't fail...
Jun 1 11:00:43 merlot pptpd: MGR: Manager process started
Jun 1 11:00:43 merlot pptpd: MGR: Maximum of 21 connections available
Go to your Windows client (XP Pro in my case) and open "Network Connections."
Start the "New Connection Wizard." Choose "connect to the network at my workplace" ->
Choose "Virtual Private Network connection" ->
Enter a name for your connection ->
Enter the hostname of the VPN server ->
Go to the properties of this new connection. Click on the "Networking" tab ->
Double click on "Internet Protocol (TCP/IP)" ->
Click on "Advanced..." ->
Untick "Use default gateway on remote network."
This will prevent all your Internet traffic from running through the VPN server (not necessary to do this, but I do).
Now for the real moment of truth. Trying to connect...
Enter your username and password in the connection dialog box and click "Connect." Monitor your /var/log/messages file, you should see something like this:
Jun 1 11:11:32 merlot pptpd: CTRL: Client 172.19.1.89 control connection started
Jun 1 11:11:32 merlot pptpd: CTRL: Starting call (launching pppd, opening GRE)
Jun 1 11:11:32 merlot pppd: pppd 2.4.2 started by root, uid 0
Jun 1 11:11:32 merlot pppd: Using interface ppp0
Jun 1 11:11:32 merlot pppd: Connect: ppp0 <--> /dev/pts/77
Jun 1 11:11:35 merlot pppd: MPPC/MPPE 128-bit stateful compression enabled
Jun 1 11:11:38 merlot pppd: found interface eth0 for proxy arp
Jun 1 11:11:38 merlot pppd: local IP address 172.19.1.6
Jun 1 11:11:38 merlot pppd: remote IP address 172.19.1.31
If you see this... CONGRATULATIONS!
You have successfully setup a Linux-based PPTP VPN server capable of MPPC and MPPE using MS-CHAP v2 for handshake authentication.
VPN Server Behind Firewall (optional)
In the event that your VPN server is behind a Linux (iptables) firewall and you want to have access to it from the Internet, follow these quick instructions:
First of all, you must have "IP: GRE tunnels over IP" and "IP: broadcast GRE over IP" support in your kernel. Make sure you have that done, or else this might not work.
To forward the PPTP ports from your router's external interface (eth1 in my case, eth0 is my internal interface, 172.19.1.6 is my VPN server's internal IP) to your VPN server, use this iptables rule set:
$ /sbin/iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 1723 -j DNAT --to 172.19.1.6
$ /sbin/iptables -A FORWARD -i eth1 -o eth0 -p TCP -d 172.19.1.6 --dport 1723 -j ACCEPT
$ /sbin/iptables -A FORWARD -i eth1 -o eth0 -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$ /sbin/iptables -t nat -A PREROUTING -i eth1 -p 47 -j DNAT --to 172.19.1.6
Hope that this document has helped some of you in some way or another. Happy VPN'ing!