Setting Up An OpenVPN Server on the Raspberry Pi

Setting up an OpenVPN server on a Raspberry Pi (RPi) is a great way to access a home network from a remote location. In addition, it can be used to secure network communications when connecting to public Wi-Fi. Since the RPi is very low-powered compared to other computers, it is ideal for keeping running all the time. While it won’t win any performance awards, it is good enough to accomplish something like this for home users.
Requirements For This Walkthrough
Materials
- Local network
- Mac or PC
- Raspberry Pi running Raspbian “wheezy”
- HDMI Cable (*optional)
- Keyboard (*optional)
- Mouse (*optional)
- Monitor with HDMI input (*optional)
*If the Raspberry Pi is set up as a headless machine, you will not need a monitor, keyboard, or mouse–just another computer, which would be used to access it remotely over the network via SSH.
Downloads
- None
Knowledge, Skills, and Abilities
- Ability to naviagate throughout a computer OS
- Knowledge of basic computer terminology
- Ability and confidence to enter commands in the Terminal, adjusting them to suit your enviornment, if necessary
- Familiarity with core networking concepts
- Basic understanding of Public Key Infrastructure
Setting Up the OpenVPN Server
Installing OpenVPN
Install OpenVPN and OpenSSL via aptitude.
sudo apt-get update sudo apt-get install openvpn openssl
Copy Example Config Files Into the OpenVPN Folder
It is a good idea to copy the example config files to/etc/openvopn and then edit those. This way, you have a clean copy to reference if you make a mistake. It also makes more sense to have them in the same location as the other OpenVPN files.
cd /etc/openvpn sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 ./easy-rsa
Update the vars File With the Correct Path
Since you copied the files, you need to update the file to reflect the new location. Then, open the file in a text editor.
cd /etc/openvpn/easy-rsa sudo vi vars
Change the line that readsexport EASY_RSA=”`pwd`” to:
export EASY_RSA="/etc/openvpn/easy-rsa"
I also found other links online that mentioned to change the the following variables below, which are at the end of the file. When you generate the encryption keys later, this information is used. Since I was just using this for a personal VPN, I just filled it it with fictional information (although, I left the country the same).
export KEY_COUNTRY="US" export KEY_PROVINCE="Delta Quadrant" export KEY_CITY="Grid 492" export KEY_ORG="Starfleet" export KEY_EMAIL="seven@ofnine.com" export KEY_EMAIL=seven@ofnine.com export KEY_CN=raspberrypi export KEY_NAME=raspberrypi export KEY_OU=raspberrypi export PKCS11_MODULE_PATH=raspberrypi export PKCS11_PIN=1234
Initialize the Public Key Infrastructure (PKI)
Now you will tell the computer to use thevars file edited in the last section and then build the certificate authority.
cd /etc/openvpn/easy-rsa/ sudo su source ./vars ./clean-all ln -s openssl-1.0.0.cnf openssl.cnf ./build-ca
Generate the Server Certificate and Key
The server will need its own key and certificate. Each client will also need some–run the second command for each client needed, naming them appropriately:
./build-key-server servername ./build-key client1
There should now be some files in /etc/openvpn/easy-rsa/keys :
ca.crt ca.key servername.crt servername.csr servername.key client1.crt client1.csr client1.key
Generate the Diffie-Hellman
Diffie-Hellman basically allows two users to exchange a secret key over an insecure medium without any prior secrets. Generate this by running the following command (this takes a long time to complete; do not cancel it):
./build-dh
Create A Server Configuration File (server.conf) From An Example
Make a copy of the example server config file to edit. It is compressed by default, so it needs to be uncompressed and then renamed to match the server.
cd /etc/openvpn
Become the pi user again.
exit
Copy the file; unzip it; make a copy of the file with the name of your server.
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn sudo gunzip server.conf.gz sudo cp server.conf servername.conf
Modify the server.conf File to Reflect the Keys Generated in the Previous Steps
View the Settings Before Editing the File
Run the following command(s) to see the config file without all of the comments. This will print out all of the options available to set. Disabled settings are commented out by a semi-colon; simply removing the semi-colon will activate the feature (once the file is saved). Use these two commands as a reference when editing the file.
cat servername.conf | grep -v "#" | tr -s '\n' cat servername.conf | grep -v "#" | grep -v ";" | tr -s '\n'
Update the Config File With the Correct Paths to the Keys Generated in the Previous Sections
The example config file needs to be updated to reflect the paths and names chosen for the keys that were previously generated. Following the example filenames above, see below for the edits:
ca.crt should change toca /etc/openvpn/easy-rsa/keys/ca.crt
cert server.crt should change tocert /etc/openvpn/easy-rsa/keys/servername.crt
key server.key should change tokey /etc/openvpn/easy-rsa/keys/servername.key
dh dh1024.pem should change todh /etc/openvpn/easy-rsa/keys/dh1024.pem
Enable Gateway Re-direct to Allow All Traffic to Flow Through the VPN
Uncomment the line push ;”redirect-gateway def1 bypass-dhcp” . It should read:
push "redirect-gateway def1 bypass-dhcp"
Enable Client-to-client Communications (Optional)
Uncomment the line push ;client-to-client . This will allow connected VPN clients to communicate with other devices on the network. This is useful in ensuring the connection works. For example, I I used the iNet Pro app once connected on the VPN to run a network scan to verify that I was actually on my home network. The line should now read:
client-to-client
Enable IPv4 Forwarding
Uncomment the line# net.ipv4.ip_forward=1 in/etc/sysctl.conf . It should look like this when you are done.
net.ipv4.ip_forward=1
Enable Routing
In order for traffic to be routed across the pi, IP-forwarding needs to be enabled.
sudo su echo 1 > /proc/sys/net/ipv4/ip_forward exit # become the pi user again crontab -e
Add the following to end of the file and save it.
@reboot sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/8 ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
Start the OpenVPN Server on the Raspberry Pi
To make sure everything is working OK, simply start OpenVPN using the server config file. Once you know everything is working, you can set it up as a daemon to run automatically. For now, it is better to see all of the details to verify its functionality.
sudo openvpn servername.conf
If everything went well, the final output on the screen should say something like
Initialization Sequence Completed
If a client were to connect, you would immediately see details as they happen. This is a great way to test out your connection.
Start the OpenVPN Automatically When the RPi Starts
Now that the OpenVPN server is working and the settings look good, it is time to make it run as a service every time the Pi boots up. This will prevent you from having to type openvpn servername.conf and having it run in the foreground.
Edit the file /etc/default/openvpn :
sudo vi /etc/default/openvpn
Uncomment the line #AUTOSTART=”all” and either leave it as is, or replace it with the name of the server config file (servername.conf in this example).
AUTOSTART="all" AUTOSTART="servername"