OpenVPN - my new friend

I recently figured it would be a good idea to set up a VPN server, to be able to route internet traffic securely to a point of departure I trust as safe. I happen to control a server located in Germany, and so it was fairly easy to find a spot to set things up on. Figuring out exactly how to get things working was slightly more different though.

The problem

If you, like me, just google for info on how to install openvpn, you'll soon get confused on an important point: do you use TUN or TAP? Most of the guides I came across don't mention the distinction but just go on to use one (primarily TAP) of them. The reason this might be a concern to you is that one of them involves making low-level changes to your networking - and if your server is not in the next room, easily accessible, you might not want to mess to much with something that'll leave it inaccessible.

If you want to actually figure out what the difference is, read further on wikipedia. Briefly, both TUN and TAP are virtual network devices, but TAP is used with a network bridge while TUN is used with routing. What this means is that when you setup openvpn, with TAP you need to create a network bridge (which means changing network configuration and thus bringing the network down and up), while with TUN  you need to setup proper NAT routing (not messing with network configuration but with firewall rules - which can also end up bad, but is easier to plan for).

Given these considerations, I opted for TUN, which is what the rest of the post will be about. If you want to setup an openvpn server using TAP, there are plenty of guides out there.

The plan

My use case for openvpn is installing the server on a debian machine (running lenny) and connecting from a ubuntu machine (running 12.04). The following steps are required:

  1. Install the openvpn server
  2. Create certificate and keys
  3. Edit server config
  4. Setup routing
  5. Setup client
  6. Enjoy

Step 1 - install openvpn

apt-get install openvpn

Yeah. That was the easy part.

Step 2 - create certificate and keys

The next bit is creating the certificate and keys needed for authentication and encryption. Because openvpn is based on SSL and TLS you need certificates to get things working. This might sound like something very tedious to get working, but fortunately there are some easy to use scripts that come with the openvpn package. These are most likely situated in /usr/share/doc/openvpn/examples/easy-rsa/2.0/ - copy that folder to /etc/openvpn/easy-rsa and cd into it. Then edit the vars file and fill in details for:

KEY_SIZE=2048   # might as well set it high for good measure
CA_EXPIRE=3650  # 10 years so it doesn't suddenly run out
KEY_COUNTRY="Your country"
KEY_PROVINCE="Your province"
KEY_CITY="Your city"
KEY_ORG="Name of organization"
KEY_EMAIL="Relevant email address"

Entering the details in the above file means you do it once even if you have to redo the certificates. After doing that, go through the following steps:

# this exports the variables into the environment

# this makes sure you start from scratch (it removes all files from the ./key folder

# this builds the openvpns root certificate

# this builds the diffie-hellman parameter file needed

# this builds the specific certificate the server uses
./build-key-server server

# this builds a certificate set for a client
./build-key client

Additionally, you can also go through the extra step of creating an extra key for tls authentication. According to the openvpn documentation, this adds an extra signature to packets, giving extra protection. Not all clients support it though, so check first if you can use it. You generate the secret key this way:

openvpn --genkey --secret ta.key

After this, all generated files are located in ./keys/. On the server end, you need the following files:

  • ca.crt
  • server.crt
  • server.key
  • dh2048.pem
  • ta.key (if you decided to use it)

On the client end you need these files:

  • ca.crt
  • client.crt
  • client.key
  • ta.key (if you decided to use it)

Step 3 - server configuration

Next, you need to edit your openvpn server config. The config is located at /etc/openvpn/server.conf. You should make sure the following values are set as follows (leave any others as default):

port 1194     # port openvpn will be listening on
proto udp     # protocol that will be used
dev tun       # network device type used
ca /etc/openvpn/easy-rsa/keys/ca.crt        # root certificate used for signing certificates
cert /etc/openvpn/easy-rsa/keys/server.crt  # servers certificate for authentication
key /etc/openvpn/easy-rsa/keys/server.key   # servers private key for certificate
dh /etc/openvpn/easy-rsa/keys/dh2048.pem    # diffie-hellman vars for establishing connection
server               # subnet that openvpn will assigning clients ip's from
ifconfig-pool-persist ipp.txt               # file to record persistent ip's in, so clients get the same ip
push "redirect-gateway def1 bypass-dhcp"    # directive to make clients redirect traffic through vpn
push "dhcp-option DNS"              # directive to make clients use googles dns
tls-auth /etc/openvpn/easy-rsa/ta.key 0     # if you decided to use tls.-auth
user nobody        # user the openvpn daemon runs as
group nogroup      # group the openvpn daemon runs as

After editing the server.conf, time to restart the openvpn daemon. Run /etc/init.d/openvpn restart, and the openvpn daemon should come up, creating a tun0 network device in the proper subnet - check with ifconfig.

Step 4 - setup routing

When you're through setting up the VPN server you need some firewall rules to make sure packets go the proper place. Using iptables, here are the commands that should get the routing part setup properly:

# use IP masquerading
iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

# accept all packets in the forward chain from device tun0 to device eth0
iptables -t filter -A FORWARD -i tun0 -o eth0 -j ACCEPT

# forward packages for related and established connections
iptables -t filter -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

After adding these rules to iptables, it's a good idea to save them to a script with iptables-save - you can then later apply them again (if needed) with iptables-apply. And obviously you can make sure they're reloaded automatically on a server reboot.

Other than changing iptables rules, you also need to make sure that the kernel allows IP forwarding. This is done with

sysctl -w net.ipv4.ip_forward=1

To make sure the change sticks, edit /etc/sysctl.conf (or add a file with the same content to /etc/sysctl.d/) and add:

net.ipv4.ip_forward = 1

With these changes, the server should happily route incoming VPN connections to the internet.

Step 5 - setup client

Finally, you need to setup your client to access the server. If using Ubuntu (or any of the variants, presumably including a desktop version of Debian), you can let NetworkManager abstract some of the concerns away. Right click the network icon in the system tray, select VPN connections and click on Configure VPN - then click on Add VPN. Choose OpenVPN. Note that in later versions of Ubuntu, you might need to install network-manager-openvpn first, to see the OpenVPN option:

sudo apt-get install network-manager-openvpn network-manager-openvpn-gnome openvpn

With these installed, you should be able to choose the proper VPN server to connect to.

Moving on, you should fill in a connection name (so you can remember what it is you're connecting to), the Gateway (use either the domain name you connect to or an IP address of the VPN server), type of connection (in our case Certificates) and then choose the path for the two certificates and the private key generated in step 2. User certificate should be client.crt, CA certificate should be ca.crt and private key should be client.key.

Next, click on the Advanced button, select the TLS Authentication tab, and mark the Use additional TLS authentication checkbox. Select the ta.key and select 1 under key direction. This should be all the configuration needed for the client - save the connection info and try connecting.

Step 6 - enjoy

If everything went according to plan, you should now be able to browse the net through your VPN connection. Test the connection using a browser and - you should see the IP address of your server.