box.matto.nl

home/

Connect your Android mobile phone to your home network servers with OpenVPN

Last edited

OpenVPN is a very flexible full-featured SSL VPN. It is completely open source. OpenVPN can be set up in many different ways. In this page we concentrate on setting up a VPN with key-based authentication.

Server

Run your own OpenVPN server on a Raspberry Pi

We use a Raspberry Pi for our OpenVPN server.

Because we don't need much more than a bare Debian, we start with creating a sober rootfs. A very easy way to do this is to start with a standard Raspbian image, boot it on the Raspberry Pi. Create a new partition on the SD card, set a filesystem on it with mkfs.ext3. Mount the partition, and do a debootstrap on it. Copy the /dev directory from Raspbian to it with cp -avx. Chroot into it, set a password for root and create a new user with a password. Now apt-get install openssh-server (so that we can do most of the work from the comfort of our desktop) and exit the chroot.

Shut down the Raspberry and put the SD-card in a Linux machine. Mount the original Raspbian partition as well as the new debootstrap partition and copy the deboostrap partition over the Raspbian partition with cp -avx. Umount and put the SD-card back into the Rapsberry Pi and boot from it. You now have a bare Debian.

Protect SD card from wearing out

Put directories that will see a lot of write cycles on tmpfs.

Example /etc/fstab:

/dev/sda1  /       ext2    defaults,noatime,errors=remount-ro       0 1
proc            /proc   proc    defaults        0       0
none    /run        tmpfs   defaults
none    /run/lock   tmpfs   defaults
none    /var/log    tmpfs   mode=0755,defaults,size=10M
none    /tmp        tmpfs   defaults

Install openvpn

apt-get install openvpn

Create certificates and keys

cp -a /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn/
cd /etc/openvpn/2.0

Edit the file vars:

export EASY_RSA="`pwd`"
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
export KEY_SIZE=4096
export CA_EXPIRE=3650
export KEY_EXPIRE=3650
export KEY_COUNTRY="US"
export KEY_PROVINCE="DR"
export KEY_CITY="Peize"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_EMAIL=mail@host.domain
export KEY_CN=mijncn
export KEY_NAME=mijnnaam
export KEY_OU=mijnou
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234

Because of the line export KEY_SIZE=4096 you will create a pem-file of 4096 bytes, with will take a very long time. Best do this from within screen so this will continue even if your ssh connection times out.

Now generate the the cerficates and keys

. ./vars
./build-ca
./build-da
./build-key-server my_server 
./build-key android

Make a symlink to the keys directory in /etc/openvpn

cd /etc/openvpn
ln -s easy-rsa/2.0/keys .

Generate ta.key and move it to the keys directory

openvpn --genkey --secret ta.key
mv ta.key keys

/etc/openvpn/server.conf

Below you find the contents of server.conf, based on a local home network on 192.168.1.xxx, the VPN will use 10.8.0.x for the VPN-server and your Android phone connection.

proto udp
dev tun
ca /etc/openvpn/easy-rsa/2.0/keys/ca.crt
cert /etc/openvpn/easy-rsa/2.0/keys/mijnserver.crt
key /etc/openvpn/easy-rsa/2.0/keys/mijnserver.key  # This file should be kept secret
dh /etc/openvpn/easy-rsa/2.0/keys/dh4096.pem
server 10.8.0.0 255.255.255.0 
push "route 192.168.1.0 255.255.255.0" 
ifconfig-pool-persist /tmp/ipp.txt
keepalive 10 120
push "redirect-gateway def1 "
tls-auth /etc/openvpn/easy-rsa/2.0/keys/ta.key 0 # This file is secret
# comp-lzo  # Comment this line out otherwise you will get write_some invalid argument errors 
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log
log-append openvpn.log
verb 3

This last line gives the debug level. Choose "verb 9" for a very verbose logging.

The line "status openvpn-status.log" will result in a small status file being kept up to date giving a bit of status info on connections.

The line "log-append openvpn.log" will result in the creation of a log-file named openvpn.log. Use this for testing purposes, we have put it in /var/log in order to move it to a tmpfs directory to prevent the SD card of your Raspberry Pi wearing out. This file can grow, so after testing perhaps it is best to comment this line out and restart the VPN server.

Restart OpenVPN

/etc/init.d/openvpn restart

Routing and NAT-ing

We need to setup NAT (network address translation) to give your VPN client access to the servers in your local home network. The VPN server will act as a gateway for your Android phone.

We set up NAT so that there is no additional routing required on your local servers, the VPN server will impersonate the requests from your Android.

/etc/sysctl.conf

Uncomment the following line:

net.ipv4.ip_forward=1

iptables

Create /etc/network/if-pre-up.d/iptables

#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules

To create the file /etc/iptables.up.rules issue the following commands:

iptables -A INPUT -i eth0 -m state --state NEW -p udp --dport 1194 -j ACCEPT

# Allow TUN interface connections to OpenVPN server
iptables -A INPUT -i tun+ -j ACCEPT

# Allow TUN interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT

# NAT the VPN client traffic to the internet
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Save the rules with the command:

iptables-save > /etc/iptables.up.rules

Create .ovpn file for your Android device

Create a file openvpn.ovpn (or whatever, just let the filename end with .ovpn). In this we take the contents of ca.cert, android.cert, android.key and ta,key. The file has the following layout, just copy the base-64 blocks from these four files into it on the appropriate places. Replace "myserver.example.com" on the third line with the FQDN or the public ip-address of your network.

client
proto udp
remote myserver.example.com
port 1194
dev tun
nobind

key-direction 1

<ca>
-----BEGIN CERTIFICATE-----
The base64 block of your ca.cert file goes in here.
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
The base64 block of your android.cert file goes in here.
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
The base64 block of your android.key file goes in here.
    -----END PRIVATE KEY-----
</key>

<tls-auth>
-----BEGIN OpenVPN Static key V1-----
The base64 block of your ta.key file goes in here.
-----END OpenVPN Static key V1-----
</tls-auth>

Put this .ovpn file on the Micro SD card of your Android phone. Install the OpenVPN connect app from the Playstore on your Android phone. Start it, open the menu and choose Import. Import the .ovpn file and test the connection.

Resources