Setting up OpenVPN on Ubuntu 16.04

22/11/2018 - Linux, OpenVPN, Android

This article outlines how to setup a VPN using OpenVPN on an Ubuntu 16.04 server with an Android client. The main goal is to get setup as quickly as possible so that internet traffic on the client goes through the server. It is a minimal set of steps taken from the guide available here. Follow the full guide if any customisation is needed.

This was setup on an OpenVZ instance running Ubuntu 16.04, in which case it is important that the tun interface is enabled (likely through your instance's control panel). The version of OpenVPN is:

OpenVPN 2.3.10 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Jun 22 2017
library versions: OpenSSL 1.0.2g  1 Mar 2016, LZO 2.08

easy-rsa setup

First install OpenVPN and easy-rsa and then create a certificates directory using make-cadir:

sudo apt install openvpn easy-rsa
make-cadir ~/openvpn-ca

Now build the certificate authority and generate necessary certificate and files (using the names server for the server and client1 for the client):

cd ~/openvpn-ca
source vars
./clean-all

# This step will ask for some details - if in a hurry just use the defaults
./build-ca

# This step will also ask for some details - if in a hurry just use the defaults
# Answer y to sign the certificate and y to commit
./build-key-server server

./build-dh
openvpn --genkey --secret keys/ta.key

# This step will also ask for some details - if in a hurry just use the defaults
# Answer y to sign the certificate and y to commit
./build-key client1

Copy the files to the OpenVPN configuration directory and generate a server configuration file:

cd ~/openvpn-ca/keys
sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf

OpenVPN setup

Edit the /etc/openvpn/server.conf file. The following lines give the changes only:

# Clients should redirect traffic through the VPN
push "redirect-gateway def1 bypass-dhcp"

# DNS servers (Google)
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4" 

# Use the certificate and key direction for server
tls-auth ta.key 0
key-direction 0

# Ciphers
cipher AES-128-CBC 
auth SHA256

# Reduce privileges
user nobody
group nogroup

Restart the OpenVPN service:

sudo systemctl restart [email protected]
sudo systemctl status [email protected]

If it fails with the error:

Nov 22 19:51:42 efault ovpn-server[13750]: library versions: OpenSSL 1.0.2g  1 Mar 2016, LZO 2.08
Nov 22 19:51:42 efault ovpn-server[13750]: daemon() failed or unsupported: Resource temporarily unavailable (errno=11)
Nov 22 19:51:42 efault ovpn-server[13750]: Exiting due to fatal error

A possible solution is to edit the /lib/systemd/system/[email protected] file and comment out the line:

#LimitNPROC=10

And restart the OpenVPN service again:

sudo systemctl daemon-reload
sudo systemctl restart [email protected]

NAT

If you have no other iptables rules, you can enable NAT with:

sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE

If you already have existing rules, you may need a more complicated setup.

If you want the rule to persist through reboots, you can use iptables-persistent (the first save of rules.v4 may happen during install, so the second line below may not be necessary):

sudo apt install iptables-persistent
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Client setup

Create a base client configuration:

mkdir ~/openvpn-ca/client
chmod 700 ~/openvpn-ca/client
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn-ca/client/base.conf

Edit the ~/openvpn-ca/client/base.conf file. The following lines give the changes only:

# Fill out the server address and the port (1194 if default)
remote <server> <port>

# Reduce privileges
user nobody
group nogroup

# Comment out the following lines
#ca ca.crt
#cert client.crt
#key client.key

# Key direction 1 for client and ciphers that match the server configuration
key-direction 1
cipher AES-128-CBC
auth SHA256

Run the following to insert the certificate files into the final configuration file:

cd ~/openvpn-ca/client
cat base.conf > client1.ovpn
echo -e '<ca>' >> client1.ovpn
cat ../keys/ca.crt >> client1.ovpn
echo -e '</ca>\n<cert>' >> client1.ovpn
cat ../keys/client1.crt >> client1.ovpn
echo -e '</cert>\n<key>' >> client1.ovpn
cat ../keys/client1.key >> client1.ovpn
echo -e '</key>\n<tls-auth>' >> client1.ovpn
cat ../keys/ta.key >> client1.ovpn
echo -e '</tls-auth>' >> client1.ovpn

Android setup

I use the OpenVPN Connect app on Android. Transfer the client1.ovpn file to your Android device e.g. by email. Select the OVPN Profile option or open the menu and select Import Profile. Find and select the client1.ovpn file and press Import, change the title if wanted and press Add.

When the profile is activated, traffic should now flow through the VPN. You can test this by visiting a website that shows your IP address.