Home‎ > ‎Dabbles‎ > ‎RaspberryPi‎ > ‎

RaspberryPi 230 - Implementing a VPN Server

posted Dec 4, 2015, 3:28 PM by Joshua S
This tutorial will demonstrate how to build a Virtual Private Network (VPN) server.  This will allow remote devices (PCs, Phones, Tablets, etc.) to connect to your network via the RaspberryPi from anywhere on the Internet.  Through this connection, you will be able to use that device as if it were connected locally on your network.  You may use this so you can access your printer, other computers, or storage devices, or so you can access an unfiltered internet if you are at work or somewhere else that filters your connection.
  • Note -- this tutorial uses PKI via a separate Certificate Authority (CA), but there was an early Dabble I created that deploys an all in one solution here
  • Note -- this tutorial uses exclusively PKI authentication -- there is a way to tie in OpenLDAP as a part of this process, but that will be saved for a possible future Dabble.
This project assumes you have a static IP set for the RaspberryPi.  No instructions speak to this, because they will vary based upon your environment and where you implemented DHCP.  Generally speaking, this is something you will configure at your router by supplying the MAC address of the Pi.  Additionally, the router will need to be configured to port forward TCP port 1194 (or whatever port you choose to implement for the VPN) to the RaspberryPi.  Note, OpenVPN is often configured to use UDP, but this protocol is also often blocked thus TCP will work much more consistently and is what I show in this Dabble.

With any of the Dabbles on this site, if you have questions, suggestions, or thoughts, please feel free to send me an eMail (I'm still working to figure out how to enable comments on Google Sites -- suggestions would be appreciated)!

Supply List:
  • RaspberryPi  The actual RaspberryPi hardware this will all be built around.  In this tutorial, a Raspberry Pi 2 is used and has a memory card with the Raspbian operating system pre-installed.
  • PuTTY SSH Client – PuTTY is a free and open-source terminal emulator, serial console and network file transfer application. It supports several network protocols, including SCP, SSH, Telnet, rlogin, and raw socket connection.  Other SSH tools can be used, but this tutorial will leverage PuTTY.

  • I know I said this guide was going to be comprehensive and not skip any steps, so what better way to start this off than by skipping steps.  I am not writing out instructions for the following (and illustrating from XKCD):
    • Buying a MicroSD Card
    • Buying a RaspberryPi 
    • Finding the IP Address of your Pi
      • This can be done in many ways, including on your router or using an IP scanner such as (AngryIP Scanner or NMAP) -- if there are requests from the "Contact Me" form; I'll look to create a tutorial for this.
    • Obtaining and installing PuTTY
  • Using PuTTY (or the SSH client of your choice) enter the IP Address or DNS Name of the RaspberryPi.
  • If this is the first time you connect, you will get a warning that the RaspberryPi's host key is unknown.  Click "Accept" or "Connect Once" to proceed with the connection.
  • Once connected, log onto the Pi using the credentials you created.  If you have not defined your own credentials, you should, but these are the default credentials:
  • UserID:  pi 
  • Password:  raspberry

  • OK, good!  Now that we are connected, let's install let's install OpenVPN:
sudo apt-get -y install openvpn
    • openvpn  virtual private network daemon.

  • We need to start by creating a directory for our keys:
sudo mkdir /etc/openvpn/keys
sudo chmod 400 /etc/openvpn/keys

  • We need to then import the following files into our key folder -- these should be generated through your Certificate Authority and then moved to your VPN server:
    • CA Certificate (ca.crt.pem)
    • Server Certificate (vpnserver.crt.pem)
    • Server Key (vpnserver.key.pem)
    • Diffie-Hellman Parameters (dh4096.pem)
  • Let's create our server TLS certificate using the following command:
sudo openvpn --genkey --secret /etc/openvpn/keys/ta.key

  • With the files in place, let's configure our server using the /etc/openvpn/server.conf file.  This will tell OpenVPN how we want it to operate.  I've attached a copy of the file used in this dabble at the end of this lesson for reference.  Make sure to update the following fields:
sudo nano /etc/openvpn/server.conf

local <the Pi's IP Address>
dev tun
proto tcp
port 1194
ca /etc/openvpn/keys/<the CA certificate>
cert /etc/openvpn/keys/<the VPN Server certificate>
key /etc/openvpn/keys/<the VPN Server key>
dh /etc/openvpn/keys/<the Diffie-Hellman Parameters>
# server and remote endpoints
# Add route to Client routing table for the OpenVPN Server
push "route" 
# Add route to the Client routing table for the OpenVPN Subnet
push "route"
# Your local subnet
push "route"
# Set primary domain name server access to the SOHO Router
# If your router does not do DNS, you can use Google DNS
push "dhcp-option DNS <DNS Server IP Address>"
push "dhcp-option DOMAIN <your domain>"
# Override the Client default gateway by using and
# rather than  This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway defl"
keepalive 10 120
tls-auth /etc/openvpn/keys/ta.key 0
cipher AES-256-CBC
user nobody
group nobody
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1

  • With the server configuration complete, we need to update the system control configuration to ensure traffic coming into the VPN is forwarded onto the local network.  To do this, let's edit the /etc/sysctl.conf file using nano.  I've attached a copy of the file used in this dabble at the end of this lesson for reference.  Make sure to update the following field:
sudo nano /etc/sysctl.conf


  • With these changes configured, we need to apply them using the following command:
sudo sysctl -p

  • OK, OpenVPN is now configured, but we need to update the RaspberryPi's firewall rules to allow traffic to be routed through the Pi.  It's best to use a script to accomplish this and locate it at /etc/firewall-openvpn-rules.sh.  First, create the script by issuing the nano command to edit the file (it is implicitly created) then insert the following lines.  I've attached a copy of the script at the end of this lesson for reference.  
sudo nano /etc/firewall-openvpn-rules.sh


iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --tosource <VPN Server Address>

    • With the script created, we need to update the file permissions to ensure it is well protected.  Do that by executing the following commands to update the access control list and owner of the file.
    sudo chmod 700 /etc/firewall-openvpn-rules.sh
    sudo chown root /etc/firewall-openvpn-rules.sh

    • Good, now that we have the script created, we need to have it execute each time the network interface loads.  We do this by editing the /etc/network/interfaces file using nano.  I've attached a copy of the script at the end of this lesson for reference.  Edit the file using the following command and add the following line beneath the iface for eth0:
    sudo nano /etc/network/interfaces

    pre-up /etc/firewall-openvpn-rules.sh

    • Congratulations!  Your VPN is now ready to go!  You should reboot your Pi, validate your port forwarding, and then try to connect by using the external IP address of your router!
    Joshua S,
    Dec 4, 2015, 3:28 PM
    Joshua S,
    Dec 4, 2015, 3:28 PM
    Joshua S,
    Dec 4, 2015, 3:28 PM