One of the disadvantages of working from places like the library and the train is that the wireless network connections aren’t exactly secure. For casual browsing, that’s not terribly important, but even for stuff like Facebook and GMail it would be nice to have a way of ensuring the connection is secure. Unfortunately, it’s not always possible or practical to use HTTPS connections for such things.
The obvious solution is a secure point-to-point connection to another machine on a wired network – in other words a VPN. The secured machine will act as an IP routing gateway, so that any insecure traffic that is intercepted will appear to be coming from that machine.
While I was at the library yesterday I created just such a setup using OpenVPN. As usual, it was more complicated to configure than I’d anticipated.
Setup steps. First the server:
1) Install openvpn on the server. Since my server is Fedora, this consists of installing the package via Yum.
$ sudo yum install openvpn
2) Create and install the security certificates and keys needed to authenticate the logins.
$ cd /usr/share/openvpn/easy-rsa/2.0
$ vi vars
(edit the last 5 lines, so that KEY_COUNTRY, KEY_PROVINCE, KEY_CTY, KEY_ORG and KEY_EMAIL are correct)
$ . ./vars
$ ./build-key-server server
$ ./build-key user1
$ ./build-key user2
… (do this for however many users you expect to have)
$ mkdir -p /etc/openvpn/keys
$ mv ca.crt server.crt server.key dh1024.pem /etc/openvpn/keys
3) Create the server configuration file and save in /etc/open/server.conf. Here’s what mine looks like:
# server’s IP address
# this is the port number assigned by IANA for OpenVPN
# use UDP – much better performance than TCP in this case
# use the tun device for a routed IP tunnel
# location of the server certificate
# location of the server key
# location of the Diffie-Hellman key parameter
# IP address and subnet mask of the VPN’s virtual network
server 10.8.0.0 255.255.255.0
# DHCP options to push to OpenVPN clients including domain and DNS servers (OpenDNS in this case)
push “dhcp-option DOMAIN local.mydomain.com”
push “dhcp-option DNS 18.104.22.168”
push “dhcp-option DNS 22.214.171.124”
push “redirect-gateway def1”
# allow direct client-to-client communication on the VPN
# allow each side to check every 10 seconds if the link is up
keepalive 10 120
# run openvpn as this user/group
# log to specified file
4) Enable IP gateway services on the server, using iptables. Note that you MUST make sure that iptables is not blocking the OpenVPN port on the internal VPN network. I spent over an hour trying to figure out why no traffic was ever being received by the server. I thought I’d disabled the firewall for the internal network – apparently not!
$ iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
$ echo 1 > /proc/sys/net/ipv4/ip_forward
5) Start the server. In Fedora nomenclature, the means:
$ /etc/init.d/openvpn start
Meanwhile on the client things are easier:
1) Securely copy over the client keys to the client. I used scp.
mkdir -p /etc/openvpn/keys
scp email@example.com:/usr/share/openvpn/easy-rsa/2.0/client1.* /etc/openvpn/keys/
scp firstname.lastname@example.org:/usr/share/openvpn/easy-rsa/2.0/ca.crt /etc/openvpn/keys/
2) Create the client configuration in /etc/openvpn/client.conf. Here’s mine:
remote 72.xx.xx.xx 1194 udp
3) Start the client. Since I’m on a Mac, I used the OpenVPN GUI Viscosity, which allows you to directly import your client.conf and keys.
P.S. So how do you know that it worked? Install WireShark. You’ll notice that almost all the traffic is now UDP traffic, and that there are no recognizable packets beyond an occasional DHCP request on the local interface.