Setting up a Raspberry Pi as a VPN server: an OpenVPN tutorial
The security of public networks used to access the internet often leaves a lot to be desired. One way to browse safely, even when you are on the move, is to set up your own VPN (short for “Virtual Private Network”). Running your own VPN also gives you access to your local network from any internet connection.
To set up your own virtual private network, you need a computer that acts as a server to create the network. The Raspberry Pi is a cost-effective option for this. You can set up a VPN on a Raspberry Pi with OpenVPN, open-source software that is available as a free download.
Setting up your own VPN: an overview of how it works
A VPN is set up on a local network (LAN), partly so that it can be accessed from outside. It is a virtual communication network in which requests and responses exchanged between the VPN server and VPN clients (the devices connected to the server) are transmitted mainly over the internet.
With a self-configured VPN, you can even access your local network from any internet connection. This means you can access data on your LAN and query individual devices remotely (for example a printer or fax), as well as use your local network’s internet connection. Thanks to an encrypted connection to your VPN server, you can also browse far more securely than you would if you connected to the internet via riskier public networks (such as open Wi-Fi networks that anyone can join).
To make a secure connection to a VPN server possible, however, you need to set up a VPN server on a computer in your local network that is permanently connected to the internet. That computer then acts as the host for the virtual private network. You connect your devices (such as laptops, smartphones or tablets) to the server using client software. A client connected to the internet from outside your private LAN accesses your VPN server over an encrypted connection known as a VPN tunnel.
This VPN tunnel starts at your client and ends at your VPN server, so it spans the entire internet connection. The tunnel is therefore much more secure than the average public internet connection, making it difficult for hackers to break into it and intercept its traffic. By connecting to your own VPN, you can work with sensitive data very securely even on public Wi-Fi networks (for example when using online banking).
The benefits of creating a VPN server with Raspberry Pi and OpenVPN
Creating a VPN server with a Raspberry Pi is particularly recommended because of its competitive cost: the purchase price of the mini computer and all the necessary components is low. In addition, the power consumption required to keep the server running around the clock is relatively modest. Overall, the mini computer offers excellent value for money (although there are now several alternatives to the Raspberry Pi).
Among the various software options for creating your own VPN, there are several reasons to choose OpenVPN: first and foremost, it is free and very widely used for VPN servers, and it supports a large number of operating systems (Windows, OS X, Android, iOS, Linux and others). The software is also known for being relatively simple to configure and highly stable.
What do you need to set up a VPN server on a Raspberry Pi?
For this tutorial you will need the following components:
• A Raspberry Pi (model 2 or later recommended)
• A Micro SD card with the Raspbian Jessie operating system installed
• A permanent internet connection (preferably wired) and a power supply (via Micro USB cable) for the Raspberry Pi.
You also need to decide whether you want to configure the VPN server directly on the Raspberry Pi (by connecting a monitor, mouse and keyboard) or via an SSH client. Managing the server remotely via SSH is the recommended option in most cases, as it lets you access the VPN server from another computer.
There are several popular tools for this, such as PuTTY, WinSCP (for Windows) or OpenSSH (for Unix-based operating systems), which you can use to operate and administer the Raspberry Pi. With SSH software, you access the Raspberry Pi by entering its IPv4 address in the client (i.e. the computer from which you want to access the Raspberry Pi) and connecting the two. You can find your Raspberry Pi’s IP address, for example, in your router’s web interface, which is usually available at “192.168.0.1” (or “fritz.box” if you have a Fritz!Box router) in your browser.
Entering the correct IP addresses
When using an SSH client, it is advisable to assign the Raspberry Pi a static private IP address on the local network; otherwise, every time you want to access the mini computer via SSH you will have to look up its current dynamic address and connect the client to it. Associating a fixed private address with the Raspberry Pi is even more important for OpenVPN: the VPN server must be permanently reachable at the same address on the local network so that it can be accessed consistently, and the VPN server must likewise always be reachable at the same address on the internet.
However, an internet connection usually has only a dynamic public IP address, which changes at least every 24 hours and therefore prevents the server from being reachable at the same address at all times. If your internet connection does not have a static public IP address, you can set up dynamic DNS (DDNS).
See the dedicated article to find out more about assigning a static IP address to the Raspberry Pi and the options available for configuring a DDNS service. If you want to use your Raspberry Pi as a server and keep it available at all times, you should update it and review its security regularly.
Installing your own VPN server on the Raspberry Pi with OpenVPN
Now you can start configuring OpenVPN. To do so, open the terminal (command line) on your Raspberry Pi.
Preparing the Raspberry Pi
Before installing OpenVPN, it is advisable to check for and install updates to the packages already on the Raspberry Pi. Enter the following commands in the console:
sudo apt-get updatesudo apt-get upgrade
If you have not yet changed your Raspberry Pi’s default password (username: “Pi”; password: “Raspberry”), you should do so immediately; otherwise anyone can access the system, both locally and via SSH. The command below starts the mini computer’s configuration tool, where you can set a secure password.
sudo raspi-config
Installing OpenVPN and configuring easy-rsa
First, use the following command to install OpenVPN and OpenSSL, which is used to encrypt the connection.
sudo apt-get install openvpn openssl -y
Once OpenVPN is installed, copy the ready-made scripts from the “easy-rsa” directory into the OpenVPN configuration folder. This is where you will create the various certificates and keys. The following command only works on Raspbian Jessie (on the previous release, Wheezy, the scripts are located in “/usr/share/doc/openvpn/examples/easy-rsa/2.0”).
sudo cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa
Then open the file “/etc/openvpn/easy-rsa/vars” in the console by running the following command:
sudo nano /etc/openvpn/easy-rsa/vars
Now you need to edit this file with the correct parameters. Change the settings by replacing the entire line “export EASY_RSA=”`pwd`”” with the following:
export EASY_RSA="/etc/openvpn/easy-rsa"
In this file you also need to change the key length, which sets the security level of the encryption. A Raspberry Pi 3 has enough processing power to handle a 2048-bit key without difficulty. On the model 2, this level of encryption already causes a noticeable drop in performance, so in that case it may be better to use 1024-bit encryption only, depending on whether connection speed or encryption strength matters more to you. 4096-bit encryption, on the other hand, is useful only in very few cases. Change the key length by entering the corresponding number of bits in the line “export KEY_SIZE=2048”.
Now go back to the “easy-rsa” configuration folder, log in as root and load the settings you just made into the environment variables by running the “vars” script with the “source” command. Finally, make the derived configuration file available via a symbolic link named “openssl.cnf”.
cd /etc/openvpn/easy-rsasudo susource varsln -s openssl-1.0.0.cnf openssl.cnf
Creating certificates and keys for OpenVPN
First, create the initial keys for OpenVPN after clearing any existing keys.
./clean-all ./build-ca OpenVPN
You will be asked to enter the two-letter “Country Name” code for your country (e.g. IT for Italy or CH for Switzerland). The related prompts are not important, so you can simply confirm them with the Enter key.
Next, generate the keys for the server:
./build-key-server server
Enter the two-letter country code again and leave the following fields blank. Finally, confirm by pressing “Y” twice when asked whether the certificate should be generated.
Then continue by configuring one or more VPN clients. To do this, create a certificate and a key for each device you want to use to access the VPN server. The procedure is the same as for the server certificate and key (enter the country code and confirm twice). You can give each device a specific name (in the commands below, one is given for each client: “laptop”, “smartphone” and “tablet” respectively).
./build-key laptop ./build-key smartphone ./build-key tablet
If you want to set a password for the clients, use the following commands instead of the ones above:
./build-key-pass laptop ./build-key-pass smartphone ./build-key-pass tablet
Complete the generation of certificates and keys with the command for the Diffie-Hellman key exchange:
./build-dh
Depending on your hardware, this may take some time. Once the process has finished, log out as root:
exit
Generating the OpenVPN server configuration file
Open the OpenVPN configuration file
sudo nano /etc/openvpn/openvpn.conf
Fill the empty file with the various directives described below. First, enable routing through an IP tunnel with “dev tun” and choose the UDP network protocol with “proto udp” (if you want to use TCP, choose “proto tcp”). The next line specifies that the OpenVPN server is reachable on port 1194, but you can change this.
dev tun proto udp port 1194
Next, reference the SSL/TLS root certificate (ca), the digital certificate (cert) and the digital key (key) from the “easy-rsa” folder. Make sure you also specify the correct encryption bit length (1024, 2048, etc.).
ca /etc/openvpn/easy-rsa/keys/ca.crtcert /etc/openvpn/easy-rsa/keys/server.crtkey /etc/openvpn/easy-rsa/keys/server.keydh /etc/openvpn/easy-rsa/keys/dh2048.pem
Now specify that the Raspberry Pi should act as a VPN server. Here you enter the IP address and subnet mask to be assigned to the VPN.
server 10.8.0.0 255.255.255.0
With the “redirect-gateway def1 bypass-dhcp” directive, all IP traffic is routed through the IP tunnel. If you are aiming for a high level of security you can experiment with this setting, but if you run into problems or browsing becomes too slow, it is best to remove it. You should, however, always use the other directives listed below to specify the public DNS servers the VPN server will use. The following commands list a 1&1 server, “217.237.150.188”, and a Google server, “8.8.8.8”, but you can also enter the IPv4 addresses of other DNS servers. With “log-append /var/log/openvpn” you specify that logs should be written to the file “/var/log/openvpn”.
push "redirect-gateway def1 bypass-dhcp"push "dhcp-option DNS 217.237.150.188"push "dhcp-option DNS 8.8.8.8"log-append /var/log/openvpn
With “persist-key” the “key” files are not re-read, and with “persist-tun” the TUN and TAP drivers for network access are not restarted. You reduce the OpenVPN daemon’s privileges with “user nobody” and “group nogroup”. With “status /var/log/openvpn-status.log” you create a status file showing the current connection. It is also advisable to set the verbosity of the log output with the “verb” directive. If you choose “0”, you will receive no output apart from error messages. A value between 1 and 4 is suitable for normal use, while higher values are useful for troubleshooting. Finally, with the “client-to-client” directive you specify that VPN clients can see not only the server but also the other VPN clients, and with “comp-lzo” you enable LZO compression (which must also be enabled in the client’s configuration file).
persist-key persist-tun user nobody group nogroup status /var/log/openvpn-status.logverb 3 client-to-client comp-lzo
Save your changes with “CTRL + O” and close the editor with “CTRL + X”.
Setting up the script for internet access from a client
To access your local network’s internet connection through your VPN tunnel, you need to set up forwarding. First, create the file “/etc/init.d/rpivpn”:
sudo nano /etc/init.d/rpivpn
Copy the following comments into the file to create the header for the Linux init script:
#! /bin/sh ### BEGIN INIT INFO # Provides: rpivpn # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: VPN initialization script ### END INIT INFO
Then enable “ip_forward” by writing a “1” to this file:
echo 'echo "1" > /proc/sys/net/ipv4/ip_forward' | sudo -s
Once that is done, use the “iptables” packet filter to set up forwarding for VPN packets.
iptables -A INPUT -i tun+ -j ACCEPT |iptables -A FORWARD -i tun+ -j ACCEPT
You still need the commands that allow your VPN clients to access the LAN and the internet. Configure them with the following lines:
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -t nat -F POSTROUTING iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Save and close the file again with “CTRL + O” and “CTRL + X”.
For the forwarding to work, you still need to give the script the appropriate permissions and install it as an init script.
sudo chmod +x /etc/init.d/rpivpn sudo update-rc.d rpivpn defaults
Now run the script and then restart the OpenVPN server.
sudo /etc/init.d/rpivpnsudo /etc/init.d/openvpn restart
Completing the client configuration
In the final step, you bundle each client’s certificates and key into a single package. To do this, log in as root again, open the “/etc/openvpn/easy-rsa/keys/” folder and create the client configuration file. The following commands open the file for the “laptop” client. The configuration works the same way for every client, so you only need to change the name of the device you are setting up.
sudo su cd /etc/openvpn/easy-rsa/keys nano laptop.ovpn
In the client’s “.ovpn” file, now enter the following:
dev tun client proto udp remote x.x.x.x 1194 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert laptop.crtkey laptop.keycomp-lzo verb 3
The contents of the file above still need to be adapted accordingly. In the fourth line, replace “x.x.x.x” with the address of your DDNS service (if you use a static public IP address, you can simply enter that), followed by the port on which the VPN server should be reachable. In the third-to-last and fourth-to-last lines, enter the name of your client (in this case: “laptop”). Once you have made the changes, save them with “CTRL + O” and close the editor with “CTRL + X”.
Finally, compress the configuration file together with the certificates and keys into a zip file. If you have not yet installed a zip package on the Raspberry Pi, do so with the following command:
apt-get install zip
Use the following commands to create a zip file, again making sure that you have used the correct client name throughout.
zip /home/pi/raspberry_laptop.zip ca.crt laptop.crt laptop.key laptop.ovpn
Now you just need to set the file permissions and then finish the configuration with “exit”.
chown pi:pi /home/pi/raspberry_laptop.zip
exit
The zip file is now ready: transfer it from the Raspberry Pi to the client (for example using an SCP or SFTP program) and then set it up on the client device. You can now use the device to access your local network, and its internet connection, from any internet connection.
Setting up your own VPN server on a Raspberry Pi is well worth it
Creating and running your own VPN is far less expensive than you might think: thanks to the Raspberry Pi’s low power consumption, running costs are minimal, and the individual server components (Raspberry Pi, Micro SD card, etc.) are very easy to find.
A VPN server on a Raspberry Pi is also highly capable. With your own dedicated VPN server on a Raspberry Pi, you can access your local network from any internet connection. The VPN connection is encrypted, allowing you to browse much more securely, whether you are using an open and/or unsecured Wi-Fi network or your mobile operator’s data connection. It is hard to find a mobile internet connection that offers better protection.
Enjoy!
