Saturday, April 04, 2009

Setting up OpenVPN with dd-wrt for unexpected road trips you don't want to miss

Somehow the words "web worker" and "vacation" don't seem to mix well together.

Web Working on Road Trips

I don't have any solid plans for the holy week but I certainly don't want to miss trips to Tagaytay, Bulacan or the nearby Ocean Park if anybody decides they want to go on a road trip.

Fortunately, finding an internet connection is easier now than ever before. Between Smart Bro, Globe Tatto, commercial and free Wi-Fi services, you're pretty much covered, specially if you won't be wandering too far away from Metro Manila.

You've got your trusty laptop and internet access is not a problem, so what's keeping you from going on that road trip ?

For me, it's secure access to my files and the virtual machines on my home network.

The internet may be more accessible here in the Philippines but it isn't necessarily more secure. In fact the data packets, be it from WiFi, 3G or HSDPA, are transmitted over the air. Anyone, with enough knowhow, the proper hardware and software could possibly capture the data as it is being transmitted.

What's a mobile web worker to do ? The solution, setting up a Virtual Private Network (VPN) .

Is a VPN Overkill ?

I know, it sounds overkill but "VPN" should not connote buying expensive Cisco hardware and VPN software. It's now possible to set up a VPN on your home network with relatively inexpensive hardware like the Linksys WRT54G router (which I happen to own) and free software like dd-wrt.

The first thing to do of course is to acquire a router that supports dd-wrt. This use to be easy as the Linksys WRT54G was the only router that was supported. Today, you have a lot more options from the likes of Buffalo, Asus and Netgear.

I won't discuss how to setup dd-wrt on your router as it's out of the scope of this article. You can find instructions from the dd-wrt wiki and do a search on google to read about how other people have fared in their attempts at installation. Note though that the process is not for the feint of heart. It's gotten easier with each release but there is still a possibility that you will "brick" (the term used to describe a router that has been rendered useless) your router.

dd-wrt has many builds. Make sure to install the vpn build.

What you need for your VPN

In addition to :
  • A supported router, I used a Linksys WRT54G v2.2 router.
  • dd-wrt vpn build, I installed v24-sp1
here are the other prerequisites for setting up the VPN :
  • A desktop or laptop computer with Linux , my desktop is running OpenSUSE v11
  • OpenVPN on the linux desktop, I installed this using the Yast software manager
  • A text editor like Kate or vi
Let me stress that this worked for me using the above hardware and software. If you are using a different router and/or a different version of dd-wrt, you might want to do some more research before attempting this.

You've been warned !!

The computer with OpenVPN is where we generate the certificate files needed to setup the OpenVPN server on dd-wrt. We will not be setting up OpenVPN on this computer.

It is also possible to use windows with the OpenVPN GUI installed instead of a linux desktop but I won't discuss how to do it here.

Step by Step Set Up

Let's get to it.

1. On your linux desktop, open a terminal and become root by using su.
su -
2. Go to /usr/share/openvpn/easy-rsa/2.0
cd /usr/share/openvpn/easy-rsa/2.0
3. Execute the following commands in the correct order
# sets some environment variables to make the succeeding scripts work
source vars

# cleans up any previously created keys if any

# create a certificate
# you will be asked to enter some information
# remember what you entered as you will need to use the same information
# to generate the server key

# create a server key
./build-key-server server

# create the Diffie-Hellman parameters needed by the server
4. The commands above will create a keys folder inside the current folder you are in with the files you need for the next step. Open the files using your chosen text editor.

5. Open a web browser and enter the IP address of your router. If you did not change the default, the IP should be This opens to the web administration interface for dd-wrt

6. Click Services, then under OpenVPN daemon click the "Enable" radio button. This should reveal additional textareas where you need to paste the contents of the files from the keys folder.
Public Server Cert > ca.crt

# note that you only need the portion of ca.crt that starts with
# and ends with
# ----- END CERTIFICATE -----.

Certificate Revoke List (CRL) > (blank)
Public Client Cert > server.crt
Private Client Key > server.key
DH PEM > dh1024.pem
OpenVPN Config > (see 7 below)
OpenVPN TLS Auth > (blank)
7. For the OpenVPN Config textarea, you will need to decide what IP address range you want to use for the private routing network that will be used by OpenVPN. In the sample configuration below, I decided to use as the private routing network. The push parameter should have the IP and subnet of your local area network.
push "route"
dev tun0
proto udp
keepalive 10 120
dh /tmp/openvpn/dh.pem
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem

8. Once the textareas have been filled up, click "Apply Settings" and just to be sure, click "Reboot Router" to reboot the router.

Hopefully, the OpenVPN server on your router should be up and running. To verify, use ssh to log into your router and run
ps | grep openvpn
You should see an openvpn process running. If you don't, then you'll need to take the following steps to turn on logging and debug the problem.

Troubleshooting with Logs

To turn on logging, click the Services tab and click the "Enable" radio button under System Log. Leave "Remote Server" blank. Then add verb 5 to your OpenVPN config textarea. Click "Apply Settings". Then log into your router via ssh and execute.
tail -f /var/log/message
Connecting Clients

Now that you have your server up and running. The next thing we want to do is to setup a client computer to connect to the OpenVPN server. If you're on windows, you can download the OpenVPN GUI.

For Linux users, you can use the openvpn applet for the NetworkManager which comes installed by default on most Linux distributions.

Before anything else, you need to create the certificates that your client computers (in this case my laptop) will use to connect to the server.

Login to your linux desktop and go back to /usr/share/openvpn/easy-rsa/2.0, then execute
./build-key client1
where client1 is the name of the client computer you want to connect to. You can also leave it as client1 if you like.

The above will generate 3 files in the keys folder, a client1.crt, client1.csr and client1.key. You need to copy client1.crt and client1.key to the client computer that wants to connect to the server. You also need to copy ca.crt from the keys folder to the client computer.

Click on the NetworkManager applet icon on your linux desktop, then click "VPN Connections" -> "Configure VPN".

Click on the VPN tab, then click "Add", choose "OpenVPN" from the connection type drop down.

In the succeeding form, enter the following information :
Connection name : (enter whatever you like here)
Gateway : (for now enter the IP address of your router)
Type: Certificates (TLS)
User Certificate : point this to the location of client1.crt on the client computer
CA Certificate : point this to the ca.crt file
Private Key: point this to client1.key
You should now be able to use the NetworkManger to connect to your router's OpenVPN server.
We have tested so far that the VPN server works but for this to be actually useful, the OpenVPN server should be able to accept connections from the internet.

Dynamic DNS and the Router Firewall

In quickest way to do this is to sign up to a free dyanmic DNS service.

dd-wrt supports several free dynamic dns services here is a comprehensive how to from the dd-wrt wiki.

Once you have DDNS set up, you need to open port 1194 on the router's firewall in order to accept connections from the internet.

Go back to the dd-wrt web interface, click the Administration tab, then click Commands. Enter the following code and click the "Save Firewall" button.
# Replace 1194 with your OpenVPN port number:
iptables -I INPUT 1 -p tcp --dport 1194 -j ACCEPT
iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT

# change to the private routing network you chose earlier
iptables -I FORWARD 1 --source -j ACCEPT

You may want to click "Reboot Router" to reboot the router and make sure that openvpn is working with the new start up firewall script.

Connecting for real

The next step is to go on a road trip, find free WiFI and connect to the OpenVPN server.

Have a blessed holy week and advanced happy easter to everyone.

References :