05 January 2010

HOWTO: Set up OpenVPN in a VPS

If, like me, you want to do any or all of the following things, you'll want to tunnel your traffic over a VPN to a remote location:
  • Access media services restricted by geography (Hulu, FOX, BBX, etc.)
  • Bypass draconian censorship
  • Conceal your identity/location/etc.
  • Protect your machine from attackers
  • etc.
You could of course use a commercial service like AlwaysVPN in which case you typically pay ($5-10) per month or (~$1) per gigabyte, but many will prefer to run their own service. FWIW AlywaysVPN has worked very well for me but it's time to move on.

First thing's first you'll want to find yourself a remote Linux server, and the easiest way to do so is to rent a virtual private server (VPS) from one of a myriad providers. No point spending more than 10 bucks a month on it as you don't need much in the way of resources (only bandwidth). Check out lowendbox.com for VPS deals under $7/month or just run with a BurstNET VPS starting at $5.95/month for a very reasonable resource allocation (including a terabyte of bandwidth!).

Once you've placed your order and passed their fraud detection systems (which includes an automated callback on the number you supply) you'll have to wait 12-24 hours for activation, upon which you'll receive an email with details for accessing your vePortal control panel as well as the VPS itself (via SSH). You'll get 2 IP addresses and I dedicated the second to both inbound and outbound traffic for VPS clients (which live on a 10.x RFC1918 subnet and access the Internet via SNAT).

If you didn't already do so when signing up then choose a sensible OS in your control panel ("OS Reload") like Ubuntu 8.04 - a Long Term Support release which means you'll be getting security fixes for years to come - or better yet, 10.4 if it's been released by the time you read this (it's the next LTS release). Do an "apt-get install unattended-upgrades" and you ought to be fairly safe until 2015. You're also going to need your TUN/TAP device(s) enabled which involves another trip to the control panel ("Enable Tun/Tap") and/or a helpdesk ticket (http://support.burst.net/). If /dev/net/tun doesn't exist then you can create it with "mknod /dev/net/tun c 10 200".

To install OpenVPN it's just a case of doing "apt-get install openvpn"... you could also download a free 2-user version of OpenVPN-AS from http://openvpn.net/ but I found it had problems trying to load netfilter modules that were already loaded so YMMV. If you want support or > 2 users you'll be looking at a very reasonable $5/user - you're on your own with the free/open source version but there's no such limitations either.

OpenVPN uses PKI but rather than go to a certificate authority we'll set one up ourselves. EasyRSA is included to simplify this process so it's just a case of doing something like this:
cd /usr/share/doc/openvpn/examples/easy-rsa/2.0
. ./vars
./clean-all
./build-ca
./build-dh
openvpn --genkey --secret ta.key
./build-key-server server
./build-key client1
./build-key client2
./build-key client3

It'll ask you a bunch of superflous information like your country, state, city, organisation, etc. but I just filled these out with '.' (blank rather than the defaults) - mostly so as not to give away information unnecessarily to anyone who asks. The only field that matters is the Common Name which you probably want to leave as 'server', 'client1' (or some other username like 'samj'), etc. When you're done here you'll want to "cp keys/* /etc/openvpn" so OpenVPN can see it.

Next you'll want to configure the OpenVPN server and client(s) based on examples in /usr/share/doc/openvpn/examples/sample-config-files. I'm running two - one "Faster" one for the best performance when I'm on a "clean" connection (which uses udp/1194) and another "Compatible" one for when I'm on a restricted/corporate network (which shares tcp/443 with HTTPS). I did a "zcat server.conf.gz > /etc/openvpn/faster.conf" and edited it so it (when filtered with `cat faster.conf | grep -v "^#" |grep -v "^;" | grep -v "^$"`) looks something like this:

local 173.212.x.x
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.9.0.0 255.255.255.0
ifconfig-pool-persist faster-ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
client-to-client
keepalive 10 120
tls-auth ta.key 0
cipher BF-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/faster-status.log
log-append /var/log/openvpn/faster.log
verb 3
mute 20

Noteworthy points:
  • local specifies which IP to bind to - I used the second (of two) that BurstNET had allocated to my VPS so as to keep the first for other servers, but you could just as easily use the first and then put clients behind the second, which would appear to be completely "clean".
  • We're using "tun" (tunneling/routing) rather than "tap" (ethernet briding) because BurstNET use venet interfaces which lack MAC addresses rather than veth. Wasn't able to get bridging up and running, as originally intended.
  • There are various hardening options but to keep it simple I just run as nobody:nogroup and use tls-auth (having generated the optional ta.key with "openvpn --genkey --secret ta.key" above).
  • Pushing Google Public DNS addresses to clients as they won't be able to use their local resolver addresses once connected. Also telling them to route all traffic over the VPN (which would otherwise only intercept traffic for a remote network).
  • Configured separate log files and subnets (10.8.0.0/24 and 10.9.0.0/24) for the "faster" and "compatible" instances.

The "compatible.conf" file varies only with the following lines:
port 443
proto tcp
server 10.8.0.0 255.255.255.0
status /var/log/openvpn/compatible-status.log
log-append /var/log/openvpn/compatible.log


Next you'll want to copy over client.conf from /usr/share/doc/openvpn/examples/sample-config-files (but set 'AUTOSTART="compatible faster"' in /etc/default/openvpn so it's ignored by the init scripts).
client
dev tun
proto udp
remote 173.212.x.x 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca burstnet-ca.crt
cert burstnet-client.crt
key burstnet-client.key
ns-cert-type server
tls-auth burstnet-ta.key 1
cipher tls-cipher DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA
cipher BF-CBC
comp-lzo
verb 3

As I've got a bunch of different connections on my clients I've prepended "burstnet-" to all the files and called the main config files "BurstNET-Faster.conf" and "BurstNET-Compatible.conf" (which appear in the Tunnelblick menu on OS X as "BurstNET-Faster" and "BurstNET-Compatible" respectively - thanks to AlwaysVPN for this idea). The only difference for BurstNET-Compatible.conf is:
proto tcp
remote 173.212.x.x 443

You're now almost ready for the smoke test (and indeed should be able to connect) but you'll end up on a 10.x subnet and therefore unable to communicate with anyone. The fix is "iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -j SNAT --to-source 173.212.x.x" (where the source IP is one of those allocated to you).

Being paranoid though I want to lock down my server with a firewall, which for Ubuntu typically means ufw (you'll need to "apt-get install ufw" if you haven't already). My ufw rules look something like this:

# ufw status
Status: active

To                         Action  From
--                         ------  ----
Anywhere                   ALLOW   1.2.3.4
1194/udp                   ALLOW   Anywhere
443/tcp                    ALLOW   Anywhere

The first rule allows me to access the server from home via SSH and 1194/udp and 443/tcp allow VPN clients in. To allow the clients to access the outside world we're going to have to rewrite their traffic to come from a public IP (which is called "SNAT"), but first you'll want to enable forwarding by setting DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw. Then it's just a case of adding something like this to /etc/ufw/before.rules:

# nat Table rules
*nat
:POSTROUTING ACCEPT [0:0]

# SNAT traffic from VPN subnet.
-A POSTROUTING -s 10.8.0.0/255.255.255.0 -j SNAT --to-source 173.212.x.x
-A POSTROUTING -s 10.9.0.0/255.255.255.0 -j SNAT --to-source 173.212.x.x

# don't delete the 'COMMIT' line or these nat table rules won't be processed
COMMIT

You may need to enable UFW ("ufw enable") and if you lose access to your server you can always disable UFW ("ufw disable") using the rudimentary "Console" function of vePortal.

On the client side you've got support for (at least) Linux (e.g. "openvpn --config /etc/openvpn/BurstNET-Faster.conf"), Mac and Windows and there's various GUIs (including OpenVPN GUI for Windows and Tunnelblick for Mac OS X). I'm (only) using Tunnelblick, and after copying Tunnelblick.app to /Applications I just need to create a ~/Library/openvpn directory and drop these files in there:
  • BurstNET-Compatible.conf
  • BurstNET-Faster.conf
  • burstnet-ca.crt
  • burstnet-client.key
  • burstnet-client.crt
  • burstnet-ta.key

When Tunnelblick's running I have a little black tunnel symbol in the top right corner of my screen from which I can connect & disconnect as necessary.

I think that's about it - hopefully there's nothing critical I've missed but feel free to follow up in the comments if you've anything to add. I'm now happily streaming from Hulu and Fox in the US, downloading Amazon MP3s (using my US credit card), and have a reasonable level of anonymity. If I was in Australia I'd have little to fear from censorship (and there's virtually nothing they can do to stop me) and as my machine has a private IP I'm effectively firewalled.

8 comments:

c said...

For the sometimes user, couldn't you do this with a bottom-of-the-barrel Rackspace instance or AWS? You could avoid all the subscription business and $6/mo would be about 75 hours of anon-a-browsing on AWS or ~400 on Rackspace's crapulous 256MB instances.

You might either roll your own optimized instance or dig up a pre-made virtualized appliance.

Either way, great little tutorial, tres au courant for all the social media/internet bannination/etc that goes on today.

You should change the title to boost it up in SEO a bit, I think it has legs. "Roll your own VPN and VPS for safe and secure browsing", or "HEY LOOK AT THIS CHINA/IRANIAN FREEDOM FIGHTERS AND AUSTRALIAN PORN ADDICTS", something catchy?

Anyway, I'll be trying this out, especially for travel. I don't care to have weasely hoteliers and bootlicking airports analyzing my traffic, thankyouverymuch, and this beats a proxy to home by a mile.

zlayer said...

I was looking for something just like this!
I already have a VPS (not with burstnet though), and I had unknowingly ran into a tap/tun issue you mentioned. Now I think I know what went wrong, I can go try again.
While we're at it, is it possible to route only one application through the VPN on the client side? Like, browse via VPN and send mail via my ISP? Or even better - outlook sends via ISP and my private thunderbird acc uses the VPN link?

Anonymous said...

very good tutorial. been looking for something like this for a long time. plus you put me on to burstnet. they seem pretty good to me.

Gabi said...

Heya,

I've done exactly what you said in this how-to, but when I connect to my VPN connection, my IP doesn't change...

Any solution ?
I have a burst vps.

anjar said...

very usefull tutorial, i have a vps in burst.net too, but my vpn doesnt start now... i dont know why..i can connect but if i ping dhcp server always time out, can you give me solution?

Tonni said...

h sams ,

why does my openvpn setting can download up to 2 mbps but when i tried to browse a streaming content like youtube, it became very slow ?

Sam Johnston said...

Guys I'm so sorry but I just don't have the time to provide support for BurstNET's services and/or OpenVPN - I'd suggest checking out the OpenVPN community for most of these questions.

Jason Ip said...

anyone know why my iptables command wouldn't be working? I'm on burstnet with Ubuntu 9.1 x64

Post a Comment