Someone I know is going to a certain country with heavily restricted internet access (tomorrow, actually). They asked me if there was any way they could access sites that might be blocked by the government (like Facebook). I figured if we set up both a VPN and SSH tunneling, then one of those services is likely to work while they're over there. By using a VPN, you can send all your internet traffic out through a server in America, thus circumventing any blocking they have in place where you're connecting.

The resulting experience was... mostly frustrating. I've set up a couple OpenVPN servers before and I always manage to screw something up. Usually it's easy to fix, but if you drop your network connection to a VM in the cloud means you're locked out and have to fix things by spinning up a new instance, mounting the old instance's hard disk, fixing things, then putting the volume back on the original instance. The web control panel for EC2 is okay, but it isn't the easiest to navigate on an eeepc screen. The sad part is that took me two times of doing this process before I created an at job that would restore the networking config file if I somehow managed to screw it up again (which I did, one last time).

Anyway, I was able to get it working and as much for my benefit as yours wanted to post this quick how-to. Next time I can refer back to this instead of wondering whether I want to set it up using bridging or routing and hopefully save myself an hour or two of frustration...

Setting up the VM

I figured this was a great excuse to try out Amazon's EC2 since I had never actually used it before and they basically give you the first year free. I used Ubuntu Server because I'm familiar with it and they had a version of it on EC2 that you could just clone. The only special instructions here are allowing inbound UDP port 1194 through the firewall (on the security group configuration page). This isn't an EC2 how-to, so I'll skip the rest of the configuration stuff because it isn't really relevant.

Installing and configuring OpenVPN

Ubuntu has packages in their repositories, so a quick sudo apt-get install openvpn was all that was needed to install it. Of course, it's also available from their web site.

I recommend looking directly at OpenVPN's own documentation (it's quite good). Some of my initial issues with the setup only occurred because I believed one how-to when it said I needed to set up a bridge interface to do what I wanted to do. Anyway, if all you want is to send your internet traffic out through your OpenVPN server, following the steps in this particular how-to will be all you need.

You can either set up your VPN with a static key or using PKI. The PKI option is a better choice, as it has some benefits like ensuring perfect forward secrecy. In order to go the PKI route, you need to generate a bunch of certificates. The OpenVPN developers have made things pretty easy, though, with the easy-rsa folder. If you aren't using Ubuntu, there may be some changes you'll need to make, but I'm sure you can figure it out.

Go ahead and change into that directory and edit the /etc/openvpn/easy-rsa/vars file, setting the KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL parameters. Then, run the following commands to build the CA certificates and keys you need:

# . ./vars
# ./clean-all
# ./build-ca
# ./build-dh

Generate your server keypair and TLS key:

# ./build-key-server server
# openvpn --genkey --secret ta.key

Generate keypairs for any clients that will be connecting to the vpn:

# ./build-key client1
# ./build-key client2

Set up the actual VPN

Now that we have all the keys generated, we can create the client and server config files for our VPN. The OpenVPN developers also make this pretty easy by supplying some sample config files with their documentation. On Ubuntu, that happens to reside in /usr/share/doc/openvpn/examples/sample-config-files/ (server.conf is the one we're interested in). Copy that default config file over into /etc/openvpn/, and let's get to editing. This config file is actually rather self-explanatory, but here are the lines we want to change (most of them just need to be uncommented):

[...]
# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key). Each client
# and the server must have their own cert and
# key file. The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series
# of scripts for generating RSA certificates
# and private keys. Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca ca.crt
cert server.crt #if you named your server keypair something else
key server.key # make sure you change it here
[...]
# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
push "redirect-gateway def1 bypass-dhcp"
# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# The addresses below refer to the public
# DNS servers provided by opendns.com.
push "dhcp-option DNS 208.67.222.222" #you can use googledns if you want
push "dhcp-option DNS 208.67.220.220" # (8.8.8.8 and 8.8.4.4)
[...]
# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
# openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth ta.key 0 # This file is secret
[...]
# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
user nobody
group nogroup
[...]

An example client config file is in that same directory, not surprisingly named client.conf. Here are the lines you'll want to change in that file:

[...]
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote vpn.example.com 1194 #put your server IP or name here
[...]
# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca ca.crt
cert client1.crt #replace with whatever you named your cert/key
key client1.key
[...]
# If a tls-auth key is used on the server
# then every client must also have the key.
tls-auth ta.key 1
[...]

You should actually be able to connect to the VPN now (but any internet traffic won't be flowing yet). In order to get that to work, you have to enable IP forwarding on the server and set up a rule so that any traffic from the VPN will get NAT-ed. To do that, I added the following two lines to /etc/rc.local so they would be run automatically whenever the system booted up.

Client side

After installing OpenVPN on your client, you need to securely copy the following files over to the client that will be connecting: ca.crt, ta.key, client1.crt, client1.key, and client.conf. In Linux, you can stick them in /etc/openvpn/, and in Windows they have to go into C:\Program files\OpenVPN\config\. If you have a Linux client, starting the OpenVPN service will autostart all the vpns you have in your /etc/openvpn/ directory.

Then, take a gander at a site like ipchicken.com before and after starting up your VPN connection to make sure that the IP address changes to the public IP address of your VPN server.

Security

Using a VPN is a great thing to do if you're concerned with security, and it can get you around some web blocking issues, but I need to warn you of a few things:

People will still be able to see the public IP address of your VPN server when you browse. If you're trying to browse anonymously, then you need to either use some means of obtaining a VPN server that can't be linked back to you. It might be easier to just use something designed for that, though (like Tor).

Using a VPN works for preventing people in the coffee shop from spying on your wireless traffic. It does not, however, keep people in between your VPN server and the site you're browsing from looking at your traffic. You should make sure you're using SSL/TLS to protect against that.

You shouldn't always count on being able to use your VPN. Some places will only allow certain traffic out of their network (like only web traffic). If you encounter something like that, there are other ways to get around it like using a proxy or even something crazy like DNS tunneling (lol).

While people on the network (or people running the network) won't be able to see your internet traffic, they will be able to see that you're using a VPN. This one probably isn't too much of an issue.

I hope this one is obvious, but using a VPN will not protect you from viruses and other bad stuff on the shady (or even non-shady) sites you intend to browse.

Now go forth, and browse (more) securely on unprotected networks!

About

Devin is a security analyst currently living in Alabama while his
wife attends vet school. He recently graduated with an MS in
computer science.