Sunday, January 18, 2009

OpenVPN

I recently set up OpenVPN at home. It’s a pilot for someone who runs a business, and needs remote access to a samba file server located at the office.

There are several pieces to the puzzle, so I’ll list them all below.

Ubuntu: The first step was to buy a used Athlon 64 desktop system with 1.5 GB of memory and upgrade it with a 500 GB Seagate Barracuda hard disk. I installed 64-bit Ubuntu 8.10 on it, desktop edition. Using the Synaptic package manager I installed Samba and OpenVPN from Ubuntu repositories. Simple enough. I also threw in openssh-server for ease of administration and file transfer, and proprietary graphics drivers for getting a decent display.

Port forwarding: On my Belkin router I enabled forwarding of port 1194 (default port for OpenVPN) to my Ubuntu machine. However the IP address of my Ubuntu machine was a DHCP address assigned by the router, so that posed a problem, solved by the next piece of the puzzle.

Static IP: I had to set the Ubuntu machine to a static IP on my home network to enable port forwarding. (For some absurd reason this worked on one Ubuntu machine but not on another… I’m still investigating why.)

DynDNS: I had to access this system from outside my home network, and I have a typical DSL connection with a dynamic IP address. So I signed up for a free DynDNS.com account. My Belkin wireless router has built-in support for DynDNS, and I decided to use it instead of a standalone client.

OpenVPN Client: On a laptop I installed the OpenVPN client. Since the Ubuntu repository had given me a release candidate version of 2.1, I chose to install the latest 2.1 release candidate rather than the stable 2.0.9 version. The 2.1 series comes with the OpenVPN GUI integrated, which is a big plus.

Key Generation: I read the steps on the OpenVPN HOWTO and generated the required certificates and keys on the Ubuntu server. Then I copied over the required keys and certificates to the client laptop.

Configuration: From the HOWTO, creating a config file for a tun configuration proved easy enough for both client and server, with lzo compression enabled. I did not need bridging since Samba was on running the same server as OpenVPN.

So did it all work together? Of course not... read on!

First, my router's DynDNS update didn’t work as expected. When I had restarted my router and DSL modem for some reason, the DynDNS client on the router recorded a bogus non-routable IP address before the DSL modem could get an IP address from upstream. And then the DynDNS client on the router promptly proceeded to update my DNS record globally with this bogus non-routable address. What’s worse, even after I corrected the situation with a manual update, my router refused to give up its earlier cached DNS lookup that pointed to the bogus IP. As a result, I couldn’t refer to my VPN server by name at all.

The alternative I considered was a Perl program called ddclient. It worked for a first update but did not run successfully in daemon mode... haven't yet figured out why.

The second issue came up when I had connected successfully and was in the testing phase. I was able to see my Samba share from my client, but my connection was unstable. I decided to switch from UDP to TCP, and then it started to work reliably. To make this switch, I had to edit the server config file and restart the service, edit the client config file, and change the port forwarding setting in the router.

How well does it perform?

Going strictly through my own internal wiring, I was able to push or pull about 2 to 3 Mbps from my laptop to my Samba server, each way. The laptop was connected using wireless 802.11g. From a friend's home, I got about 300 to 350 Kbps for reads; I didn't test writes.

I suppose setting up an OpenSSH server and using SSH tunneling would have worked just as well, with the addition of a virtual NIC. But this was cooler. :)