The holiday has been started, you love to check your e-mail, Facebook or WhatsApp at your holiday location but can you trust the provided Wi-Fi-connection? The answer is: NO. Never trust these kind of Wi-Fi-networks.
Maybe somebody has set up a wireless access point (AP)/WLAN-hotspot with the same name as the access point of your hotel/Internet café and you connected unsuspected with this evil access point. Or some other client at the Wi-Fi-network is sniffing all your traffic including passwords!
Or you love to watch live television from your foreign holiday location but the content has been geo-blocked? Read this tutorial how to circumvent these problems. Here you will learn how to set up a Virtual Private Network (VPN) from your remote location to your home network using a Raspberry Pi. As VPN-client a device running Android, Ubuntu, Debian or Raspbian is assumed. With little modifications you can adapt this tutorial and let a computer running Ubuntu or Debian be your OpenVPN server instead of the Raspberry Pi.
Assumed is that your Raspberry Pi is running Raspbian as operating system and is connected to your home network already. Otherwise read this tutorial: Raspberry Pi: First use.
The tutorial has been divided into these sections:
- Install OpenVPN
- Create certificates and keys
- Configure OpenVPN server
- Configure firewall
- Create VPN connections to our VPN server
At the end some links to external resources are included.
Installing OpenVPN consists of these steps: bringing the software at your Raspberry Pi to the latest versions and the actual installation of the OpenVPN package and dependencies. Of course you have to login first into the Raspberry Pi. All commands are executed from the command shell.
Login into your Raspberry Pi
Open a SSH-connection to your Raspberry Pi and login:
(default password: raspberry)
Change user so that you are ‘root’ to perform administrative tasks:
Update your Raspberry Pi to the latest software releases:
apt-get update apt-get upgrade
Perform the actual install of OpenVPN:
apt-get install openvpn openssl
Create certificates and keys
This step is divided into configuring ‘easy-rsa’ (preparations), creating three kinds of certificates and keys (certification authority, server and user) and generating the Diffie-Hellman-parameter.
Preparations before creating certificates
By installing OpenVPN, also the package ‘easy-rsa’ has been installed as dependency. This is a package which contains certification authority (CA) utilities. Copy these scripts to the OpenVPN-directory:
cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa
Now change some easy-rsa settings in the file: /etc/openvpn/easy-rsa/vars using your favorite text-editor i.e.:
cd /etc/openvpn/easy-rsa/ vi vars
Give EASY_RSA the value “/etc/openvpn/easy-rsa” (export EASY_RSA=”/etc/openvpn/easy-rsa” ) and increase the key size to 2048 bit (export KEY_SIZE=2048 ).
Make sure the old EASY_RSA and KEY_SIZE are replaced or commented out.
Read these easy-rsa settings:
In the easy-rsa package are multiple OpenSSL-configuration files (openssl-0.9.6.cnf, openssl-0.9.8.cnf and openssl-1.0.0.cnf) you have to select the 1.0.0 version by creating a symbolic link:
ln -s openssl-1.0.0.cnf openssl.cnf
Now easy-rsa is ready to create certificates and keys.
Create certificate and key for the: Certification authority
It’s always a good idea to cleanup things, so start with this:
Now create the certification authority root certificate for OpenVPN:
- Answer the question: “Country Name” with the two letter country code where your Raspberry Pi is located, i.e. NL for The Netherlands.
- Make “State or Province Name“, “Locality Name“, “Organization Name” and “Organizational Unit Name” empty by giving a DOT “.” as value.
- Confirm “Common Name [OpenVPN]” and “Name [EasyRSA]” by just pressing enter.
- Also make “Email Address” empty by giving a dot as value.
Create certificate and key for the: Server
- Use for “Country Name“, “State or Province Name“, “Locality Name“, “Organization Name” and “Organizational Unit Name” the same values as used by creating the certification authority root certificate (previous step)
- Confirm “Common Name [server]” and “Name [EasyRSA]” by just pressing enter.
- Also make “Email Address” empty by giving a dot as value.
- Keep the “challenge password“, “optional company name” empty by pressing enter.
Sign the certificate by answering two times: ‘y‘ (‘Sign the certificate?’ and ‘1 out of 1 certificate requests certified, commit?’).
Create certificate and key for the: User(s)
You have to create for every VPN-user a certificate and key. You can protect these by using a password. This is recommended because otherwise everybody who obtains (steals?) these user-settings can use the VPN to your home network. The two commands which apply are ‘build-key-pass‘ and ‘build-key‘ respectively to create certificates and keys with and without password. Here we will create certificate and key with a password, to set a good example:
Change ‘user1’ into something appropriate.
Answer the questions: “Enter PEM pass phrase” and “Verifying – Enter PEM pass phrase” with your desired password. By handing over the VPN settings to the user, you also have to give this password, of course.
Answer the other questions in the same way as for a server, keep the ‘Common Name‘ and ‘Name‘ unchanged and ‘A challenge password‘ and ‘An optional company name‘ empty. Finally sign the certificate by answering two times ‘y‘.
Repeat these steps for all VPN-users. Of course change ‘user1’ to the relevant name.
For a safe key-exchange the Diffie-Hellman-Parameter must be created:
Creating this parameter can take a while. Wait and relax!
Configure OpenVPN server
In this step we will create the actual configuration file for the OpenVPN server. Create the file /etc/openvpn/openvpn.conf with as contents:
dev tun proto udp port 1194 ca /etc/openvpn/easy-rsa/keys/ca.crt cert /etc/openvpn/easy-rsa/keys/server.crt key /etc/openvpn/easy-rsa/keys/server.key dh /etc/openvpn/easy-rsa/keys/dh2048.pem user nobody group nogroup server 10.8.0.0 255.255.255.0 persist-key persist-tun status /var/log/openvpn-status.log verb 3 client-to-client push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 22.214.171.124" log-append /var/log/openvpn comp-lzo
Important here to mention are these settings:
- OpenVPN is running at UDP port 1194
- The configuration file is pointing to the files which we created in the previous steps:
- Certification authority certificate
- Server certificate and key
- Certification authority certificate
- The VPN client will get an IP address in subnet 10.8.0.0/24
- The traffic from the VPN client will be redirected via the VPN: “redirect-gateway def1 bypass-dhcp“
- As DNS for the client the public DNS server of Google will be used: “dhcp-option DNS 126.96.36.199“
Basic test the OpenVPN server/configuration
Now all OpenVPN settings at the server side are in place to start the server. Try to start it to check whether there are no typos in the configuration and all dependencies are in place.
Start OpenVPN server in this way:
Make sure the tunnel interface is present after this step. Check whether tunnel interface exists by issuing this command:
ifconfig | grep tun
Output must be something like this:
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
When it’s not there, try to reboot your Raspberry Pi (and make sure you become root again).
You have to configure two firewalls: The one in your router (port forwarding) and the Raspberry Pi iptables based firewall. Configuring the firewall in the router means that VPN-traffic must be redirected to the computer where OpenVPN is running (Raspberry Pi). Besides of that you have to configure the Raspberry Pi firewall by making some holes to let VPN traffic through and redirect Internet traffic from the VPN, via the Raspberry Pi back to the Internet.
Port forwarding router
Now create a port forward in your router. VPN-traffic from your public Internet connection must be redirected to OpenVPN at your Raspberry Pi. Recommended is to use port 443 at the public side, because this is one of the few ports which is not blocked at most of the (corporate) firewalls. How to configure your router is beyond the scope of this tutorial.
In short, create a UDP-forward like this:
Public IP address:443 -> Raspberry Pi:1194
Configure firewall Raspberry Pi
The firewall is based on ‘iptables’. When you have a firewall in place already, please only pick those firewall rules which applies to your situation. At the end of this chapter, you will find the settings you need in case you use Arno’s IPtables Firewall at Debian/Ubuntu.
I prepared a script which will flush all the existing rules at the firewall, set the default policy on drop and white list only traffic which is needed in our situation: unlimited access on the loopback device, incoming SSH (to manage the Raspberry Pi) and incoming VPN-connections. Finally traffic from the VPN (tunnel) is allowed to pass through the Raspberry Pi, back to the outside interface (to the Internet). Traffic to the Internet will be forwarded using network address translation (NAT). For the latter you also have to enable IPv4 forward which is include in the script too.
Create the firewall script file i.e. /home/pi/firewall.sh with these contents:
#!/bin/bash export INTERFACE_OUTSIDE=wlan0 export INTERFACE_TUNNEL=tun0 # Flushing all rules iptables -F iptables -X # Setting default filter policy iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Allow unlimited traffic on loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Allow incoming SSH iptables -A INPUT -i $INTERFACE_OUTSIDE -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $INTERFACE_OUTSIDE -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT #VPN # Allow incoming VPN iptables -A INPUT -i $INTERFACE_OUTSIDE -p udp --dport 1194 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o $INTERFACE_OUTSIDE -p udp --sport 1194 -m state --state ESTABLISHED -j ACCEPT # Allow TUN interface connections to OpenVPN server iptables -A INPUT -i tun+ -j ACCEPT # Allow TUN interface connections to be forwarded through other interfaces iptables -A FORWARD -i tun+ -o $INTERFACE_OUTSIDE -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A FORWARD -i $INTERFACE_OUTSIDE -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT # NAT the VPN client traffic to the Internet sysctl -w net.ipv4.ip_forward=1 iptables -t nat -F POSTROUTING iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $INTERFACE_OUTSIDE -j MASQUERADE iptables -A INPUT -j DROP iptables -A OUTPUT -j DROP
Important: Replace the INTERFACE_OUTSIDE-value (wlan0) with the name of the interface you use to connect your Raspberry Pi with the home network, i.e. eth0 or wlan0.
Start the script/configure firewall by executing:
When everything is OK, most important you don’t lock yourself out, you can execute this script automatically at startup of your Raspberry Pi, by creating a service for it. Read in this tutorial how to do this: Linux: Let your program run as background service.
Arno’s IPtables Firewall at Debian/Ubuntu
Read this chapter only when you use ‘Arno’s IPtables Firewall’.
Change the settings in: /etc/arno-iptables-firewall/conf.d/00debconf.conf so that it will contain at least these settings:
OPEN_UDP="1194" INT_IF="tun+" NAT=1 INTERNAL_NET="10.8.0.0/24" NAT_INTERNAL_NET="10.8.0.0/24"
…and restart the firewall:
systemctl restart arno-iptables-firewall
The server side is ready to use.
Create VPN connections to our VPN server
To create a connection to the server you need actually two things: A client and the configuration for the client. Here we will start by creating the configuration(s) for the client(s) called an OpenVPN configuration package.
OpenVPN configuration package
A configuration package contains two certificates (certification authority and user) a user key and information how to connect with the OpenVPN server (configuration). We created the certificates and key in one of the previous steps already, the only thing which remains is creating the configuration file. These steps must be repeated for every separate user.
Go to the directory “/etc/openvpn/easy-rsa/keys/“.
Create for “user1” the OpenVPN configuration file:
Add this as content to the file:
dev tun client proto udp remote PUBLIC_IP_ADDRESS PORT resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert user1.crt key user1.key comp-lzo verb 3
Replace PUBLIC_IP_ADDRESS with the IP-address of your home network router. This must be the address which is accessible from the public Internet. A DNS-name which is pointing to this address is also allowed. Replace PORT with the UDP-port you configured in your home network router which points to OpenVPN at your Raspberry Pi.
Make sure you replace “user1.crt” and “user1.key” with the certificate and key file name of the appropriate user.
Now zip everything (certificates, key and configuration file) together into a package to make it easier to transfer.
zip /home/pi/openvpn_user1.zip ca.crt user1.crt user1.key user1.ovpn chown pi:pi /home/pi/openvpn_user1.zip
Copy openvpn_user1.zip to OpenVPN client device (Android SD card) and unpack it again. How? It’s up to you, use a pendrive, scp or put it temporarily on a webserver (httpS) which is running at the Raspberry Pi. But make sure to give this file and password only to the person which is allowed to connect via VPN to your home network.
VPN Client – Android
To use your VPN connection from an Android device, you have to install OpenVPN Connect as client, configure the client and start your VPN-connection.
- Download and install OpenVPN Connect from Google Play:
- Start “OpenVPN Connect”
- Settings->Import->Import Profile from SD card”
- Select the .ovpn file
- Type the password (Private Key Password)
- Confirm the application Permission dialog (intercept all network traffic)
- Press “Connect”
Ready! You can use the VPN-connection from the client!
VPN Client – Ubuntu/Debian/Raspian
Perform these steps at a computer which is running Ubuntu, Debian or Raspbian. These steps must not be executed at the OpenVPN-server: These are VPN-client instructions.
Install the client:
sudo apt-get install openvpn
Make sure you unpack the package openvpn_user1.zip. Execute this command in the directory which contains the contents of that package:
sudo openvpn --config user1.ovpn
Ready! You can use the VPN connection from the client!