In my previous entry, I wrote about how awesome DD-WRT is, and how it had replaced a number of network devices allowing me to reduce the number of machines at home I had to administer. I finished the article by talking about how I’d set up a VPN tunnel to the office so multiple machines – namely, my Macbook Pro and my iMac – could access company resources at the same time.
But at the end, I mentioned that PPTP was not what I was using to connect myself back to my home network when I’m on the road. But why?
Two words: broadcast packets.
PPTP, by default, does not support the relaying of broadcast packets across the VPN link.* For Mac users, this means Bonjour/Rendezvous based services such as easily shared computers on a network are not accessible as they rely on network broadcasts to advertise their services.
PPTP can support broadcast packets with the help of a program called bcrelay. This program is actually installed on DD-WRT routers even, but does not work even though the DD-WRT web GUI claims that they can support relaying broadcast packets. To verify, you can drop to shell and try yourself:
root@Eywa:~# bcrelay bcrelay: pptpd was compiled without support for bcrelay, exiting. run configure --with-bcrelay, make, and install.
The version of pptpd that ships with v24sp2 of DD-WRT lacks bcrelay support. It’s important to note that this doesn’t mean the services are completely inaccessible. You can still reach them if you know IP addresses. Good for people with and understanding of networking, but not good for people like my wife and definitely not the “Mac way.”
So, what options are left, if no PPTP?
OpenVPN is a massively flexible (and therefore massively difficult to configure) open source VPN solution. DD-WRT ships with OpenVPN server available with support for broadcast packets, so that is what I decided to use.
A couple of notes before you begin. There are some tradeoffs to using OpenVPN. Perhaps the biggest is that it’s not natively supported on any operating system (unlike PPTP). That means on Windows or Mac, you’ll need a third-party client. And it’s not compatible at all with iPhones, iPods or iPads (unless they’re jailbroken). It is also much more difficult to configure that the relatively easy and reasonably well documented PPTP server setup. It was a worthwile tradeoff for me, but it may not be for you.
So, before you begin, you’ll need the following:
- You have already configured your router using DD-WRT and have the most recent release (as of this writing, v24-sp2), VPN version installed.
- The version number should be in the upper right corner of the web admin. If it says “std” or “vpn,” you’re in good shape. If it says “micro,” you probably don’t have the necessary tools.
- You possess some basic understanding of networking, and have the necessary settings to complete a VPN connection. If you’ve gotten as far as flashing with third-party firmware, you probably do.
- You understand that there is the possibility, albeit remote, that you could brick your router. I am not responsible for that, which is why I suggest you purchase an additional router to get all this set up on first before sacrificing your primary router.
- You’re not scared of the shell.
- You must sacrifice a goat to the networking Gods.
For reference, my network uses 192.168.1.x for addresses. This can cause problems as it’s incredibly common for LANs. You may want to change your addresses to something less common. Not that big a deal for me, though. I also have mine set up in bridged, as opposed to routed, mode. I thing this is smarter (and easier), but if you’re curious, the difference is explained here.
The first thing you need to do is install OpenVPN on your client machine. Even if you intend to use something different, you still need to install it so that you can generate all the certificates you’ll need. On a Mac, I find the best way to do this is with MacPorts.
toruk:~ peckrob$ sudo port install openvpn2
It’ll crank for awhile compiling and installing what it needs, so go get a snack. Then, once you have it installed, head over to /opt/local/share/doc/openvpn2/easy-rsa/2.0/ and run the following commands:
source ./vars ./clean-all ./build-ca ./build-key-server server ./build-key client1 ./build-dh
At each stage, it will ask you questions. It is important to provide consistent answers or you will get errors. Importantly, don’t add passwords to your certificates. Once you are finished, you will find all your keys in the keys/ directory.
Now, the fun part.
Head over to the keys directory (/opt/local/share/doc/openvpn2/easy-rsa/2.0/keys). There should be a bunch of files in there. In a browser, open up your router’s web admin, and go to Services -> VPN.
- Under OpenVPN Daemon, next to “Start OpenVPN Daemon,” select “Enable”
- “Start Type,” set to “WAN Up”
- CA Cert. Go back to your shell and “cat ca.crt”. Past everything between the “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” including those two lines. You must include the BEGIN and END for this to work on each one! (This was a major trip-up for me).
- “Public Client Cert,” go back to shell and “cat server.crt”. Past everything between the “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” as above.
- “Private Client Key,” go back to shell and “cat server.key.” You need everything between “—–BEGIN RSA PRIVATE KEY—–” and “—–END RSA PRIVATE KEY—–” as above.
- “DH PEM,” go back to shell and “cat dh1024.pem”. You need everything between “—–BEGIN DH PARAMETERS—–” and “—–END DH PARAMETERS—–” as above.
The important not above is to include the lines containing “—-whatever—-”. Not doing this cost me about 3 hours of messing around until I figured this out.
With that all complete, it’s now time for your server config. Here is my server config:
mode server proto tcp port 1194 dev tap0 server-bridge 192.168.1.1 255.255.255.0 192.168.1.201 192.168.1.210 # Gateway (VPN Server) Subnetmask Start-IP End-IP keepalive 10 120 daemon verb 6 client-to-client tls-server dh /tmp/openvpn/dh.pem ca /tmp/openvpn/ca.crt cert /tmp/openvpn/cert.pem key /tmp/openvpn/key.pem
The important things here are “dev tap0″, which creates an ethernet bridge and not a tunnel (as “dev tun0″ would do), and the “server-bridge” line. The documentation for that line is below it. The start IP and end IP specifies an IP range that VPN clients will receive addresses from.
With all this complete, press “Save” and “Apply Settings” at the bottom of the screen. Wait patiently. Then, in the web admin, go to Administration -> Commands. If you already have a Startup script, edit it, otherwise, add this to the commands window:
openvpn --mktun --dev tap0 brctl addif br0 tap0 ifconfig tap0 0.0.0.0 promisc up
Press “Save Startup.” Then, if you already have rules in “Firewall,” edit those, otherwise add:
iptables -I INPUT 2 -p tcp --dport 1194 -j ACCEPT
Press “Save Firewall.” Now, reboot your router. When it comes back up, you should have a running OpenVPN server. To check, go to Administration -> Commands, and type this into the command window:
ps | grep openvpn
If you see something that looks like:
11456 root 2720 S openvpn --config /tmp/openvpn/openvpn.conf --route-up 17606 root 932 S grep openvpn
Then it worked. Congratulations, you have a working OpenVPN instance. But how to connect to it?
If you use Mac, you really have two choices: Tunnelblick or Viscosity. Tunnelblick is a little on the ugly side and difficult to configure, but is free and open source. Viscosity is reasonably pretty to look at and easier to configure, but is a commercial product. I chose Viscosity, so that’s what I’m demonstrating here.
Once you have Viscosity downloaded and installed, go to Preferences and Connections, and add a connection. Enter a name and server address. Set the protocol to TCP and the device to tap.
Now, before you continue, go back to your shell. Go back to the /opt/local/share/doc/openvpn2/easy-rsa/2.0/keys directory, and copy those keys someplace in your home (~) folder that you’ll be able to access.
Back in Viscosity, go to the “Certificates” tab. You should see three lines labeled “CA,” “Cert,” and “Key.” For “CA,” select the “ca.crt” file you just moved. For “Cert,” select “client1.crt”. And, for “Key,” select “client1.key”.
Under the “Options” tab, disabled LZO compression. For some reason this was causing a problem for me, so I just disabled it.
Click “Save.” If all is right in the Universe and the goat you sacrificed to the Gods (you did do the goat sacrifice step, right?) was pleasing, you should now be able to connect back to your home network. Broadcast packets will work, and everything will be wonderful.