change line 72 by adding a # in front of the line (so you are commenting out the line)

5. The script will be owned by root. Grant it execute permissions by running the following

chmod u+rwx MakeOpenVPN.sh

6. Now execute the script using the following command. You will be asked for the name of an existing client for whom you had generated the keys and certificates for when configuring the openvpn server (for instance client1)

./MakeOpenVPN.sh

The script checks to ensure the following files exist in the folder /etc/openvpn/easy-rsa/keys

{client1}.crt
{client1}.aes256.key
ca.crt
ta.key

If any of the above files are missing, an error is displayed and the script stops.

However, if everything goes well, the following is displayed

“Done! {client1}.ovpn Successfully Created.“

and the file {client1}.ovpn is placed in the /etc/openvpn/easy-rsa/keys folder

7. Thats it folks! The client config file is now ready. Import it into your openvpn client to connect to your openvpn server. Don’t forget the password you had configured for the client when you generated the key because it will be requested everytime you try connecting to the openvpn server.

Background

Recently I got asked by a friend to recommend a good router/modem that will allow him to vpn into his home network. He was concerned about his internet traffic being eavesdropped on when he connected to a network he didn’t know much about (ah yes, he could just NOT connect to these dodgy networks I hear you say 🙂 )

Well being the good friend that I am, I pointed him to some good routers/modems however it got me thinking. Why not use a Raspberry Pi to accomplish this feat? After a bit of salesmanship, I got my friend convinced that a OpenVPN server running on a Raspberry Pi was the best solution 🙂

After placing our order for the Raspberry Pi (and the case, power adapter, sd card etc), I started researching on how I would get OpenVPN installed and configured. A quick google search revealed a lot of articles, so I felt quite confident that this task wasn’t too difficult. Well, lets just say that my opinion changed once I started the configuration! I couldn’t find any ONE blog that told me exactly what had to be done. There was always something missing and I had to do my own research to fill in that gap. And that my friend, is essentially the motivation for this blog, to provide a one stop shop for anyone trying to install/configure a OpenVPN server on a Raspberry Pi.

In this part, I will show you how to install and then configure openvpn on a Raspberry Pi. In the next blog post, I will show you how to configure the clients, so that they can connect to the openvpn server.

a static internal ip address for the Raspberry Pi. This can be easily done by reserving an ip address on your router for the Raspberry Pi

create a port forwarding rule on your router to forward all udp 1194 traffic it receives from the internet to your Raspberry Pi.

an internet routable domain name. If you don’t already own a public DNS hostname, you can use services like https://www.noip.com to get a free domain.

some means of accessing your Raspberry Pi. Initially you will need a usb keyboard and mouse and a tv screen to access it, however the latest builds of Raspbian include RealVNC server by default, so you can configure and then remotely connect to the Raspberry Pi from another computer.

Server Implementation Steps

First and foremost, we need to secure the Raspberry Pi. By default it comes with a username pi and the password for this account is set to raspberry. You can either change the default password by using sudo passwd or create a new account with the same privileges as pi and then lock/delete the pi account. The article at https://www.madirish.net/566 shows how you can create a new account and then lock pi.

Next, start a terminal session and run the following to install openvpn

4. Uncomment (remove the # prefix) the following line and save the changes

net.ipv4.ip_forward=1

5. Run the following command to make the change persistent over reboots

sudo sysctl -p

6. Next, we will setup a Certificate Authority (CA) and generate certificates and keys for the OpenVPN server and clients. For the CA, we will use easy-rsa, a PKI solution that comes bundled with OpenVPN 2.3.4.

In the terminal window, elevate the session to root privileges using the following

sudo -s

7. Then copy the easy-rsa folder to a subfolder under the openvpn folder

cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa

8. Next, modify the vars file included with easy-rsa (I am using nano to modify the file)

cd /etc/openvpn/easy-rsa
nano vars

9. Since we have copied easy-rsa to a new location, change the following line from

export EASY_RSA="`pwd`" to export EASY_RSA="/etc/openvpn/easy-rsa"

10. Scroll down and change KEY_SIZE to 2048 (if different)

export KEY_SIZE=2048

11. Going down a few more lines, you will see the default fields that will be used for the certificates. Change these to the appropriate values so that you don’t have to change it each time a certificate is generated

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

12. Save the changes and exit the text editor

13. All the prep work has now been done. Lets start with the certificate generation process. Run the following command to build the vars file

source ./vars

14. Next, remove any previously generated keys by running the following command (this will delete all contents of /etc/openvpn/easy-rsa/keys folder)

./clean-all

15. Create a Certificate Authority by running the following command and filling in the appropriate values. Press enter to accept the default values or “.” to leave them as blank. For Common Name you can enter OpenVPN-CA

16. Next, generate a server certificate and key using the following command ( For each of the requested fields, either accept the defaults by pressing Enter or leave them blank by entering “.” Also, note down the following as well

Common Name – enter the public DNS record to your server.

when asked for “A challenge password []:” enter “.” to leave it blank.

when asked for “An optional company name []:” enter “.” to leave it blank.

17. Next, run the following command to generate a certificate for {client1} where client1 is the name of a user who will be able to use openvpn.

For each of the requested fields, either accept the defaults by pressing enter or leave them blank by entering “.” The most important field is the PEM pass phrase. This is the password that the user will enter every time they establish a vpn session.

Also, when requested for

“A challenge password []:” – leave this field blank by entering “.”

“An optional company name []:” – leave this field blank by entering “.”

18. AES-256-CBC will be used as the key encryption scheme, so firstly, run the following command and check the output to ensure that your version of OpenVPN supports it

openvpn --show-ciphers

19. Next, generate an AES 256 key for {client1} using the following command (replace client1 with the name you gave your user above). You will be asked for “Enter pass phrase for {Client1}.key” – for simplicity, you can make this the same as what you had in step 17 above. Enter the same password when asked for PEM pass phrase

“The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification. Any UDP packet not bearing the correct HMAC signature can be dropped without further processing. The tls-auth HMAC signature provides an additional level of security above and beyond that provided by SSL/TLS. It can protect against:

DoS attacks or port flooding on the OpenVPN UDP port.

Port scanning to determine which server UDP ports are in a listening state.

Buffer overflow vulnerabilities in the SSL/TLS implementation.

SSL/TLS handshake initiations from unauthorized machines (while such handshakes would ultimately fail to authenticate, tls-auth can cut them off at a much earlier point).”

Using tls-auth requires the generation of a shared secret key that is used in addition to the standard RSA certificate/key. Run the following command to generate this (ensure you are in the /etc/openvpn/easy-rsa/keys folder)

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

23. Next, we will create a customised OpenVPN server configuration file. A sample server.conf file is already present. Use the following commands to copy it to /etc/openvpn folder (ensure you are already in the /etc/openvpn folder)

24. It is good practise to rename server.conf file to your servername. This differentiates it from the standard template file. In my case, I have renamed it to servername.conf. Open the servername.conf file using a text editor (I am using nano)

nano servername.conf

25. We will go through the file servername.conf and change the following items. If the items are commented out using a prefix of # or ; then uncomment them

I have read numerous places that the line ;local a.b.c.d needs to be uncommented and a.b.c.d needs to be changed to the OpenVPN server’s ip address. However, when I did that, my OpenVPN server would always error when the Raspberry Pi boots/reboots with the following error

the next line makes sure that all of the client’s traffic passes through the OpenVPN server. We will setup the OpenVPN server to handle this traffic via NAT a bit further down in this blog

push "redirect-gateway def1"

Uncomment the following line if you want the connected clients to reach each other. By default, the clients can only reach to the server

client-to-client

It is not recommended, however if you are going to have multiple clients connect to the OpenVPN server using the same certificate/key files or common names then uncomment the following. IT IS HIGHLY RECOMMENDED THAT EACH CLIENT HAVE THEIR OWN CERTIFICATE/KEY and COMMON NAME.

duplicate-cn

Update the location of the tls-auth key with the following line

tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0

ensure the cryptographic cipher is setup to the following

cipher AES-256-CBC

Next, we need to strip all permissions and privileges from the openvpn process when it runs, so that in case it gets compromised, there is no permission leak. This is done by uncommenting the following lines

user nobody
group nobody

Scroll down a few more lines and check that the following are listed in the config file

persist-key
persist-tun

Lets enable logging and ensure they are all output to /var/log folder. Change the status log line as below

status /var/log/openvpn-status.log

for the actual log file, you can either enable the log file to get rewritten every time openvpn starts or you can append to the existing log file. I personally prefer log-append. So, based on your selection, uncomment one of the following and change appropriately

log /var/log/openvpn.log
log-append /var/log/openvpn.log

Lastly, make sure the following lines are present in the config file

verb 3
explicit-exit-notify 1

save the configuration file

26. Next on the list is configuring NAT on the Raspberry Pi interface that is being used by the openvpn server. For the sake of portability, I am using wlan0 however you can use the ethernet interface (now be careful when you use the ethernet interface, on Raspberry Pi 3, it is not named something simple as eth0 but it is enx{mac-address} where mac-address is the mac-address of the interface)

Use the following line to enable NAT on the wireless interface

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

save the updated rules using the following to make it persistent

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

27. Let’s test that openvpn is happy with the configuration file. To do this, run the following command

openvpn servername.conf

check the logs at /var/log/openvpn.log to ensure you see something similar to below

28. Now that we have confirmation that the configuration is successful, the only task left is to ensure that openvpn server starts automatically every time Raspberry Pi starts. To do this, open /etc/defaults/openvpn using a text editor and add the following underneath the bunch of lines starting with AUTOSTART

AUTOSTART="servername.conf"

So, essentially, below is what you should see (the text in orange is what was added)

Woo hoo! Give your self a pat on the back for a job well done! The openvpn server configuration is now complete. I am mindful that this blog has grown to a mammoth size. I will detail the client configuration in the next blog. So off you go, have a break, a refreshing beverage if you must and come back for the client configuration 🙂