How to install OpenVPN on Raspberry Pi

I recently had an SD card on my raspberry pi hosting my VPN corrupt, so I figured I would make a post about my process for reinstalling OpenVPN on Raspbian Stretch.

Our first step is to download the OpenVPN installation files. The most recent version can be found here. As of writing this guide, the most recent version is 2.4.6. Also, I am mostly following the official OpenVPN install guide, so if you run into any issues check there.

  • cd /opt/
  • (sudo) wget
  • tar xfz openvpn-2.4.6.tar.gz
Next, we need to install a few dependencies for OpenVPN.

  • sudo apt-get install libssl-dev liblzo2-dev libpam0g-dev -y
Once those finish installing, we'll navigate to the newly created openvpn-2.4.6 directory and begin the install process. This process might take a good minute so just sit back and watch the magic work before your eyes.

  • cd openvpn-2.4.6
  • sudo ./configure
  • sudo make
  • sudo make install
One of the biggest reasons I wanted to setup OpenVPN vs. using PiVPN was to create working certificates so I can verify that I am actually connecting to my home network, so we are going to set up a root certificate authority that can sign client certificates now.

The tool we are going to use for that is called Easy-RSA. As of writing this post, Easy-RSA is on version 3.0.5. A link to their releases can be found here.

  • sudo wget
  • sudo tar xfz EasyRSA-nix-3.0.5.tgz
  • cd EasyRSA-3.0.5
Now that we are in the EasyRSA directory lets set that up. We will create a file called vars where you need to uncomment and fill in the KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL parameters with your own data. This file will be used to build the Public Key Infrastructure.
  • sudo cp vars.example vars
  • sudo nano vars
Now that we have that file made, we need to build the certificate authority so that we can sign our certificates. When building the CA, it will ask you for a common name. Just make this something you will recognize like [YOURDOMAIN] VPN-CA You will also need to set a secure password for the CA key file.
  • sudo ./easyrsa init-pki
  • sudo ./easyrsa build-ca
Once the certificate authority is built we must generate the server certificate. From what I have read, most people recommend not setting a password on the server certificate files, which is especially true since we need to run OpenVPN in the background as a daemon once we are finished. Anyway, let's generate the server certificate.
  • sudo ./easyrsa build-server-full [SERVERNAME] nopass
Now we'll generate a client file. Client certificates should really have a secure password.

  • sudo ./easyrsa build-client-full [CLIENTNAME]
We now need to build a Diffie Hellman key. This step will absolutely take the longest. DH keys take quite a bit of processing power to create, and we are setting this up on a raspberry pi which doesn't have very much. If I remember correctly it took me like 20 minutes to complete, so go turn on The Office and let this do its thing...
  • sudo ./easyrsa gen-dh
Once that's finished, we need to generate a TLS-Auth key. This file needs to be fairly well protected, so we need to log in as root so that we can access the correct folders.
  • su
  • cd /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/private/
  • openssl --genkey --secret ta.key
  • exit

Now that all of our certificates are generated, we need to create the configuration files. First, we will create the server configuration file. 
  • cd /opt/openvpn-2.4.6/
  • sudo nano server.conf
Paste the following into your server.conf:

port 1194
proto udp
dev tun
ca /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/ca.crt
cert /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/issued/[SERVERNAME].crt
key /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/private/[SERVERNAME].key  
dh /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/dh.pem
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS [YOURDNSSERVER]"
push "dhcp-option DNS [YOURDNSSERVER]"
keepalive 10 120
tls-auth /opt/openvpn-2.4.6/EasyRSA-3.0.5/pki/private/ta.key 0
cipher AES-256-CBC
user nobody
group nogroup
status openvpn-status.log
verb 3
explicit-exit-notify 1

That should do it for the server configuration. Now we'll move onto the client configuration.
  • sudo nano [CLIENTNAME].conf
Paste the following into your server.conf. We will use inline certificate files to make importing the client configuration much easier on other devices. You will need to paste your own certificates where there are the X's. The ca tags correspond to ca.crt, the cert tags correspond to [CLIENTNAME].cert, the key tags correspond with [CLIENTNAME].key, and the tls-auth tags correspond to ta.key.:

dev tun
proto udp
resolv-retry infinite
remote-cert-tls server
key-direction 1
# 2048 bit OpenVPN static key
-----BEGIN OpenVPN Static key V1-----
-----END OpenVPN Static key V1-----
cipher AES-256-CBC
verb 3

 Forward the proper port on your router (default is 1194) and then start up the OpenVPN service for our first test. We are only going for a successful connection on this go-around.

  • sudo openvpn --config /opt/openvpn-2.4.6/server.conf
Find another device to test with, securely copy the [CLIENTNAME].conf to it, and then connect to the OpenVPN server. If everything is done correctly, it should have connected. If it did not work, check the log files on the client and server to see if there is anything weird going on. 

Anyway, the show must go on. At the moment you should not have internet access on the client device, and that's because we have not set any iptables rules yet to allow our OpenVPN client traffic to NAT behind the actual server IP. A helpful resource can be found here.
  • sudo iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE
  • sudo sysctl -w net.ipv4.ip_forward=1
Now, with these rules set your clients should have internet access BUT iptables does not automatically save rules between reboots, so we need to save it by installing iptables-persistent. It should ask you if you want to save any rules you have already set, to which you should say yes.
  • sudo apt-get install iptables-persistent
Now everything should be fully functioning. You can test your config one last time to make sure all is good, then we will let it run in the background. To view the log files now, you must view /var/log/syslog.
  • sudo openvpn --config /opt/openvpn-2.4.6/server.conf --daemon
The only thing I have not yet worked out how to do is start OpenVPN on boot, but that shouldn't be too hard. :)