Sunday 19 July 2015

Using a Raspberry PI as a VPN Server

Having toyed with the idea for a while of setting up a VPN server at home, I was finally inspired to actually do something about it when I watched Kate Russel on BBC Click talk about how she'd set up such a system using a Raspberry PI. Deciding to strike while the iron was hot, I took advantage of my Amazon Prime membership and ordered a Raspberry PI for next day delivery.

Arriving before 0930 Sunday morning, I immediately unpacked it and set about following the instructions in the article. What follows is a few things that tripped me up a bit / weren't immediately obvious to me, split out into sections with the same names as the ones in the article.

Install Raspbian on your Rasberry Pi

A minor detail, but since the instructions don't include attaching a mouse, it isn't necessarily obvious how to "choose Raspbian and click install". To do so, use the arrow keys to highlight the Raspbian option, press the Enter key to select it and then press the i key to begin installation.

Once installed, upon booting up for the first time, a configuration screen is shown. I used this to enable SSH so that I would be able to administer the box without needing to leave a keyboard connected.

Give your Raspberry Pi a static IP address

It's not necessary to run the ifconfig command with sudo. However, the reboot command at the end does require it.

There's a slight mismatch between the names of the values referenced in the article and how they're actually displayed in the output of the ifconfig command:

Name in article Name in ifconfig output
Current IP Address inet addr
Broadcast Range Bcast
Subnet Mask Mask

The line that the article states is "iface eth0 inet dhcp" was actually "iface eth0 inet manual" in my file.

When running "sudo nano etc/network/interfaces" there is a missing leading slash; the command should be "sudo nano /etc/network/interfaces". When editing the file, although I'm not sure if it's actually necessary, the address, netmask, network, broadcast and gateway lines are usually indented under the "iface eth0 inet static" line (at least in most of the examples I found on the web).

Set up an easy control system

I used a Mac to connect to the PI over SSH, so I didn't need to install a separate SSH client. I did, however, need to connect as the pi user (by default, ssh will try and connect using the username of the current user on the Mac). This was done by entering the command:

ssh pi@[ip-address-of-my-pi]
from the command prompt on my Mac.

Update your Raspberry Pi

A very minor thing that might confuse inexperienced users, is that when running the "sudo apt-get upgrade" command, it will display how much extra space will be taken up (in my case it was actually less space!) and ask if you wish to continue. To continue, simply press the y key followed by the Enter key.

Similarly, when running the "sudo apt-get install openvpn" command, press the y key followed by the Enter key when asked if you wish to continue.

Build keys for each user

After choosing to sign the certificate, it asks "1 out of 1 certificate requests certified, commit? [y/n]", press the y key followed by the Enter key.

After running "openssl rsa -in KateAndroid.key -des3 -out KateAndroid.3des.key", the pass-phrase for the .key file is the one previously entered when running the build-key-pass command (so ignore the note about making it one you can remember), the next one is a new one for the .3des.key file.

Generate the Diffie-Hellman key exchange.

Just as a warning, when running the build-dh command, I kicked it off from an ssh session on my Mac. I then went away to do other stuff whilst waiting for the command to complete. When I came back an hour or so later, however, it appeared to not have completed, nor be progressing. I hit the Enter key and received the following message:


Write failed: Broken pipe
I decided to start it again, but this time directly on the PI (by connecting a keyboard and monitor to it). It actually completed pretty quickly the second time, so I guess the progress it had made from the first run got saved; thankfully I didn't have to wait another hour or so.

Ensure you have a static public IP address

I tried to sign up for an account with DNS Dynamic, as per the article; however, despite trying a couple of different email addresses, I never received a confirmation email and was unable to log in with the credentials I used on the sign-up page. I ended up going with an alternative dynamic DNS provider - ChangeIP.

When I ran the "sudo apt-get install ddclient" command, it launched a wizard for configuring ddclient. Unfortunately, it was unclear what options to choose in the wizard and I could find nothing on the ChangeIP website to help me. Fortunately, someone had already figured out how to configure OpenVPN to work with ChangeIP, so after choosing some options using the wizard (that turned out to be mostly correct), I edited my /etc/ddclient.conf file as per this blog post.

The ddclient command should be run with sudo: sudo ddclient

Create profile scripts for the devices you want to connect

When editing the files in this section, nano should be preceded with sudo, e.g. "nano /etc/openvpn/easy-rsa/keys/Default.txt" should be "sudo nano /etc/openvpn/easy-rsa/keys/Default.txt".

For the creation of the Default.txt file, [YOUR PUBLIC IP ADDRESS] should be replaced with your dynamic DNS value (e.g. [your-chosen-subdomain].dynamic-dns.net), not an IP address.

When creating the MakeOVPN.sh file, there are two lines that should actually be a single line:


#Ready to make a new .opvn file - Start by populating with the
default file
(The above two lines should be a single line.)

Export your client keys for use on the connecting devices

I would not recommend running the command "chmod 777 -R /etc/openvpn" followed by "chmod 600 -R /etc/openvpn". Once complete, this will end up with all files and directories under /etc/openvpn having read and write permission only by the file/directory owner. This means that all the scripts will no longer be executable. In my case, I was able to use the scp command to copy the .ovpn file, after having granted permission to read the file itself and all parent directories.


# Run from a command prompt on the Raspberry PI
chmod 777 /etc/openvpn
chmod 777 /etc/openvpn/easy-rsa
chmod 777 /etc/openvpn/easy-rsa/keys
chmod 777 /etc/openvpn/easy-rsa/keys/[ClientName].ovpn

# Run from the computer you wish to download the file to
scp pi@[ip-address-of-your-pi]:/etc/openvpn/easy-rsa/keys/[ClientName].ovpn [ClientName].ovpn

Install the OpenVPN Connect app on your device

When importing the key, the PEM pass-phrase that is needed is the one used when creating the 3des.key file.

One more thing

After all this was done, my phone still couldn't connect to the OpenVPN server. I then realised that although I'd followed the instructions to open up the firewall on the PI itself, I hadn't done anything about the firewall on my router. Once I updated my router to do port-forwarding of port 1194 to the PI, everything worked swimmingly!