OpenVPN server on Fedora 16 connecting Cyanogenmod 7.2.0 [routed]

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


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_PROVINCE="M0"
export KEY_CITY="m00nieTown"
export KEY_ORG=""
export KEY_EMAIL=""

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

# Local IP to bind to
local 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

# 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 (
# back to the OpenVPN server.
push "route"
# 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″

# Allow clients to "see" each other

# 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.

# 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.

# 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 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 😀 (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.


  • I’m having some trouble with this, I followed these instructions exactly- running Fedora 16 and CM7.2 RC1 on a HTC Vision.
    I’m not sure how to go about troubleshooting it, it just keeps saying “Connecting…” until it times out and I see an error “Unable to connect to the network. Do you want to try again?” (This is on the phone)
    Any ideas on how to fix it…? These instructions have been very useful and I hope I can get it working.

  • Hi Proxin

    Usually I manually run the openvpn server openvpn --config server.conf --script-security 2 so I can monitor the output while I try connecting. Usually the logs are very descriptive of the problem.
    If you dont get anything in the logs when you try to connect then I’d guess there’s a problem on your router/firewall/nat.

    m00nie 🙂

  • I did have an error that I got fixed by that: by using ‘systemctl start openvpn@server.conf‘, it used up the port I was attempting to use with the command ‘openvpn –config server.conf –script-security 2’. I got the following error:

    Mon May 7 08:05:07 2012 us=441920 TCP/UDP: Socket bind failed on local address [undef]:1194: Address already in use

    I used ‘systemctl stop openvpn@server.service‘ and retried it and it started successfully.
    Errors below are what I am seeing (so they ARE interacting, it’s just not connecting properly somehow…):

    Mon May 7 08:12:06 2012 us=129989 read UDPv4 [ECONNREFUSED]: Connection refused (code=111)

    I see multiple lines of this as the phone attempts to connect to it. Do you know anything I should do to get this working? I feel like I’m really close and I’ve been wanting to do this for months now…
    Thanks for the help so far by the way. 🙂

  • I have read that this “TLS handshake failed” issue might be fixed by syncing time between the server and client, would you happen to have any leads to point me in the right direction to get this working?

  • Hi Proxin

    Might just be you need to change your “device” under the settings on your phone to TUN?


  • Hi again,
    I got that issue fixed, looks like an glitch happened with my keys somehow. I cleaned them and created new ones and fixed that.

    So I can now connect, but when I am connected to the VPN on my phone, I lose the ability to do pretty much anything else with data (DNS issue I think). Whether I have “Redirect Gateway” selected or not on my phone, I get timeouts on pages loading as well as no reply from pings (tried pinging and its IP as well)

    “From Dest Unreachable, bad code: 10” repeats down my screen when I try to ping.

    Is there anything you can think of that I should do to fix this? Do I need to have more ports forwarded to my server machine?

    Sorry to keep bugging you with this by the way… 🙁

  • Hi again Proxin

    To sort the DNS i used Set DNS from the market. Theres a link at the end of the post 🙂

    You could try a traceroute and see where the problem starts. Your maybe missing a route for the openvpn subnet on your router? It could be a NAT problem too? E.g. I had to add my openvpn subnet to my NAT ACL since it was a cisco router.
    Its probably not an issue on your server machine i would guess.

    m00nie 🙂

  • Hey m00nie!
    I’ve been having a rough time getting this to work, I have been unable to ping the server through the VPN. BUT! I ran a script to clear my iptables, made YOUR iptables into a script and ran it, then rebooted and now I can ping 🙂

    The only thing I am missing is ability to connect to other machines now once traffic is routed through the VPN… I used Set DNS from the Market like you recommended, and it’s a fantastic app- but I can’t seem to get DNS to work.
    Can you describe exactly what you had to on your router to add your openvpn subnet ot your NAT ACL? I have a Netgear router which is what I’m working with, hopefully the procedure will be similar.
    Thanks for all of the help so far :mrgreen:

  • Hi Proxin

    Glad to hear your pretty much there 🙂

    My setup uses a Cisco 1800. I just added my subnet to be permitted by the ACL applied to the nat statement. so something like access-list 100 permit ip any . I’ve never used a netgear router so I cant be much more help there I’m afraid but I would guess they just NAT any internal address. Maybe worth checking the routing on the netgear too?
    Good luck


  • I got it working using NAT-Hack, from here:

    Someone on OpenVPN IRC described this as the solution because (and I quote)
    “his router is probably a POS NetGEAR that doesn’t allow much configuration”
    Which, is probably true because I haven’t found a way to define routes.
    Thanks for all the help m00nie, I can finally route all traffic through the VPN, ping any internal LAN address, etc. now.

  • Hi Proxin

    Cool 😀 Glad you got it sorted in the end and thx for sharing the “NAT-Hack” I’ll have a look at that too.


Leave a Reply