A VPN, or Virtual Private Network, was originally created to access a local network from the Internet. In our modern days, they are aggressively marketed for privacy. While they can be used to hide your Internet activity from your ISP, it is possible for your VPN company to collect all the same data. Ultimately, a VPN is a powerful tool when used correctly, but they could be a liability when used not used correctly.

The correct way to use a VPN is under these cases:

  1. To break free of a geo-restriction: To access a site from a different IP address or country.
  2. To secure your Internet connection: If you are on a public network, a VPN will encrypt all traffic to the VPN server. This protects your web traffic from being watched (but your web traffic could be watched by the VPN server).
  3. If you need to access resources on your personal network: If you are away from home and need to access your local network shares or take advantage of your local blocklists.

Presently, we will discuss our final point. We will use a Raspberry Pi to create a VPN into our own network. If your network includes a blocklist, such as PiHole, you will be safe on the Internet, protected from the ads and trackers. Finally, if you have network shares, your personal VPN will allow you to connect to those folders.

Installing a VPN on a Raspberry Pi is easy. We first need to make sure to have Raspberry Pi OS (formally called Raspbian). It works best without a desktop environment, so this tutorial will utilize the command line, so you will either need to setup your device with a monitor and keyboard, or you will need to enable SSH through the Raspberry Pi configuration:

raspi-config

Select Interfacing Options and enable SSH.

Before you begin, make sure your Pi OS is up to date.

To get started with installing a VPN, use the following command:

curl -L https://install.pivpn.io | bash

The script will install any necessary packages before asking for specific input.

You will be prompted to understand that the script will install either OpenVPN or Wireguard VPN protocol.

For this tutorial we will be using OpenVPN because the technology is more mature and most Linux network managers already have plugins to make connecting to OpenVPN more efficient. Wireguard is newer and faster technology, but it will require a separate VPN client to connect.

The next prompt informs you that your Pi needs a dedicated IP address. This means that when you connect your Pi to your network, your router might assign a random IP address. You need to make sure that your VPN server always has the same IP address on your network, so you can manage that by setting up a static IP address on the Pi and also by creating a static address in your router by reserving an IP address in the DCHP Reservation Table.

Our script makes things easier by offering to let you choose if you set a static IP. If you select Yes on this step, your Pi will be configured to always pull the same IP address from your router. It is better, however, to set a reserved address on your router so it doesn’t randomly assign your VPN server IP address to another device.

The next step will ask you to select a user you want to use. If you are using the default pi user, make sure you have changed the password (you can do that after the tutorial). Change the password with this command:

passwd 

Once you have selected the user, the next prompt will ask if you want Wireguard or OpenVPN. For this tutorial we are using OpenVPN

The next prompt screen asks about the Installation mode. We are looking at three settings:

Protocol: UDP is the default. Unless you know why, keep this setting.
Custom Domain: Use this if you are configuring a domain (requires a separate DNS service). If you are using just the IP address, keep None.
Features: Use Modern Features unless you are using some really old tech. I would not deviate from Modern features as it may create some security holes.

We can select No here to save all the settings. I clicked Yes to show each screen.

If you selected Yes, you will find a few new screens for each of these three points.

UDP / TCP: Use UDP

Port: I used the default port for VPNs 1194. You can use any port that is not used for another purpose. Changing the port could make your VPN more secure by adding a lay of obscurity.

Next, we find a screen asking if we want to use pi-hole as the DNS server. NOTE that even if you select this, it will not use Pi-hole for blocking unless your router is also using Pi-hole. I selected Yes to verify blocking will be managed by Pi-hole when my router is using it.

I did test if the VPN filters through the Pi-hole if the router is not using Pi-hole, and it does not block.

Next we are asked if we want to add a custom domain. I clicked no, and on the next screen selected my public IP address for the VPN configuration. If my IP address changes, I will need to change this value.

OpenVPN can run faster if you are using an OpenVPN client version 2.4 or later. OpenVPN 2.4 released December 2016, so it is likely you can select Yes to get higher pass-through transfer rates.

The certificate size determines the security of the VPN server. Using a 256-bit certificate will be secure enough, but you can use the higher levels, it will just take a lot longer for your server to generate the key (thus increases install time).

The key will take a while to generate and the server will run through the install. You will finally be about unattended upgrades. It is advisable to enable upgrades, but you want to reboot the server once in a while. A cron job running once a week to reboot the system would do nicely.

Creating a client profile

The installation will complete, but you will need to create a client profile in order to connect to the server. The great part about OpenVPN is you can export a single configuration file (.opvn) and use that combined with your password to access the VPN.

To create a profile, run in the terminal:

pivpn -a

You will enter the following:

Name for the client: {enter your desired name}
How many days should the certificate last?: {how long before it expires}
Enter the password for the client: {the desired password to access the server}
Enter the password again to verify: {repeat password}

The process creates a configuration file in the home directory /ovpns. You can see here that I have the file:

piholevpn.ovpn

in the directory:

/home/pi/ovpns/

You will need to extract the configuration file from the server. If you are accessing your device on SSH, the easiest is to use scp:

scp This email address is being protected from spambots. You need JavaScript enabled to view it.:~/ovpns/piholevpn.ovpn ~/{dir}/piholevpn.ovp

n

In this:
pi is the user
192.168.5.54 is the VPN static local IP address
piholevpn.ovpn is the name of the config file created above
~/{dir}/ is the location on your local computer where the file is stored.

Connecting

The first thing we need to before we connect to our VPN is to allow the pi to be accessible from the Internet.

To allow connections from the Internet, you need to set up Port Forwarding in your router. Each manufacturer is different, so again you’ll need to research Port Fowarding on your router. The typical process is the same: Select the destination device or IP address, at the port (1194 in our example), and allow Internet access to the device. Once that is completed, you will be able to connect to the VPN.

Connecting your device with OpenVPN is simple, but it will depend on your device. On Android and Apple devices, download the OpenVPN app, which for privacy-focused friends, you can find on f-droid for Android.

On Linux devices, make sure you have the openvpn plugin installed for your network manager. Many distros like Mint will already have it installed. Windows and Mac users, there are instructions for OpenVPN clients.

Once you have your client setup, simply import the ovpn file and enter your password. You should see a notification about being online.

Now are able to get into our network, access shares, and manage the blocklist with pihole.

Example

In our example, we will use MX Linux on an open public wireless network at the local library. I have connected to the Internet and agreed to their terms, so now I can go surfing away. I first test Google to show that the Internet is working. I use this because my pi-hole blocks google.com simply as a canary domain to test if my blocklist is working and that the vpn is pulling in DNS settings from pi-hole. Success! We are on Google.com. Now lets test the Internet speed. Without the VPN I get 20.15 down and 11.29 up.

Now lets connect to the VPN. On MX Linux, I need to follow steps to connect to a VPN on the XFCE desktop. I would follow similar steps on Cinnamon and Gnome.
Open up the Network Connections tool and find the bottom of the VPN section and select Import a saved VPN configuration.

Click the Create button and open the piholevpn.ovpn file we extracted from the VPN server.

All the data should import and you will just need to supply your client password we created above.

Now you can set the VPN to manually connect or to automatically connect every time your computer reaches an Internet connection.

We need to restart the browser to update the DNS cache.

Trying Google.com again, now we are not able to connect. Performing another speed test, we see some degradation. We are now at 9.76 down and 7.55 up.

I need to stop here and comment on this degradation. First, on my initial tests, I did not experience any degradation. It is possible that the network was bogged down on this day I performed the tests. Second, remember that we are using a very low power device without a gigabit ethernet port. Using a better pi will give us better results.

Now, you can see I can access the pi-hole configuration and make any changes I need to my blocklists. I am now being protected by my own pi-hole on my own VPN even though I am on the Internet at an open public library.

Finally, let’s double check that I can access my network shares. When I go to login, I am able to access my shares that are being served up from my home office, so we are all good to go.

Now any time I need a VPN, it is easy enough to turn on the pi and connect.