Setup a VPN on Your iPhone With OpenVPN and Linux

January 19, 2013 Category: Security

Introduction

I'm quite happy because finally there is an official OpenVPN client for IOS. It took me about an hour to setup an OpenVPN server and got the iPhone working. This is the 'press release'.

screenshot

The OpenVPN client is great because it automatically reconnects when your iPhone wakes from sleep, do you don't have to manually reconnect.

So this is how to quickly setup your own OpenVPN server and hook up your iPhone.

How It Works

OpenVPN is an SSL-based VPN solution. SSL-based VPNs are cool because if you set it up properly, you will never be blocked by any firewall as long as TCP-port 443 is accessible. Standard, OpenVPN uses UDP as a transport at port 1194, but you can switch to TCP to increase the chance that your traffic will not be blocked.

Authentication is performed based on public/private key cryptography. The OpenVPN server is similar to an HTTPS server. The client however, does not authenticate with a username and password but you use a client certificate.

So before you can setup an actual VPN configuration with OpenVPN, you need to setup a Certificate Authority.

With the CA you can create the server certificate and then generate all client certificates for authentication. Clients use the CA certificate to validate the server.

OpenVPN installation

OpenVPN is often standard on most common Linux Distros. apt-get install openvpn for any Debian or Ubuntu version is all you need to install OpenVPN.

Or take a look here

Creating a certificate authority.

I assume that you will create a configuration in /etc/openvpn. But before you can setup the configuration, you need to create a certificate authority. I used the folder /etc/openvpn/easy-rsa for this.

This is no coincidence, as we use the easy-rsa scripts as part of OpenVPN to quickly setup our certificate authority.

We start with copying all these files to this new directory:

cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0* /etc/openvpn/easy-rsa

Next, we cd to this directory and edit the 'vars' file. The following instructions are straight from the OpenVPN howto.

export KEY_COUNTRY="US"
export KEY_PROVINCE="California"
export KEY_CITY="San Fransisco"
export KEY_ORG="My Company"
export KEY_EMAIL="my@mail.com"
export KEY_CN=server
export KEY_NAME=server
export KEY_OU=home

Then I had to copy openssl-1.0.0.cnf to openssl.cnf because the 'vars' script complained that it couldn't find the latter file.

cp openssl-1.0.0.cnf openssl.cnf

Then we 'source' var and run two additional commands that actually generate the certificate authority.

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

You will have to confirm the values or change them if necessary.

Now we have a certificate authority and we can create new certificates that will be signed by this authority.

WARNING: be extremely careful with all key files, they should be kept private.

Creating the Server Certificate

First we create the server certificate:

./build-key-server server

It's up to you to come up with an alternative for 'server'. This is the file name under which the key files and certificates are stored.

All files that are generated can be found in the '/etc/openvpn/easy-rsa/keys' directory.

Creating the Client Certificate

Now that we have a server certificate, we are going to create a certificate for our iPhone (or any other iOS device).

./build-key iPhone

Last, we must generate Diffie-Helman parameters like this:

./build-dh

So now we have everything in place to start creating an OpenVPN configuration. We must create a configuration for the server and the client. Those configurations are based on the examples that can be find in /usr/share/doc/openvpn/examples/.

Example Server configuration

This is my server configuration which is operational. It is stored in /etc/openvpn/iphone.conf

dev tun2
tls-server
dh easy-rsa/keys/dh1024.pem
ca easy-rsa/keys/ca.crt
cert easy-rsa/keys/server.crt
key easy-rsa/keys/server.key
server 10.0.0.0 255.255.255.0
log /var/log/openvpn-iphone.log
comp-lzo
script-security 2
route-up "/sbin/ifconfig tun2 up"
port 443
proto tcp-server
keepalive 30 120
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"

I use TCP-port 443 as this destination port is almost never blocked as this would break most internet connectivity. The downside is that I can no longer host any secure web site on this IP-address.

I'm aware that you now know that I'm running OpenVPN on this box and you will be able to talk to this service, however, as it uses certificates for authentication, security will be sufficient, unless OpenVPN itself is vulnerable.

The keepalive parameter prevents your phone from reconnecting every 40 seconds by default, as I experienced.

Change any parameters if required and then start or restart the OpenVPN service:

/etc/init.d/openvpn restart

Make sure that the server is running properly in /var/log/openvpn-iphone.log

If you want to use your VPN to browse the internet, we still need to configure a basic firewall setup.

I'm assuming that you already have some kind of IPtables file wall running. If not, you might want to look at LIFS, a powerful Linux firewall script. So I assume that you already have a secure IPtables configuration, you only need to add some stuff.

Assuming that you will - for example - use the 10.0.0.0/24 network for VPN clients such as your iPhone, you must also create a NAT rule so VPN clients can use the IP-address of the Linux server to access Internet.

iptables -t nat -A POSTROUTING -s "10.0.0.0/24" -o "eth0" -j MASQUERADE

Please note that you must change eth0 with the appropriate interface of your router. Change the IP-address range according to your own situation. It should not conflict with your existing network.

iptables -A FORWARD -p tcp -s 10.0.0.0/24 -d 0.0.0.0/0 -j ACCEPT

Please note that I haven't tested these rules, as I have a different setup. But this should be sufficient. And make sure that forwarding is enabled like this:

echo 1 > /proc/sys/net/ipv4/ip_forward

Example Client configuration

Create a file called iphone.ovpn and configure it like this:

tls-client
remote <some domain name or IP address>
ca ca.crt
cert iphone.crt
key iphone.key
comp-lzo
port 443
proto tcp

Setting up your iPhone

You need to get the following files on your iOS device:

iphone.ovpn
ca.crt
iphone.crt
iphone.key

The safest way is to use iTunes and connect your device with a cable, although I believe that iCloud stuff works too.

  1. Open iTunes
  2. Select your device at the top right
  3. Go to the Apps tab
  4. Scroll to the file sharing section
  5. Select the OpenVPN application
  6. Add all mentioned files at the right side
  7. Sync your device

Test your iPhone

Open the OpenVPN client. You will see a notice that a new configuration has been imported and you need to accept this configuration. As it might not work straight away, you need to monitor /var/log/openvpn-iphone.log on the server to watch for any errors.

Now try to connect and enjoy.

Updated 20130123 with keepalive option. Updated 20130801 with extra server push options for traffic redirection and DNS configuration

Comments