VPN Tunnel with PPTP and Poptop

There's many reasons you may want to setup a VPN. I was looking to route all my internet traffic through a vpn for anonymous browsing, specifically for when I am connected to a public wifi. Whatever reason you may have, setting up a VPN is an easy and straight forward process.

First step will be to install and configure a VPN on a remote server. We will be using Poptop (pptpd) which is an open source implementation of the Point to point Tunneling Protocol. For the remote server, I use an EC2 instance from Amazon, however you can use any host you like. Just ensure your host will allow traffic on port 1723. This is the port pptpd listens on and is not configurable. For AWS, this was a security group setting from the EC2 panel. For this first install, I am running Ubuntu 10.04, so this post will be geared towards installing on Ubuntu.

After the server has been installed and configured, a local client will need to be installed to connect to our vpn. PPTPClient. The client will be installed on ArchLinux, but will be compatible with most Linux distributions.

Setting up the remote VPN with PPTP

Install PPTP

Login to your server and install the PPTP daemon.

sudo apt-get install pptpd

Next we need to define the ip range that will be used to assign addresses to clients when they connect. Open /etc/pptpd.conf and uncomment the following directives. See pptpd.conf(5) for more details and other options.

localip 192.168.0.1
remoteip 192.168.0.2-100

The last step in configuring the daemon, we need to add a user. Open /etc/ppp/chap-secrets and add the following to the end of the file replacing USERNAME and PASSWORD with the credentials you would like to use.

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
$USERNAME	$SERVER	$PASSWORD			*

The asterisk allows clients to connect from any ip address.

With the daemon configured restart pptpd.

sudo service pptpd restart

Configure IPv4 Forwarding

At this point the vpn is setup, however no internet traffic will be routed through the vpn. To start, the IPv4 policy needs to allow ip forwarding. This can be enabled by modifying the kernel parameters in /etc/sysctl.conf

net.ipv4.ip_forward = 1

Now reload the configuration.

sudo sysctl -p

Next, rules need to be defined in the iptables so packets being sent out to the Internet are modified to take the ip address of our VPN. Add the following two commands to /etc/rc.local. This script is will be ran at boot so the iptables are always updated. Run each line at a command prompt to immediately enable these settings.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

The first line updates the nat table (-t nat) to alter all packets going out eth0 (-A POSTROUTING -o eth0) to use the vpn's ip address (-j MASQUERADE). If your internet connection goes out over a different interface, replace eth0 in the first statement with your setting.

The second line ensures the maximum segment size (mss) of the tcp packets are clamped (restricted) to the maximum transmission unit (msu). This means responding servers will never send packets larger than can be received. More information on this specific command can be found by searching the iptables manpage for 'TCPMSS'. LATRC.org also has a clear explanation.

Connecting to our VPN

Install PPTP-Client

If you are looking to start the vpn at boot, look at your

Install the package from your package manager.

sudo pacman -S pptp-client

We need to add a user to pptp-client the same way we did with pptpd. Edit /etc/ppp/chap-secrets with the same credentials as before.

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
$USERNAME	$SERVER	$PASSWORD			*

With our credentials file setup, a configuration file will need to be created at /etc/ppp/peers/. Enter the following into the new file:

pty "pptp $VPN_IP --nolaunchpppd"
name $USERNAME
usepeerdns
defaultroute
remotename $SERVER
require-mppe-128
file /etc/ppp/options.pptp
ipparam $VPN

Make sure to replace $VPN_IP with either the ip address or domain name of your remote server. Ensure $USERNAME and $SERVER are consistent with what is in the two chaps-secrets files. Finally ensure the ipparam value matches the name of the file created.

The client is configured, finally we can connect to the VPN.

Connecting and Routing

sudo pon $VPN

where $VPN is the name of the configuration file in /etc/ppp/peers. This will establish a connection with the vpn. Check that you have successfully connected by running

sudo ip addr

There should be a network interface ppp0. If not, something went wrong and you can debug the issue with

pon $VPN debug dump logfd 2 nodetach

This will give you some insight into the error, and either PPTP Client Diagnosis or Google will have the solution.

Once we are certain the connection has been made, we need to route our internet traffic through the new interface. $INTERFACE should be replaced with the current interface used to connect to the internet.

sudo ip route del default dev $INTERFACE
sudo ip route add default dev ppp0

Now, all of your internet traffic is going out through the vpn and using it's ip address. You can verify this by running

curl http://automation.whatismyip.com/n09230945.asp

This will return the ip address of your vpn

When you want to disconnect from the vpn use

sudo poff $VPN

Then reverse the ip route

commands from above to reroute through your original interface. You may also need to restart previously running network managers. For me I always have to run the following to restart my wireless connection.
sudo netcfg -R wlan0

And there you have it. A secure VPN to route traffic through.