How to Set Up a Raspberry Pi VPN Hotspot

If you’re an expat like Ellie and me there’s a good chance there’s at least a part of you that misses being able to watch streaming content easily from your own country. The answer is a VPN, but these days it’s not that straightforward. I recently took some time to get a Raspberry Pi VPN hotspot set up at home and figured I’d share my lessons learned.

Disclosure: This post contains affiliate links. Sees Opportunity may receive a commission for products and services you purchase through our links at no additional cost to you.

If you’re away from your home country, whether temporarily traveling or living as an expat, it can be frustrating to navigate the myriad of content licensing rules that often prevent you from accessing the streaming content you get back home. To get around these restrictions you can use a Virtual Private Network (VPN), which makes it appear that your computer is accessing the internet from a different location than where you actually are.

If you’re trying to access content from a single computer, smartphone, or tablet, the easiest thing to do is to use an app from one of the many VPN providers available today. Some reputable examples are VyprVPN, NordVPN, and ExpressVPN. However, if you’re like us you have several devices that you’d like to get streaming access enabled for, including dedicated streaming devices like Roku that don’t support native VPN apps. In this case the best approach, while not the easiest, is to set up a VPN hotspot, which automatically gives any device connected to the hotspot a VPN connection.

I had a lot of trouble finding a reliable guide to help me get this all set up, but after lots of trial and error I have it working. I wrote up the guide below to hopefully help others; enjoy!

Raspberry Pi VPN Hotspot Guide

Note: I would consider this guide to be of intermediate skill level. It assumes you’re familiar with the Linux operating system, IP networking concepts, and are comfortable using the command line.

Materials

You’ll need the following components to get started:

  • Raspberry Pi 4 (2 or 4GB RAM – $35 to $55)
  • 5V 3A USB-C Power Supply ($8 to $10)
  • 16 to 32GB Micro SD Card (32GB recommended – $6 to $12)
  • Ethernet Patch Cable ($5 to $10)
  • Home Router with Open Ethernet Port

The following components aren’t necessarily required, but recommended:

  • Raspberry Pi 4 Case ($10 to $30)

The VPN

I tried three different VPN providers while trying to get this setup to work due to the DNS issues I’ll talk about below. I finally settled on Unlocator because they provide a “hybrid” solution that combines their VPN with their Smart DNS service. You’ll see why that’s important below! Not only is Unlocator affordable, it our time using it it’s proven fast and reliable.

Pro-tip: Once you sign up for service, be sure to visit the Regions page in your Smart DNS settings and make sure your favorite services are set to your desired country/region.

Setting up the Raspberry Pi

Start by downloading the latest version of Raspbian Lite image here. Once downloaded, write the image to the SD card. After the image is written, re-mount the SD card on your computer and write an empty file named “ssh” into the boot partition to enable SSH access to your Pi. Unmount the SD card and put it into the Raspberry Pi. Connect the Pi to your home router using the ethernet cable. Finally, plug the power supply into an outlet and then into the Pi to start it. Give the Pi a minute or two to boot up.

Now you’ll need to log into the Pi to do some basic setup. To do so, you’ll first need to find the Pi’s IP address on your home network. The easiest way to do this is to log into your home router and look for the device named “raspberrypi” (the default hostname). Once you have its IP address, SSH into the Pi; the default username and password are pi and raspberry, respectively.

First, let’s make sure the Pi’s software is all up-to-date:

$ sudo apt update
$ sudo apt full-upgrade

Next, take care of some basic setup using the raspi-config tool. At a minimum you should:

  • Change the password for the pi user
  • Modify the Pi’s hostname under Network options
  • Update your WiFi country under Localisation options
  • Expand the filesystem under Advanced options
  • Adjust the memory split to 16MB (the minimum) under Advanced options

Reboot the Pi so that all of the new settings take affect, then SSH back in.

Configure the VPN on the Pi

We’ll use OpenVPN on the Raspberry Pi to run and manage our VPN connection. Start by installing OpenVPN on the Pi:

$ sudo apt install -y openvpn

Next tell OpenVPN to not automatically start any VPN (we’ll configure it later to autostart in a different way). Open /etc/default/openvpn and uncomment the following line:

AUTOSTART="none"

Now we need to download and set up the VPN connection configuration for Unlocator. First, Log into your Unlocator account and go to the VPN Account Info section to see your VPN username (your email) and password. Create and open /etc/openvpn/auth and add your username and password on separate lines:

username
password

Pro-tip: it’s best practice to protect files like this with sensitive information. Update the file permissions so that only the root user has access:

$ sudo chmod 600 /etc/openvpn/auth

Back in your Unlocator account, go to the Server List section. Expand the section for your home country and find the server closest to your current location (if more than one is available). Copy the UDP link for the server you want. A UDP connection for the VPN offers significantly better speed than TCP. Back on your Pi, use wget to download the config file into your home directory:

$ cd
$ wget https://unlocator.com/configs/openvpn/<your-server-config>.ovpn

Now copy the Unlocator VPN configuration into OpenVPN’s client config directory:

$ sudo cp ~/<your-server-config>.ovpn /etc/openvpn/client/Unlocator.conf

Open /etc/openvpn/client/Unlocator.conf and find a line that says auth-user-pass and update it to point to the username and password file you created above:

auth-user-pass /etc/openvpn/auth

Next, enable the OpenVPN service for this new configuration and start it up:

$ sudo systemctl enable openvpn-client@Unlocator
$ sudo systemctl start openvpn-client@Unlocator

Finally, verify that the VPN has connected successfully by checking the Pi’s network interfaces and looking for one named something similar to tun0:

$ ifconfig

With our VPN connection set up and running, it’s time to turn the Raspberry Pi into a wireless access point.

Configure the Pi as a Wireless Access Point

In order to serve as an access point we need to make sure the Pi’s wireless interface has a static IP. We also need to make sure that the wireless interface doesn’t try to function like a client by disabling the WPA supplicant. Add the following configuration to the end of the /etc/dhcpcd.conf file:

# WLAN config for access point
interface wlan0
    static ip_address=10.10.0.1/24
    nohook wpa_supplicant

Pro-tip: you can choose any IP address in private IP space.

DNS Setup

Next, install the software we need to run the Pi as a wireless access point and provide its own DHCP and DNS servers:

$ sudo apt install -y hostapd dnsmasq

Once installed, they need to be configured. We’ll start with dnsmasq, which will be the DHCP and DNS servers for our access point. Open /etc/dnsmasq.conf and replace all of the contents with this:

# dnsmasq config for VPN AP

interface=wlan0
dhcp-range=10.10.0.8,10.10.0.32,255.255.255.0,24h
no-resolv

# Unlocator SmartDNS
server=185.37.37.37

domain=my-vpn-pi
address=/gw.my-vpn-pi/10.10.0.1

This configuration is doing a few important things:

  • Setting the range of IP addresses to offer through DHCP, along with the renewal time
  • Telling dnsmasq to not read system default DNS resolution endpoints (this is important for our DNS setup)
  • Telling dnsmasq to use Unlocator’s Smart DNS servers for recursive DNS resolutions
  • Setting up the local domain name and a static assignment of a hostname (as seen by clients who will connect to the access point) to the Pi

Here’s a complete description of all available dnsmasq configuration items. I discovered that the DNS settings are critical to ensure that access to your streaming services works flawlessly. You need them in addition to the VPN itself because some streaming services implement clever region detection not only by IP address (which the VPN fixes), but also by checking which of their global endpoints you’re being routed to as a result of your local DNS resolutions.

Access Point Setup

Next, let’s configure hostapd, which will manage the Pi’s wireless access point. Create and open /etc/hostapd/hostapd.conf and add the following content:

# VPN AP config
interface=wlan0
hw_mode=a
channel=48
ieee80211d=1
country_code=DE
ieee80211n=1
ieee80211ac=1
wmm_enabled=1
macaddr_acl=0
ignore_broadcast_ssid=0
ssid=My-VPN-Pi
auth_algs=1
wpa=2
wpa_passphrase=your-passphrase-1234!
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

I found that the Gentoo Linux wiki has the best descriptions of hostapd settings.

Note: you should change the country_code and channel settings based on where you’re located. The country_code should match what you set up in raspi-config above, and to figure out what channels you have available run the command below and look at the listed “Frequencies” (channel numbers are in the square brackets):

$ sudo iw list

Note: you should also at least change the wpa_passphrase setting to something more secure! You can also update the ssid to be whatever you want.

Finally, enable both of the services we just configured:

$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl enable dnsmasq

Your Raspberry Pi should now be broadcasting the WiFi SSID that you just configured, and you should be able to connect to it from another computer or mobile device. However, it’s not very useful yet because we’re not forwarding any traffic.

Route All Wireless Traffic to the VPN

The wireless network we just created is currently operating in isolation. We need to make some networking updates to re-route its traffic to the VPN. Start by installing some additional software to help us save firewall rules:

$ sudo DEBIAN_FRONTEND=noninteractive \
  apt install -y netfilter-persistent iptables-persistent

Next, we need to tell the Pi to allow IP traffic forwarding between interfaces. Create and open /etc/sysctl.d/routed-ap.conf and add the following content:

# Enable IPv4 routing
net.ipv4.ip_forward=1

In order for traffic to be routed from the wireless network to the VPN network, we need to add a firewall rule that will automatically do address translation for us:

$ sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Note: if necessary, substitute the interface name, tun0, with whatever interface name the VPN created on your Pi.

Finally, save the new firewall rule so that it will automatically be loaded at boot:

$ sudo netfilter-persistent save

Now, let’s restart everything to apply all the new configurations. The easiest way to do this is to restart the Pi itself:

$ sudo reboot

Verify it All Works

Give the Pi a minute or two to fully reboot. When it’s back up you should be able to see your new wireless network available on your other computers and mobile devices. Connect to the network with one of your devices, and on that device open a browser and go to BrowserLeaks to make sure everything is working as intended. You should see your IP address location, WebRTC leak test, and DNS leak test information all resolving to servers near the VPN server location that you selected above.

Congratulations, you now have your very own Raspberry Pi VPN hotspot and you should now be able to watch all your favorite streaming services from your home country; enjoy!

Troubleshooting

If things don’t seem to be working for you, check the status of all of the services that we’ve set up. Here’s how to do that:

$ sudo systemctl status <service>

Replace “<service>” above with the name of the service to check, such as dnsmasq, hostapd, or openvpn-client@Unlocator. That command will show you the status of the service, which should say “active (running)”, as well as the latest log messages from the service (look for any error messages).

The only issue I’ve had so far is that every now and then the VPN seems to go down and for whatever reason isn’t able to recover automatically. Thankfully, the solution is pretty simple: just restart it (I’ve also been restarting dnsmasq at the same time):

$ sudo systemctl restart dnsmasq
$ sudo systemctl restart openvpn-client@Unlocator

Optional Things

One thing you may want to do on your Pi is increase the size of the Swap file. Start by turning off the current swap:

$ sudo dphys-swapfile swapoff

Next open /etc/dphys-swapfile and edit the line that starts with “CONF_SWAPSIZE” to set the desired size of your swap. The general recommendation is to make the swap file twice the size of your available RAM, but this is only useful up to a certain point. For most use cases, a 2GB swap file will be more than enough:

CONF_SWAPSIZE=2048

Finally, reconfigure the swap file and turn it back on:

$ sudo dphys-swapfile setup
$ sudo dphys-swapfile swapon

Photo by Harrison Broadbent on Unsplash