[toc]After a new clean install of my home server I thought I'd try a routed OpenVPN setup rather than the bridged type setup [here]. Since there is usually a maximum of 2 concurrent connections to my home server I've never found the need to use a routed setup and found SMB shares were working ok.

Now I've tried a routed setup I can see the benefit in terms of speed and functionality :)

You can read more about the differences on the OpenVPN site: what-is-the-difference-between-bridging-and-routing

This guide was made using a samsung galaxy s2 running cyanogenmod 7.2.0. The server is running Fedora 16 and openvpn 2.2.1.  Here's a (very poor) diagram of the setup.

I've also testing this server setup using cyanogenmod 9 nightly and OpenVPN for android which is a new application that makes use of a VPN API added in Android 4.0+. It works very well and this application is very good!

crappy diagram

OS/System setup

First off install the required packages
yum install openvpn
Now we need to check ip forwarding  is enabled.  cat /proc/sys/net/ipv4/ip_forward  should return 1 if its already enabled. If it returns 0 run the command below.
echo 1 > /proc/sys/net/ipv4/ip_forward
To make this persist throuhg reboots add net.ipv4.ip_forward = 1 to the /etc/sysctl.conf file You can also do it by editing /etc/sysctl.conf and adding the following (this is a good thing to do as it will ensure that packet-forwarding persists across reboots):
net.ipv4.ip_forward = 1
Next we need to allow traffic through the servers firewall
iptables -A INPUT -m state –state NEW -m udp -p udp –dport 12345 -j ACCEPT
iptables -A INPUT -i tap+ -p all -j ACCEPT
iptables -A OUTPUT -o tap+ -p all -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
iptables -A FORWARD -i eth0 -o tap+ -j ACCEPT
iptables -A FORWARD -i eth0 -o tap+ -m state –state ESTABLISHED,RELATED -j ACCEPT

OpenVPN Server

Certificates

Now we need to generate certificates for our server to use. OpenVPN comes with some scripts to take most of the pain out of this. To keep things where I can find them I like to move these to/etc/openvpn/easy-rsa. First off we make a new directory and copy the scripts into it.
mkdir /etc/openvpn/easy-rsa
cd /etc/openvpn
cp -R /usr/share/openvpn/easy-rsa/2.0/* easy-rsa/
cd easy-rsa
Edit the following in the vars file of this directory
export KEY_COUNTRY="UK"
export KEY_PROVINCE="M0"
export KEY_CITY="m00nieTown"
export KEY_ORG="m00nie.co"
export KEY_EMAIL="spam@weeeeeimaspamer.com"
Now just run the following commands
source ./vars ## execute your new vars file
./clean-all  ## Setup the easy-rsa directory (Deletes all keys)
./build-dh  ## takes a while consider backgrounding
./pkitool --initca ## creates ca cert and key
./pkitool --server server ## creates a server cert and key
cd keys
openvpn --genkey --secret ta.key  ## Build a TLS key
sudo cp server.crt server.key ca.crt dh1024.pem ta.key ../../
cd ../..

Server Config File

Now to edit the /etc/openvpn/server.conf file. Mine looks like the following
#################################################
# OpenVPN server config file
# Made using OpenVPN 2.SOMETHING on Fedora 16
#################################################
mode server
tls-server

Local IP to bind to

local 10.10.10.2 port 12345

TCP or UDP....Might be worth trying both to check your

own performance but Id go for UDP first

proto udp

tun OR tap

tun = routed

tap = bridged

dev tun

Certificate locations

ca ca.crt
cert server.crt
key server.key
dh dh1024.pem

Configure server mode and supply a VPN subnet

for OpenVPN to draw client addresses from.

The server will take 192.168..1.1 for itself,

the rest will be made available to clients.

Each client will be able to reach the server

on 192.168.1.1

server 192.168.1.0 255.255.255.0

This tells OpenVPN to record IPs given to hosts and

each time a host will be given the same IP

ifconfig-pool-persist ippool.txt

Push routes to the client to allow it

to reach other private subnets behind

the server. Remember that these

private subnets will also need

to know to route the OpenVPN client

address pool (10.8.0.0/255.255.255.0)

back to the OpenVPN server.

push "route 10.10.10.0 255.255.255.0"

Pushing DNS doesn't seem to currently work although

this requires a script on a non windoes system so I'll

try sometime :)

push “dhcp-option DNS 8.8.8.8″

Allow clients to "see" each other

client-to-client

Send keep alive every 10s and fail after 120s of no reply

keepalive 10 120

Configure the (pretty awesome) tls-auth

tls-auth ta.key 0

Select a cryptographic cipher.

cipher AES-128-CBC # AES

cipher DES-EDE3-CBC # Triple-DES

cipher BF-CBC # Blowfish (default)

Enable compression on the VPN link.

If you enable it here, you must also

enable it in the client config file.

comp-lzo

The maximum number of concurrently connected

clients we want to allow.

max-clients 5

It's a good idea to reduce the OpenVPN

daemon's privileges after initialization.

user nobody
group nobody

The persist options will try to avoid

accessing certain resources on restart

that may no longer be accessible because

of the privilege downgrade.

persist-key
persist-tun

Output a short status file showing

current connections, truncated

and rewritten every minute.

status openvpn-status.log

Logging...

log-append openvpn.log

Set the appropriate level of log

file verbosity.

0 is silent, except for fatal errors

4 is reasonable for general usage

5 and 6 can help to debug connection problems

9 is extremely

verbose verb 4

Silence repeating messages. At most 20

sequential messages of the same message

category will be output to the log.

mute 20


You should be able to run the server with the following command and recieve no errors. If you do fix them first

openvpn --config server.conf --script-security 2

If it all looks good lets make OpenVPN run as a service and start when the server boots

systemctl start openvpn@server.service
systemctl enable openvpn@server.service

Client Setup

Client Certificates

We need to create some certificates for our client (the phone)
cd /etc/openvpn/easy-rsa
Now edit the vars file and change the CN to something unique (this needs done for each cert you generate). Then execute the commands below to crrate a p12 file. This one file will contain all the certificates the phones needs (although not the ta.key file).
source ./vars
./pkitool --pkcs12 phone
Now I just moved the file to my webserver and browsed there on the phone.
cd keys
mv phone.p12 /var/www/html
Now browse to the file on your phone E.g http://10.10.10.2/phone.p12. Your phone will then store the certificates into is credential store (you might need to set-up a credential store password if you haven't already) :) You can also just copy it to the phones flash and install it from there.

Phone setup

Cyanogenmod  7.2.0 seems to add native TLS-auth support so configure the phone like below:

Main VPN settings page for openvpn in cyanogenmod android

Advanced openvpn settings for cyanogenmod android

TLS auth settings for cyanogenmod openvpn android

 

 

 

 

 

 

 

 

 

 

Save the settings and try connecting :D (you may need to forward ports on your router). If you redirect your gateway you may need to change your DNS settings I used Set DNS for this.