Create a VPN with the Raspberry Pi
The Raspberry Pi is cheap enough to leave on a network you’d like to connect to remotely, so let’s learn how to set it up to do just that…
One possible scenario for wanting a cheap server that you can leave somewhere is if you have recently moved away from home and would like to be able to easily access all of the devices on the network at home, in a secure manner. This will enable you to send files directly to computers, diagnose problems and other useful things. You’ll also be leaving a powered USB hub connected to the Pi, so that you can tell someone to plug in their flash drive, hard drive etc and put files on it for them. This way, they can simply come and collect it later whenever the transfer has finished.
We’ll be using Arch Linux as the operating system for our VPN server, since it is lightweight and has only the minimum packages required for a working system. If it’s been a while since you’ve used Arch Linux, the distro has recently moved to a new service management framework called systemd, so it’ll be good to get up to speed on that also.
Our VPN server will be made up of the following software components:
Base Arch Linux system
OpenVPN – the software we will use to create a secure VPN
Netcfg – used to easily manage the multiple network adapters we’ll need
Bridge-utils – used to bridge the VPN and Ethernet adaptors
SSH – will provide secure remote access to the Raspberry Pi and the files on it
A dynamic DNS daemon (No-IP) – software that runs in the background and points a domain name to your router’s IP address, meaning that you can access your Raspberry Pi from anywhere using an easy-to-remember web address.
This tutorial assumes that you have flashed the latest Arch Linux ARM image to an SD card. If you haven’t, the instructions for flashing an image can be found on our tutorial. You’ll only need to go up to the step where you write the image to the SD card. You’ll have to adapt the instructions slightly for using the Arch Linux image rather than the Debian one.
A Raspberry Pi with all necessary peripherals.
An SD card containing the latest Arch Linux image for the Raspberry Pi
A second computer to be used as a VPN client – we’ll assume you’re using a popular Linux distribution that uses Network Manager, like Debian
Step by Step
Logging into Arch Linux
Connect the necessary cables to the Pi and wait for the Arch Linux login prompt. The login is ‘root’, and the password is also ‘root’. We’ll change the root password from the default later on.
Run a full system update
Arch Linux runs on a rolling release schedule, meaning that there are no version numbers and software is continually updated. The package manager in Arch Linux is called pacman. Use the command ‘pacman -Syu’ to start a full system update. If for some reason the update fails, try running ‘pacman -Syu’ again. Sadly, the Arch Linux ARM servers tend to be quite busy. There may be a lot of packages to update so it may take a while, especially because the Pi runs from an SD card.
Install the required packages
Use the command:
pacman -S noip netcfg bridge-utils openvpn
to install the required packages mentioned at the start of the article. Answer ‘y’ to any prompts you may encounter.
A word about subnets
One thing to note here is that because we’re setting up a client-to-site bridge, we’ll be connecting the client to the server’s network. This means that the subnet that the server is on needs to be different from the client subnet. For example, the subnet at your advisor’s home is 192.168.1.0/24, and the subnet here is 172.17.173.0/24. If the subnet here was 192.168.1.0/24, then there would be a routing conflict because the machine won’t know if you’re referring to a local address or one on the VPN. It’s a good idea to have a non-standard subnet for this reason. In our case, the client subnet is non-standard so it doesn’t matter what the server subnet is for now. However, we’re still going to change the server subnet at some point because you may end up needing to connect from a network such as public Wi-Fi, which may use a standard subnet. If you need to change your server subnet, we suggest picking a /24 subnet (subnet mask 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
You should be able to easily change your network configuration on your wireless router’s settings page.
Investigate your network
We highly recommend assigning a static IP to your server Raspberry Pi rather than being handed one by your router because you’ll always know where to find it on the network, which will be useful for accessing it remotely. You’ll also need a static IP if you want to access the Raspberry Pi from the internet. We’ll need to find out a couple of things about your current network setup before setting a static IP. You can use the commands ‘ifconfig eth0’ and ‘ip route show’ to do this.
Set up a static IP address
Now that we have found out things about your network, such as your current IP address, the network mask and so on, we can set up a static IP address. We’re going to use the Arch Linux netcfg framework to manage our network connections as we’ll need three different connections eventually: Ethernet, which is automatically handled by the bridge adaptor; a VPN tap adaptor; and a bridge adaptor to combine the two.
Change directory to the /etc/network.d directory and open a new file called bridge in nano (or the text editor of your choice):
cd /etc/network.d nano bridge
Then fill in the bridge configuration to look as follows and save the changes (swapping our network values for your own):
INTERFACE=“br0” CONNECTION=“bridge” DESCRIPTION=“VPN Bridge connection” BRIDGE_INTERFACES=“eth0” IP=‘static’ ADDR=‘192.168.1.215’ NETMASK=‘24’ GATEWAY=‘192.168.1.254’ DNS=(‘192.168.1.254’)
Once done, save the file using Ctrl+O followed by Enter, then exit nano using Crl+X. We’ll add the VPN adaptor to the bridge later on.
We now need to configure what profiles netcfg should load by editing /etc/conf.d/netcfg and configuring the networks array as follows:
Save the changes, exit nano and then run the following commands to disable DHCP and enable the Ethernet interface and the bridge with a static IP permanently:
systemctl disable dhcpcd@eth0. service systemctl enable netcfg.service
You can now restart the Pi for the changes to take effect.
Log in with SSH
Once the Pi has booted back up, open a terminal on your Linux computer and type ‘ssh root@[IP of your pi]’. Answer yes, to say that you want to connect, and type in the root password, which will still be root. You are now logged in over SSH.
Change the root password
Since we will probably be exposing an SSH login to the internet, it would be a very good idea to change the password to something much more secure. Type ‘passwd’, then follow the on- screen instructions to change your password. Your SSH session will stay logged in, but you’ll need to use the new password next time you log in. You may also want to change the contents of /etc/hostname to set the hostname to a self- identifying name, such as ‘vpnserver’ rather than the default ‘alarmpi’. The change won’t take
place until after a restart.
Set up the public key infrastructure variables
We’re going to be using a certificate infrastructure to authenticate OpenVPN. This is where a certificate and private key (which must be kept a secret) is generated for each client, and signed by the certificate authority. Only clients with signed certificates are allowed to connect. The key and certificate are used to encrypt the data sent between the client and the server. This secure approach means that additional username and password authentication on the client is not necessary. There are a bunch of scripts which make setting this up easy. Start by copying the scripts to /etc/openvpn with:
cp -r /usr/share/openvpn/easy-rsa/ /etc/ openvpn
and then change to that directory.
We’re going to be making a template to base our certificates on. Edit the vars file with nano and change the following lines at the bottom of the file from something like:
export KEY_COUNTRY=“US” export KEY_PROVINCE=“CA” export KEY_CITY=“SanFrancisco” export KEY_ORG=“Fort-Funston” export KEY_EMAIL=“firstname.lastname@example.org” export KEY_EMAILemail@example.com export KEY_CN=changeme export KEY_NAME=changeme export KEY_OU=changeme
export KEY_COUNTRY=“UK” export KEY_PROVINCE=“” export KEY_CITY=“Ormskirk” export KEY_ORG=“Home” export KEY_EMAIL=“firstname.lastname@example.org” export KEY_CN=“liamvpn-ca” export KEY_NAME=“liamvpn-ca” export KEY_OU=“None”
Once you have saved the changes, export the variables with:
and then clean any previous configuration with:
Create the certificates
Start by generating the certificate authority certificate, with which we will sign everything else (press Enter to leave fields set as they are):
Following that, we want to generate a server certificate with:
./build-key-server [server hostname]
Press Enter when asked for any information, don’t fill in a password or company name and accept the request to sign the certificate.
We now need to generate the Diffie–Hellman parameters, needed to allow two users to exchange a secret key over an insecure medium using the Diffie–Hellman key exchange protocol (this may take a couple of minutes):
The final step is to generate a certificate for each client that you would like to connect to the VPN. In this case, our client is a laptop.
Simply do what you did during the build- key-server script and then you’ll have all the certificates you need.
Configure the OpenVPN server
We’re going to base our configuration file on the example server configuration file using the command ‘cp /usr/share/openvpn/ examples/server.conf /etc/openvpn/server.conf.’
Open /etc/openvpn/server.conf in nano. Start by changing:
;dev tap dev tun
dev tap0 ;dev tun
because we are using a network tap adaptor which allows us to bridge the networks, rather than create a tunnel.
Replace the certificates here with the ones you created:
ca ca.crt cert server.crt key server.key # This file should be kept secret dh dh1024.pem
In our case, the configuration looked like:
ca /etc/openvpn/easy-rsa/keys/ca.crt cert /etc/openvpn/easy-rsa/keys/liamvpn. crt key /etc/openvpn/easy-rsa/keys/liamvpn. key dh /etc/openvpn/easy-rsa/keys/dh1024.pem
Comment out the line:
server 10.8.0.0 255.255.255.0
by placing a semicolon in front of it because we want an Ethernet bridge rather than a regular server. To enable the Ethernet bridge, uncomment the line:
server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
Then change the values to match your server’s network configuration. The first is the server’s IP address; the second is the subnet mask. The
last two values are the start and end ranges of IP addresses allocatable to connecting clients.
Finally, uncomment the lines:
;user nobody ;group nobody
to give OpenVPN the least privileges possible and then save the changes to the file.