Tuesday 22 January 2013

A £20 VPN Router: OpenWRT and the TP-Link TL-WR841N

I use a PPTP VPN service regularly, but it only allows a single continuous connection so it can't be shared easily between multiple devices (although my provider is happy for that single connection to come from a router however). So I decided to find and configure a router to maintain a VPN connection, and route specific devices on my network across the VPN link. The steps below may help you to do the same thing.

Standard disclaimer: Anything you do to your router will no doubt invalid its warranty, and if you're really unlucky you might even brick the thing completely. If you follow my instructions you've taken this risk upon yourself. Don't blame me if something goes wrong!

I used OpenWRT, a Linux distribution for embedded devices. OpenWRT is open source and has a great community providing all manner of additional packages, and more importantly pre-built images for dozens of popular devices.

The device I used was the TP-Link TL-WR841N Wireless N Cable Router. There are all manner of TP-Link routers available that run OpenWRT, but I was trying to get the cheapest possible device that would still accomplish what I wanted (I'm broke). If you can spend a bit more money, there are models with extra antennae, and gigabit ethernet (which would have been nice to have). If you are looking at this model in particular, you may see it referred to as the WR841N and WR841ND. These are the same device, the only difference being the antennae are detachable on the ND version. So for the purposes of hacking the thing, it's the same.

For the purposes of this post, I'm going to assume you have already set up OpenWRT to accomplish basic tasks (provide a local network and WiFi, connect to your ISP etc.) and you're just here for the PPTP VPN goodness. It would take me too long to cover all the basics and they are already very well documented at the OpenWRT Wiki.

In a nutshell, I used this firmware image:
openwrt-ar71xx-generic-tl-wr841n-v8-squashfs-factory.bin

And followed the initial installation steps found here:
http://wiki.openwrt.org/toh/tp-link/tl-wr841nd
here: http://wiki.openwrt.org/doc/howto/firstlogin
and here: http://wiki.openwrt.org/doc/howto/basic.config

Now for the fun stuff.

Install PPTP VPN Client


Login via SSH and install the necessary packages:

opkg update
opkg install ppp-mod-pptp

Next, you'll need to edit the /etc/network/interfaces files and and append the following, replacing the server name and credentials with those from your VPN provider:

config 'interface' 'vpn' 
        option 'ifname'    'pptp-vpn'  
        option 'proto'     'pptp'
        option 'username'  'vpnusername'
        option 'password'  'vpnpassword'
        option 'server'    'vpn.example.org or ipaddress' 
        option 'buffering' '1' 

You can use vi to edit the file. If you're new to vi, have a quick read of this page.

You can now bring the interface up with this command:

ifup vpn

Wait a few seconds for the VPN connection to handshake and you should be able to see an interface called pptp-vpn:

root@OpenWrt:~# ifconfig -a
pptp-vpn  Link encap:Point-to-Point Protocol  

          inet addr:xxx.xxx.xxx.xxx  P-t-P:xxx.xxx.xxx.xxx  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1400  Metric:1
          RX packets:59720 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
          RX bytes:2152092 (2.0 MiB)  TX bytes:80 (80.0 B)


Your VPN interface is now up, but you're not using it. The first thing you need to do is add the interface to a firewall zone. It's easier to do this from LuCi, the web interface. In fact, if we'd done the whole thing though LuCi it would have done this for you - but it would have also steamrollered the routing, which we'll come to in a moment.

Login to the web interface, select Network > Interfaces and click 'Edit' on the VPN interface. Select 'Firewall Settings' and add the VPN to the WAN firewall zone. This grants the same firewall permissions to the VPN route as your standard default route (your WAN connection).

Set up DHCP and static assignments


We're going to do some clever routing in a minute, but a prerequisite for this is that devices on your network have fixed IP addresses. This way we can create rules for them that determine which route they use to connect to the Internet.

There are several ways to achieve this, but perhaps the easiest (from a device point of view) is to ensure that your DHCP server always gives the same IP address to the same device.

In LuCi, select Network > DHCP and DNS. You will see a list of existing DHCP leases, and at the bottom of the page you can click the Add button to add static leases. Here you can pick a device by its MAC address or by its current IP address, and then pick a static IP. The static IP should be part of your network obviously, so if your LAN uses the 192.168.1.0/24 network, you can pick any IP from 192.168.1.2 to 192.168.1.254.

You'll need your device (laptop, phone etc.) to renew its DHCP lease. It may not pick up the new IP immediately. Make a note of the IP addresses you want to route through the VPN.

Set up Routing Tables


For this next trick, you'll need the ip package (formerly iproute2) which you may not have. To install it, type:

opkg install ip

Now you'll need to edit the file /etc/iproute2/rt_tables, which ip creates. Edit in in vi of course! You're going to add a line specifying route table 10 for the VPN. When you're done it should look like this:


#
# reserved values
#
255  local
254  main
253  default
10   vpn
0    unspec
#
# local
#
#1   inr.ruhelp

Now we've created a new table specifically for VPN routes, we'll add some devices to it. Say we have 2 computers that we want to traverse our VPN with IP addresses of 192.168.1.35 and 192.168.1.45. Enter the following commands:


ip rule add from 192.168.1.35 table vpn
ip rule add from 192.168.1.45 table vpn

Now we just tell the router what to do with devices in this table:

ip route add default via <tunnel_ip> dev pptp-vpn table vpn

Replace <tunnel_ip> with the IP address shown as 'inet addr' (the first one) in the ifconfig output above. Make sure you're taking it from the pptp-vpn bit of the ifconfig output.

That's it! Give your router a few seconds to sort its cache out, and then try browsing whatsmyip.net from one of those devices. You should see your VPN address.



Scripts


Your VPN connection may not stay alive for ever. If it fails (mine seems to once or twice a day), your router should automatically reconnect it, but you'll end up with a different IP address. Your routing table will no longer be able to route those devices to that IP. Rather than log in and update the route every time this happens, I created the following script:


#!/bin/sh

VPNIP=`ip addr show pptp-vpn | sed -n '3p' | awk '{ print $2 }'`
ROUTE=`ip route show table vpn | awk '{ print $3 }'`

if [ "$VPNIP" != "$ROUTE" ]; then
    ip route add default via $VPNIP dev pptp-vpn table vpn
fi

This script will check if the VPN route is out of sync with the VPN IP address, and update it if necessary. You can even run this every minute from cron. 

First, save the script as /root/checkvpn.sh.

Then, navigate to System > Scheduled Tasks in LuCi, and add the following:

* * * * * /root/checkvpn.sh


Another handy tip is to create some scripts on your local computers to add themselves, or remove themselves from the VPN table. You can do these as shell scripts, make desktop shortcuts to them etc... the specifics will vary depending on your platform. The main requirement is that you have SSH key authentication set up (so you don't have to enter a password every time).

Then just create an on-script that uses ssh to send the command:

ssh root@192.168.1.1 'ip rule add from 192.168.1.35 table vpn'

An off script would look like this:

ssh root@192.168.1.1 'ip rule del from 192.168.1.35 table vpn'

These examples are assuming your IP is 192.168.1.35 of course. Bear in mind that these commands append or remove rules from a routing table. So if you accidentally add the 'on' rule 3 times, you'll need to delete it 3 times as well.

Happy VPNing! Any helpful comments or corrections gratefully received.



3 comments:

  1. I will definitely try going for your technique dear but these days I am very busy and hardly get time to do anything extra but for my internet privacy I am using best vpn china and the important thing about this VPN is that, it’s not expensive at all.

    ReplyDelete
  2. It proved to be Very helpful to me and I am sure to all the commentators here! expressvpn free trial

    ReplyDelete
  3. Nice knowledge gaining article. This post is really the best on this valuable topic. top android vpn

    ReplyDelete