Quick and Dirty VPN Server with pptpd

I’ve recently found myself wanting to be able to quickly create a VPN server, with minimal client-side setup. Normally, my VPN Server of choice is OpenVPN, but this doesn’t really fill those criteria – server side, you’ve got to generate keyfiles, certificates, config files. This wouldn’t be so bad – but it’s a similar story client-side. If your grandma want’s a VPN connection, then having to send over OpenVPN installers, certificate files and configs isn’t ideal.

Most operating systems have built-in support for a VPN Protocol called “PPTP”, or Point-to-Point Tunneling Protocol, so I decided to investigate. It turns out that minimal effort is required to set up a PPTP server, and virtually NO effort is required on the client side. PPTP is supported by OS X, Windows, Android, iOS natively, and can clients are easily obtainable for Linux and various BSD distributions.

Before I go any further – I’d like to clarify that PPTP is NOT terribly secure. I wouldn’t use it for transferring any particularly sensitive information; I’m using it purely for convenience reasons. I’d recommend it for watching Netflix or Hulu from outside the US, but not for transferring mega secret nuclear launch-codes. Services exist that allow the cracking of MS-CHAPv2, the protocol that PPTP uses for encrypting┬ácommunications.

OK, now that you know not to use PPTP/MS-CHAPv2 as a security measure, lets move on.

These instructions were tested on Debian 7.0 – but installation aside, should be valid for any distro.

Install PPTPD. This can be done via a simple apt-get install pptpd.

Open up /etc/pptpd.conf in your editor of choice. At the end of the file, add these lines:

localip x.x.x.x
remoteip y.y.y.y-z

where x.x.x.x is the external IP of your server, and remoteip y.y.y.y-z, where y.y.y.y is the first address in the range you wish to assign to your clients, and z is the last octet of the last address you wish to assign to clients. For instance, if I wanted client IPs to lie in the range 192.168.0.1-192.168.0.254, I’d enter remoteip 192.168.0.1-254. You don’t need to do anything special to be able to assign these IPs, it’s all handled for you. Just make sure you use private address space, it’d be rude not to.

You should also append:

ms-dns 208.67.222.222
ms-dns 208.67.220.220

to the file, in order to specific the DNS servers you want your clients to use. You can, of course, substitute the 208.67.222.220/208.67.222.220 with DNS servers of your choice.

Now that the pptpd is configured, we need to allow our server to forward IPv4 traffic. This can be done by editing /etc/sysctl.conf, and uncommenting the line that reads #net.ipv4.ip_forward=1. We then need to reload the sysctl.conf file – this can be done by running sudo sysctl -p.

We also need to configure iptables to perform NAT – this can be done by running iptables -A POSTROUTING -t nat -j SNAT --to-source z.z.z.z, where z.z.z.z is the external IP of your VPS. It’s worth noting that iptables rules aren’t persisted to disk – check out this article to see how to make them survive a reboot.

We’re almost set – all that’s left to do is to create a pptpd user. This is done by editing the file /etc/ppp/chap-secrets. Entries are stored in the form username service password ip – so if I wanted to add a user called bob, with the password bananna and the IP 192.168.0.1, I’d add the line:

bob pptpd bananna 192.168.0.1

(Bear in mind that passwords in /etc/ppp/chap-secrets are stored in plaintext.)

Your pptpd VPN server is now configured – all that’s left to do is to run /etc/init.d/pptpd restart to make the changes take effect.