Some readers of this blog may recall that several months ago I had wished for a Simple VPN device – back then I had written:
There is another type of software that ought to be moved into its own box, and that is Virtual Private Network (VPN) client and server software. Yes, I’m aware of OpenVPN, and I tried to find setup instructions that someone like me could understand, but to no avail – it looks like you need a degree in computer networking to understand how to set up this type of software. And yet, built into hardware devices, it could be immensely useful in certain circumstances. Let’s consider the following diagram:
In this particular case we have a SIP-based VoIP adapter at a remote location. Anyone who has worked with Asterisk behind the wrong kind of firewall knows the issues involved with using SIP and not having things set up just so (one-way audio, anyone)? But also, we may for whatever reason want that “remote” VoiP adapter to appear as if it were on the local network (maybe we have an ISP playing games with SIP packets?). So we plug the VoIP adapter into our “VPN Client-Side Device” and on the other end, we have a companion “VPN Server-Side Device” which in this case makes two connections to the router – one to receive the “tunneled” data and the second to send the unencrypted data back onto the local network. The green arrows represent the “tunnel”, the orange arrows show where the data from the VoIP adapter enters and exits the tunnel. Please note this is entirely a wired connection, we aren’t using wireless anywhere here. Also note that as far as the VoIP adapter is concerned, the only network it can “see” is the one at the other end of the tunnel – under no circumstances can it access the Internet other than by going through the tunnel.
I show this using a VoIP adapter, but I’m sure that people could think of a lot of other ways this could be used, and a lot of other devices that could be connected to the client end.
Now some will probably argue that it is inefficient to have a device that does nothing but provide the tunnel. But that’s the point – almost anyone could set this up. If you send the client-side device to your grandmother, she can set it up (well, maybe that’s pushing it a bit, but you get my point). People who would never touch a Linux box or a server could use this.
I want to tell you, when I wrote that I had no idea just how difficult it would be to actually get VPN tunneling working using OpenVPN. The problem isn’t that it doesn’t work — actually, it works quite well — the problem is that it’s a real bear to set up, unless you have someone who knows what they are doing walk you through it. Unfortunately, you may not haves someone who knows what they are doing to help you, so you’re stuck with me (unless you can find a better page on the subject – if such exists, please let us know in a comment).
The real issue is that you have to learn so many new things at once to make this work. So, my attempt here is going to be to try and give you a “cookbook”, with plenty of screenshots so you can see how things actually look when everything is configured. I’m actually also going to approach this in a slightly backward manner, showing you how to configure the client first, then the server. My theory is that you will think that configuring the client is so simple that configuring the server can’t be much harder, and you’ll get sucked into the project before you realize what you’ve gotten yourself into! 🙂
By the way, what we are doing here doesn’t look exactly like the diagram above – instead it looks more like this (note that the “Primary Router” on the client side can be omitted if you don’t need any UN-tunneled connections, or if the DSL or Cable modem has a built-in router):
For our client, we need something that you can plug your desired device into. You may have a laptop, and you want to communicate securely with a home office. You may have a VoIP adapter, and you want to make secure calls to a remote Asterisk server. While you can run a software client on the Laptop, when you have a hardware device like a VoIP adapter your choices become more limited. The solution is to purchase a router that is capable of being re-flashed with custom firmware. In this case we are going to use the Tomato firmware, and in particular, a version of the firmware designed to support OpenVPN as either a client or a server. Here we’re going to use it as a client. The idea will be that ANY device plugged into the router will automatically use the VPN tunnel, and if for some reason the tunnel isn’t available then the connected device will not be able to communicate, therefore there’s little chance that an insecure communication can take place.
Some readers will already have a router capable of running Tomato firmware, and some will not. The main Tomato Firmware page shows which routers are supported. If you do not already have one of these and plan to buy one, I recommend that you consider the Asus WL-520GU. I know that the main Tomato firmware page says there’s no USB support for that model, but that’s not necessary for what we’re going to do, and it’s not even true if you use the recommended firmware build. The reason I suggest using the WL-520GU is because I’m told that although it’s not totally impossible to “brick” the router by doing a bad flash, if you do make a mistake, your chances of being able to recover (so that the router isn’t consigned to being an expensive paperweight) are far better than with some other models.
I should mention here that I inherited this project from someone else who couldn’t get it to work. I had made the mistake of casually suggesting they get the Asus router if they wanted to attempt this, only to find them on my doorstep with router in hand. So again, I’m not saying this will be easy, and the one thing I will not tell you how to do is how to get the Tomato firmware onto your router. The reason is that if I give you instructions and leave out a step and you brick your router, you will be mad at me. Better you find someone else’s instructions, and if they’ve left out a step, you can be mad at them. I will mention that, at least in the case of the Asus router I had here, it was a two-step process – I used the Asus Firmware Restoration Utility to first install DD-WRT (using these instructions) and then used DD-WRT’s web interface (Administration -> Firmware Upgrade) to install Tomato (I’m skipping a whole tale of woe and grief that transpired between those two events). Basically I followed the instructions at An Easy Guide to Installing Tomato on the Asus 520gu, but I’m not telling you to do that — it’s up to you which instructions you wish to follow.
Why Tomato instead of DD-WRT? Because Tomato works, that’s why. But if you want to try getting it working on DD-WRT, go ahead, knock yourself silly (only one tip for you, from a tweet by @pista01 on Twitter — if you keep getting TLS errors, make sure your NTP client is set up). If you succeed, great for you. If you don’t, you’re welcome to come back here and continue on.
But don’t just grab the first build of the Tomato firmware that you see. You need one that includes VPN support. There are two versions I would highly recommend — if you have taken my advice and acquired an Asus WL-520GU (or similar model with built-in USB port), then I recommend teddy bear’s build because it enables the “missing” USB support, and also includes the VPN support from SgtPepperKSU’s build — which is the one you should get if you DON’T have the Asus WL-520GU, but instead have some other compatible router (EDIT: Advanced users may also wish to check out thor2002ro’s build, which offers both the VPN and USB support from the aforementioned builds, plus support for SDHC, SNMP, and perhaps other additional features. I haven’t tested that one at all, and note that recent versions probably won’t work with many router models due to memory requirements, so unless you really need one of the features in that version and know that your router supports it, I’d stick with one of the other versions). Make sure you read up on the chosen build and be sure you get the correct firmware version. For the Asus I used the binary from inside the tomato-1.25-ND-USB-8632-vpn3.3.rar archive, but since then a newer version has been released (tomato-1.25-ND-USB-8634-vpn3.4.rar was released in August, 2009), or you may prefer a different version.
In this series you will see several screenshots. I’m using the custom “Tomato USB” theme, so the colors and “look” may be a bit different than what you see, but other than that everything’s in the same place as with the default theme. Later (after taking the screenshots) I replaced the tomato.png file from the theme with the one you see at the right, which I happen to like a little bit better.
Two other caveats: Although this router has wireless capability, for this application we aren’t going to use it — it’s going to be used on a wired network only. That said, once you get it set up and working, feel free to experiment with the wireless capabilities if you like — just be aware that if something on the wireless side of things doesn’t work, I really can’t assist you. And also, we’re assuming that everything plugged into this router will be using the VPN tunnel full time, which implies that this router might (perhaps in a majority of cases) be plugged into another router, so that some other devices can access the local Internet connection, while the devices plugged into this router are limited to going through the tunnel. Note that if this router is plugged into another router, it would be preferable (but not absolutely essential) if it were in that router’s DMZ, so that you don’t have double NAT (Network Address Translation) taking place.
And now, a word about OpenVPN. OpenVPN supports two different modes of operation — TAP and TUN. In this case, we are using TUN. We MIGHT explore TAP at a later time, but TUN is easier to set up, and ANYTHING that can be done to simplify this process is worthwhile. The main difference, from the users point of view, is that using TUN the two ends of the tunnel occupy two different portions of the local address range. In this case, on our “home” LAN, the addresses are in the 192.168.0.x range and are assigned by the main router. At the client end of the tunnel, the router running the Tomato firmware will hand out addresses in the 192.168.5.x range. Neither router steps on the other’s toes, so to speak, when handing out addresses. And there is one other difference — although shared directories can be accessed across the network, Windows/Samba shares cannot be “seen” on opposite ends of the tunnel. If you know they are there and know the IP address and share name of the hosting device, you can still access them, but the mechanism that advertises shares doesn’t cross the tunnel.
With TAP, on the other hand, the router at the primary location hands out IP addresses in the same local address range to devices on both sides of the tunnel, and also (in theory, anyway) shares will be “advertised” across the tunnel. Sound like what you’d want, right? Except that when we tried to set it up on the server side, somehow we managed to bring down the entire network – it basically acted like a denial-of-service attack on the entire LAN, and the problem stopped the moment we went back to using TUN. After you’ve messed with this stuff long enough, something like that can leave a rather bitter taste in your mouth, so we decided to stick with what worked. In our particular application, seeing shares across the LAN would not be essential. Even if you eventually want to try using TAP, I suggest setting it up using TUN first, then when you have achieved that you can cross your fingers and try switching the mode to TUN at both ends. I doubt it will work easily for you, but experimentation is certainly welcome.
If you want to know more about TUN/TAP and other OpenVPN options, you might want to get the book Beginning OpenVPN 2.0.9 (Amazon affiliate link) by Markus Feilner and Norbert Graf — see my recent mini-review of this book (links edited February, 2010 to reflect updated and expanded edition of the book).
So with the preliminaries out of the way, let’s get to the client screenshots…
This first shot shows the header, sidebar, and Save/Cancel buttons. Since the settings are probably a bit hard to read, we’ll zoom in on the pertinent part:
The main thing to keep in mind here is that the subnet you select must not conflict with address assignments on the primary network at the server. Next, on the Router Identification page, enter a Hostname to identify the router:
One thing I have read in several places is that it’s important for the time to be set accurately at the client. For your choice of time servers there are several presets, but if you use Custom you can specify one or more of your own as the first choice(s), if you have a machine on your network that acts as an NTP server:
At this point you should probably go to the Administration | Admin Access page and set things up there to your liking. Remember that anything you make accessible on the router’s local LAN will also be accessible on the other side of your tunnel using the same security methods, so be careful.
Now to what we came for… setting up the VPN client. Click on VPN Tunneling and then on Client. I’ll say that one more time – you MUST click on Client. It’s far too easy to skip that step and accidentally be trying to configure a server! Then you should be at the Client 1, Basic tab:
Of course, the button at the bottom of the page will sat “Start Now” instead of “Stop Now” – I took these screenshots through the tunnel, so I couldn’t very well stop it to get that little detail right! After setting that up you want to click on the Advanced tab:
Note that the connection retry value is -1 (which means infinite retries) and there are two added lines in the custom configuration section:
keepalive 10 120
In case the connection to the server or the Internet goes down for a time, those settings should cause the client to keep attempting to re-establish the connection to the server. The float command is useful if your client is at a location where the ISP might change the IP address without advance notice — it is supposed to allow the VPN connection to survive an IP address change. You can omit float if your client is at a fixed IP address that is not subject to change.
And then the Keys tab – just take a look now, when we move on to the server I’ll explain how these are filled in:
There is one more thing that needs to be done (besides adding the keys) for our tunnel on the client side. Go to Administration | Scripts and click on the WAN Up tab. Enter the following two lines into the text box:
route del -net 0.0.0.0
route add -host `nvram get vpn_client1_addr` gw `nvram get wan_gateway`
The second line may wrap on your display due to length. You may want to copy and paste those lines so you get them right, but if you must type them, note that the ` characters are actually backticks – the small apostrophe-like character on the key to the left of the “1” key (the number 1) near the top left corner of most keyboards (well, in my part of the world, anyway). Then click on the Save button way down at the bottom of the page. If you fail to do this and your tunnel ever goes down (server dies or is inaccessible, etc.) there is a possibility that traffic that should go through the tunnel will use the local Internet connection instead. These two lines will keep that from happening. When you are done it should look like this:
Just a note for future reference: You can optionally add an additional line here to allow you to get to something “upstream” of the network on the WAN side of the router. For example, let’s say you have configured the server to allow you to connect to devices on both the LAN subnet (192.168.5.x in our example here) and also devices connected to the primary router, in other words, on the WAN side of the router running the Tomato firmware (which were in the 192.168.1.x range on our example setup). But let’s suppose that upstream of that, you have a cable modem at 192.168.100.1 at the client location that you’d also like to be able to access. As long as you don’t have a conflicting address elsewhere in your network, you could add a line such as this in your WAN Up script:
route add -net 192.168.100.0 netmask 255.255.255.0 gw `nvram get wan_gateway`
… which would allow access to anything in the range of 192.168.100.0 through 192.168.100.255. If you want to be more specific, you can narrow it down to an exact address:
route add -host 192.168.100.1 gw `nvram get wan_gateway`
We’ll cover what else has to be done to enable this type of additional routing at the server end in the upcoming installments, but the above is what has to be done at the client-side router that is running the Tomato firmware. Note that you do not normally have to a a line such as this to get to devices on the same subnets as the LAN or WAN ports of the router, but just for anything upstream of the network that the WAN port of the router is connected to. If you don’t understand why you might want to add this type of additional routing now, just ignore this information for the time being, but make sure you do add the first two lines I mentioned above.
Once your tunnel is operational, you should go to the Advanced | Routing page and look at the Current Routing Table. Your addresses will differ (this was a test setup; you probably will see a wider range of addresses) but the main thing you want to make sure is that there is never an entry of default (or 0.0.0.0) in the destination column that goes to any interface other than a tunnel (tun11 in this illustration) — you should never see that whether the tunnel is enabled or disabled. If you do, then something’s likely wrong with the two lines you entered above (under the WAN Up tab):
So, that’s the basic client setup. Wasn’t too difficult, right? Ah, but just wait until we get going on the server — hopefully I can make it easy enough that you won’t have about three weeks worth of sleepless nights, when you occasionally mutter under your breath things like “Why? Why?? Why??? WHY won’t this damn thing work!”, and other things I’d rather not put on the Internet! But before I can write the next part, I REALLY need to catch some ZZZ’s, so the server will have to wait for part 2.