Tunnel Vision
Surely someone out there has wondered if they could set up a VPN server on a router running DD-WRT. And surely they, and other people, have wondered if they could use that same VPN server with Ubuntu.
Well, I’m here to tell them that they can. And not only that, I’ll also tell them how, because that’s just the kind of guy I am!
Let’s start by configuring the router.
First off, you may already have your DD-WRT router, but, sadly, the default build does not have VPN. So grab a VPN build, flash your router and come back here. apparently, you don’t need a specific version of DD-WRT—they all have the PPTP daemon, as far as I can tell.
Once you’ve got your VPN DD-WRT running, it’s time to enable the VPN server. This is child’s play. Navigate to Administration, then Services and select Enable under PPTP. Once you’ve enabled it, set the server IP to the LAN IP of the router (192.168.1.1 by default). Then choose a client IP range; pick something you’re not already using, e.g. 192.168.1.250-254. And finally, enter a bunch of username/password combinations, using the following format:
username1 * password1 *
username2 * password2 *
Yes, the asterisks need to be there. Now save your changes and your VPN server will be running.
Now, it’s time to configure Ubuntu. I use Kubuntu, but since this process does not require anything graphical, it’ll work on anything Ubuntu. Consequently, you’ll need to fire up a console and become root or use sudo.
To enable PPTP support, you’ll need the pptp-linux package. So use apt-get to install it:
# apt-get install pptp-linux
You now have support for PPTP, but, obviously, some configuration is in order. All the files related to the package are in /etc/ppp.
First off, you’ll need to choose a profile name for the VPN connection; I’ll assume you picked home, but it can be anything you like. Now, edit or create the file /etc/ppp/chap-secrets, adding the following line:
username1 home password1 *
Obviously, username1 and password1 are the credentials you entered on your router. Again, the asterisk is there for a reason.
Next, it’s time to specify some more information about the profile. This is stored in the /etc/ppp/peers directory. So go ahead and create the file /etc/ppp/peers/home with the following contents:
remotename home
linkname home
ipparam home
pty "pptp hostname --nolaunchpppd"
name username1
usepeerdns
require-mppe
mppe-stateful
persist
noauth
file /etc/ppp/options.pptp
Obviously, you should again replace home and username1 with the values you chose. Also, replace hostname with the address of your router; if you don’t have a static IP, you’ll probably appreciate services like No-IP.com, which, incidentally, DD-WRT can automatically notify for you.
If you’d like to know the meaning of all the stuff in the file you just created, consult man pppd.
You should be all set now. If you issue the command
# pon home
the VPN tunnel will be established and you will have access to your router’s LAN—unless you’re firewalled, which is highly likely. If you run ifconfig, you should see a new ppp interface for the tunnel.
Unsurprisingly, to disable the tunnel, you’d issue
# poff home
Now, while the tunnel provides you with encrypted access to your home LAN, all other traffic will still be routed through the default gateway—type route to see some proof. Thus, if you want to tunnel everything through your router, so you can keep people from sniffing out your passwords, IM conversations, URLs you visit and whatnot, you’ll need to mess with your routing table a bit.
Routing isn’t as hard as it may seem. You just need to think about it for a second. Obviously, to route everything through your VPN tunnel, you’ll need to make your router the default gateway. But if you do that, your VPN tunnel will stop working, since the connection to your router uses the default gateway of whatever location you’re at. Thus, you’ll need to set up a separate route to your router first. Let’s say your router’s remote IP (as in /etc/ppp/peers/home) is 123.45.67.89 and your current default gateway is 10.0.0.1, then you’d enter
# route add 123.45.67.89 gw 10.0.0.1
Now you can add the router’s LAN IP (e.g. 192.168.1.1) as a default gateway. It’ll be reachable thanks to the route that was added when the tunnel was set up.
# route add default gw 192.168.1.1
And finally, the two routes you just added make the old default gateway obsolete, so you can now safely remove it:
# route del default gw 10.0.0.1
I think you should be able to do this routing magic by putting a script in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d, but I haven’d tried yet. This would also make restoring the previous routing table easier.
Update: You can easily achieve this by putting a script in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d. Everything is documented in /etc/ppp/ip-up and ip-down. Here’s my up script …
#!/bin/bash
# Ignore these two lines.
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
test -z "$PPP_IPPARAM" && exit 0
# The LAN IP of your router.
REMOTE_GATEWAY=10.0.0.1
# The Internet hostname of your router.
REMOTE_HOSTNAME=babylon.no-ip.biz
# You might still have to tweak stuff from this point.
# Set this directly if your router has a static IP.
REMOTE_IP=`host $REMOTE_HOSTNAME | awk '{print $4}'`
# Note: If you use multiple gateways, this will fail.
# In this case, set the IP directly or whatever.
LOCAL_GATEWAY=`route -n | awk '/UG/{print $2}'`
# You shouldn't have to touch anything from this point.
test "$LOCAL_GATEWAY" = "$REMOTE_GATEWAY" && exit 0
FILE="/etc/ppp/routing.$PPP_IPPARAM"
echo "$REMOTE_IP $REMOTE_GATEWAY $LOCAL_GATEWAY" >"$FILE"
route add $REMOTE_IP gw $LOCAL_GATEWAY
route add default gw $REMOTE_GATEWAY
route del default gw $LOCAL_GATEWAY
… and my down script, which simply undoes all the work …
#!/bin/bash
# No configuration required.
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
test -z "$PPP_IPPARAM" && exit 0
FILE="/etc/ppp/routing.$PPP_IPPARAM"
test -r "$FILE" || exit 0
read REMOTE_IP REMOTE_GATEWAY LOCAL_GATEWAY <"$FILE"
route add default gw $LOCAL_GATEWAY
route del default gw $REMOTE_GATEWAY
route del $REMOTE_IP gw $LOCAL_GATEWAY
rm -f "$FILE"
So, if all this worked, your traffic should now be entirely routed through the ppp interface. You can use Wireshark to verify that your outgoing traffic is all PPP and GRE. If not, well, try again. Good luck!