OpenVPN On The Raspberry Pi

In this blog post we will look at creating a VPN on a Raspberry Pi. So why use a VPN well if you travel a lot, or live outside your home country, or if your like me and don’t want to miss your country annihilate the opposition at Rugby, are security conscious, or would like to keep your IP address located in your home country, using a VPN is a viable option. Even better hosting your VPN on a Raspberry Pi offers a cheap and efficient solution when compared to other options.

In this post we will perform the following tasks:

  • Setup a VPN server on our home network connecting the Raspberry PI to our home router.
  • Install Arch Linux as the Raspbery Pi operating system.
  • We will install OpenVPN to create our secure VPN Server.
  • We will use Netcfg to manage the network adapters.
  • Use bridge-utils to bridge the VPN and the Ethernet adpater.
  • Use SSH for secure remote access to our Raspberry Pi.
  • We also use the No IP service that will provide us with dynamic DNS daemon that will provide us with a domain name that points to our routers IP address so we can access our VPN from anywhere.

Setup Arch Linux On The Raspberry Pi

The first thing we are going to do is setup our Raspberry Pi with an operating system.

Download Arch Linux Distribution

The first thing we need to do is install Arch Linux on the Raspberry Pi. So firstly head over to the arch linux downloads page and download the latest version of arch linux.

1
https://www.archlinux.org/download/

Prepare the SD Card

Next we need to insert the SD card into the SD card drive and find the card name using the lsblk command.

1
lsblk

After running the command you should see output similar to the below:

1
2
3
4
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
...
sdc           8:16   1  59.6G  0 disk
...

In the above output the name of the SD device is /dev/sdc but this can be different on your system. Next we will use parted utility to format the drive and create the required partitions. Firstly create the partition table by running the command :

1
sudo parted /dev/sdc --script -- mklabel msdos

Next run the command to create the partitions:

1
sudo parted /dev/sdc --script -- mkpart primary fat32 1 128sudo parted /dev/sdc --script -- mkpart primary ext4 128 100%

Next add the bootable flag to the boot partition:

1
sudo parted /dev/sdc --script -- set 1 boot on

Next to confirm that everything is setup correctly we will print the partition table to the console:

1
sudo parted /dev/sdc --script print

The output should look something like:

1
2
3
Number  Start   End     Size    Type     File system  Flags
 1      1049kB  128MB   127MB   primary               boot, lba
 2      128MB   64.0GB  63.9GB  primary

Next we will format the boot partition to FAT32:

1
sudo mkfs.vfat -F32 /dev/sdc1

Next we must format the root partition:

1
sudo mkfs.ext4 -F /dev/sdc2

Install Arch Linux

Now that the SD card is setup we need to start the installation process of Arch Linux. First we will need to mount the partition and copy the distribution files.

First we will create the directories that will serve as the mount points.

1
sudo mkdir -p /mnt/arch/{boot,root}

Next we will mount the partitions:

1
2
sudo mount /dev/sdc1 /mnt/arch/boot
sudo mount /dev/sdc2 /mnt/arch/root

Next use the tar command to extract the contents of the Arch Linux distribution to the /mnt/arch/root directory:

1
sudo tar -xf <ARCH_LINUX_DISTRIBUTION> -C /mnt/arch/root

Next we need to move the boot files to the mounted boot partition.

1
sudo mv /mnt/arch/root/boot/* /mnt/arch/boot

Next unmount the partitions:

1
sudo umount /mnt/arch/boot /mnt/arch/root

Booting the Raspberry Pi

To boot the Raspberry PI put the SD card into the Pi and plug in any peripherals such as keyboard, monitor etc. Next login to your Raspberry Pi using the user root and the password root. Once logged in you can change your password etc, but for the purposes of this tutorial we will leave them as root.

Finally you will want to initialize the package manager and update the system.

1
2
pacman-key –init
pacman-key --populate archlinuxarm

Setup OpenVPN On Arch Linux

Login To The Raspberry Pi

If you haven’t already done so please login to the Raspberry Pi using the user root and the password root.

Update Arch Linux

Next we will ensure our system is current by executing a system update.

1
pacman -Syu

Install Packages

Next we will install some of the packages that we will use in this post. Run the following commands:

1
pacman -S noip netcfg bridge-utils openvpn

Answer y to any prompts that you may encounter. Once the above packages are installed we will configure the network.

Configure The Network

We need to configure a client to site bridge because we will be connecting the VPN client to the servers network. Therefore, the servers subnet must be different from the clients subnet. For example the network subnet at your home could be 192.168.1.0/24. If the subnet of the server has the same subnet 192.168.1.0/24 the network would have problems routing traffic because it would not know if the network address was referring to the home network or the VPN server.

In this case we must ensure that the home network and the VPN are on different subnets. For this reason it is recommend to pick a non standard subnet. You should we able to change your home subnet by configuring your home router with a non standard subnet so it does not matter what the servers subnet is. However, you still might want to change the servers subnet as you may want to connect from a public Wi-Fi that uses a standard subnet. It is recommend to change your servers subnet by picking a /24 subnet which has the subnet mask:

1
255.255.255.0

in one of the private address ranges:

  • 10.0.0.0 – 10.255.255.255
  • 172.16.0.0 – 172.31.255.255
  • 192.168.0.0 – 192.168.255.255

Next we will setup a static IP for the VPN server running on the Raspberry Pi. Setting up a static IP has the advantage that you will always know where to access your Raspberry PI when you need to access it remotely. In order to do this we will use the Arch Linux netcfg command to manage our network connections. We will need to setup three different network connections:

  • A VPN tap adapter
  • Ethernet handled by the bridge adapter
  • Bridge adapter to combine the previous two

First we need to change the directory:

1
cd /etc/network.d

Next we need to open a new file name bridge:

1
nano bridge

With the file bridge opened enter the network configuration below changing the network settings with your own:

1
2
3
4
5
6
7
8
9
INTERFACE=”br0”
CONNECTION=”bridge”
DESCRIPTION=”VPN Bridge Connection”
BRIDGE_INTERFACE=”eth0”
IP=”static”
ADDR=’192.168.1.220’
NETMASK=’24’
GATEWAY=’192.168.1.254’
DNS=(‘192.168.1.254’)

One you have entered the above interface save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X.

Next we need to configure the profiles netcfg will load by editing /etc/conf.d/netcfg.

1
nano /etc/conf.d/netcfg

Add or change the NETWORKS array to:

1
NETWORKS=(bridge)

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X. Next we will run the commands to disable DHCP. We will also enable the ethernet interface and the bridge with a static IP.

1
2
systemctl disable dhcpcd@eth0.service
systemctl enable netcfg.service

Now restart the Pi for the changes to take effect. When the Raspberry Pi comes back up login with SSH using the password root unless you changed it:

1
ssh root@<PI_IP_ADDRESS>

Next change your root password using the passwd command picking a secure password.

1
passwd

You can also change the host name of your VPN server by editing the /etc/hostname file. This is a good idea to make it easier to identify the server.

VPN Public Key Infrastructure

Next we are going to setup the public key infrastructure using a certificate to authenticate OpenVPN. We will generate a certificate and a private key that you should keep private for each client. The certificate and the key are used to encrypt the traffic sent between the client and the VPN server. First we need to copy the scripts to /etc/openvpn.

1
2
cp -r /usr/share/openvpn/easy-rsa/ /etc/openvpn
cd /etc/openvpn

Next we are going to create a template to base our certificate on.

1
nano vars

Change the lines at the end of the file to something like:

1
2
3
4
5
6
7
8
export KEY_COUNTRY=”IE”
export KEY_PROVINCE=””
export KEY_CITY=”Dublin”
export KEY_ORG=”Home”
export KEY_EMAIL=”stephen@vpn.myhome.org”
export KEY_CN=”stephenvpn-ca”
export KEY_NAME=”stephenvpn-ca”
export KEY_OU=”None”

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X, then export the variables:

1
source ./vars

Next clean any previous configuration:

1
./clean-all

Next we will create the certificates. First we will generate the authority certificate that we will use to sign the rest.

1
./build-ca

Next we will generate the server certificate using the server host name.

1
./build-key-server <SERVER HOST NAME>

If asked for any information press enter, and don’t fill in a password or company name. Also, accept the request to sign the certificate. Next we will generate the Diffe-Hellman parameters needed to allow the exchange of a secret key.

1
./build-dh

Next you must generate a certificate for each client that you would like to connect to OpenVPN. In this case we will generate a key for stephen’s laptop.

1
./build-key stephen-laptop

OpenVPN Server Configuration

Next we will configure the OpenVPN Server.

1
cp /usr/share/openvpn/examples/server.conf /etc/openvpn/server.conf

Above we copy an example server configuration that we will configure below:

1
nano /etc/openvpn/server.conf

Make the following changes to the file by changing:

1
2
;dev tap
dev tun

to:

1
2
dev tap0
;dev tun

We make the above changes because we want to use a tap adapter which allows us to bridge the network rather than creating a tunnel. Next replace the certificates that you created.

1
2
3
4
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh1024.pem

With the ones we created which is something like:

1
2
3
4
ca /etc/openvpn/easy-rsa/keys/ca.cert
cert /etc/openvpn/easy-rsa/keys/stephenvpn.crt
key /etc/openvpn/easy-rsa/keys/stephenvpn.key
dh /etc/openvpn/easy-rsa/keys/dh1024.pem

Also comment out the line by place a semicolon in front of it:

1
server 10.8.0.0 255.255.255.0

to:

1
;server 10.8.0.0 255.255.255.0

Also uncomment the below line as we want to use a ethernet bridge rather than a regular server.

1
server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100

Also after you uncomment the above line you need to change the values to match your servers configuration, fill in the appropriate values replacing the placeholders.

1
server-bridge <Server IP> <Server Subnet Mask> <Server Start Ip Range>  <Server End IP Range>

Finally uncomment the lines:

1
2
;user nobody
;group nobody

to

1
2
user nobody
group nobody

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X.

Configure The Tap Interface

Next we will configure the Tap interface.

1
nano /etc/network.d/tap

Add the following lines to the file:

1
2
3
4
5
INTERFACE=’tap0’
CONNECTION=’tuptap’
MODE=’tap’
USER=’nobody’
GROUP=’nobody’

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X. Next we need to configure our bridge with the tap interface.

1
nano /etc/network.d/bridge

Change the bridge interfaces line to look like:

1
BRIDGE_INTERFACES=”eth0 tap0”

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X. Next we need to configure netcfg.

1
nano /etc/conf.d/netcfg

Change the NETWORKS variable to:

1
NETWORKS=(tap bridge

Save the file using Ctrl + O followed by Enter and then exit nano using Ctrl + X.

Enable OpenVPN

Next we must enable OpenVPN:

1
systemctl enable openvpn@server

Now reboot the Raspberry Pi and make sure that everything starts up as expected.

Configure Dynamic DNS

Now that the OpenVPN server is configured we will now configure Dynamic DNS so we can access our VPN server from anywhere using a easy to remember domain name. Go to the no-ip website and create an account for the No-IP free option.

1
www.no-ip.com/personal

Once you have activated your account by clicking the link in the sign up email that you will receive from no-ip, login to your no-ip account and add a new host. You must choose a host name and a domain. Select the host type as DNS Host and the click the create host button. For example I entered the host name stephen-home with the domain no-ip.org so that I can access the VPN server from stephen-home.no-ip.org.

With are account created we now need to configure the no-ip daemon on our Raspberry Pi. The no-ip daemon will update the no-ip account we created in the last step mapping the router IP address to the domain name we created with the no-ip service. From the command line on our Raspberry Pi enter:

1
noip2 -C -Y 

This will start the interactive configuration. In my case I left the update interval at 30 minutes which means the no-ip daemon will push the VPN Server public IP address every 30 minutes to the no-ip account. Once you have completed the configuration steps we must start the daemon.

1
/etc/rc.d/noip start

After a couple of minutes the VPN public IP address will be accessible from the no-ip host name.

Configure NAT Port Forwarding

Next we need to configure NAT port forwarding to allow your devices behind your router to share the same IP4 address, and also it is more secure to segregate your home network from the Internet. NAT works by forwarding a port from the routers external IP address to a device on the LAN. What we want to do is forward port 22 used for SSH that comes to the routers external IP address to the Raspberry Pi. We will also forward UDP port 1194 as this is used by OpenVPN. To configure port forwarding you will have to use your routers configuration which will depend on the router that you are using.

Configure A VPN Client

I am currently using Ubuntu so I will setup an Ubuntu client to connect to the OpenVPN server running on the Raspberry Pi.

1
2
sudo apt-get update
sudo apt-get install network-manager-openvpn-gnome

Once the OpenVPN client is installed we need to copy the certificates that we created for stephens laptop in a previous step. We will use SCP to copy the files into /etc/openvpn/keys directory

1
2
3
4
5
6
7
cd /etc/openvpn
sudo mkdir keys
cd keys
sudo scp root@[IP Address Of Pi]:/etc/openvpn/easy-rsa/keys/ca.cert .
sudo scp root@[IP Address Of Pi]:/etc/openvpn/easy-rsa/keys/stephenlaptop.cert .
sudo scp root@[IP Address Of Pi]:/etc/openvpn/easy-rsa/keys/stephen-laptop.key .
sudo chmod +r *

Next we create the VPN connection by clicking on the Network Icon on the top menu bar of Ubuntu. Click on Edit Connections, then click on the VPN tab and click add. Select OpenVPN as a connection type and the click create, and fill in the appropriate information.

We also need to set the advanced settings, so set:

  • use a tap device
  • use LZO data compression

Finally, set the option to “Use this connection only for resources on its network”. To do this you must go to the IPv4 Settings tab and click on the Routes button. Tick the box with the option “ Use this connection only for resources on its network” and save your connection and close the network connections dialog.

Now you can connect to your VPN server, by clicking on the Network Icon in the top menu bar of Ubuntu then hover over VPN connections and select the VPN connection that you just created.