Route your entire home network through a VPN
You will need a device to use as a gateway for your network. A Raspberry Pi is good enough for this job. You will also need a valid account with a VPN provider such as ProtonVPN or NordVPN. ProtonVPN has the advantage of letting you connect to a few nodes, without bandwidth limit, if you subscribe to their free plan.
For this tutorial, I will assume you use a Raspberry Pi 4 with the Raspberry Pi OS (formerly known as Raspbian) and have an account with ProtonVPN.
Install your favorite OS and connect the device to your network, preferably using an ethernet cable.
Setup a fix IP address for your future gateway
First of all don’t forget to update your OS:
sudo apt update
sudo apt upgrade
note the current device IP address with the command
hostname -I
Then, open a terminal on the Raspberry Pi and open the file called dhcpcd.conf
sudo vim /etc/dhcpcd.conf
add the following lines to the file (replace XX with the actual address):
interface eth0
static ip_address=192.168.1.XX/24
# this is the IP address of your default gateway
static routers=192.168.2.1
static domain_name_servers=192.168.1.1 9.9.9.9
Then reboot the system for the changes to take effect
sudo reboot
Install OpenVPN
You will need OpenVPN to establish the VPN connection between your gateway and your VPN provider. Install it using the package distribution
sudo apt-get install openvpn
then activate the OpenVPN daemon
sudo systemctl enable openvpn
Setup the OpenVPN ProtonVPN configuration
Go to ProtonVPN and login to access your personal dashboard. Then, on the side menu, click on the OpenVPN/IKEv2 item.
On this page, note the OpenVPN username and password (they are different from your regular ProtonVPN credentials) as you will need them later on in your configuration file.
To generate a configuration file, choose GNU/Linux as your platform, UDP as the protocol, and then choose a country or a specific server in the list where you want to route your gateway traffic (and therefore your entire network). Then click on download to get the .ovpn configuration file. (Note that you can also choose a TOR node for even more privacy.)
Go back to your Raspberry Pi terminal and navigate to the OpenVPN configuration folder and create a new configuration file
cd /etc/openvpn
Create a new login file that will contain your ProtonVPN credential
vim login.txt
and past on the 1st line your username and on the 2nd your password so it looks like
<your_ovpn_username>
<your_ovpn_password>
then, still in this same folder, create a server configuration file:
vim server.conf
copy the content of the configuration file you just downloaded from Proton VPN and the line containing the auth-user-pass instruction to point to your login.txt file you just created:
auth-user-pass /etc/openvpn/login.txt
Add the following lines below to add additional routes and force the traffic through your pihole instance
# replace with the IP of your pihole instance
push "dhcp-option DNS 192.168.1.XX"
# replace with the IP of your gateway
push "route 192.168.1.0 255.255.255.0 192.168.1.XX 1"
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
Now start the OpenVPN client by establishing a new VPN connection
sudo systemctl restart openvpn@server
check that your public IP address now matches a ProtonVPN exit IP for the country of your choice. For this, you can either navigate to https://dnsleaktest.com/ or issue the following command in the terminal
curl ifconfig.me
Setting up the network routes and firewall
We need to let the Raspberry Pi forward the network traffic to act as a router:
sudo /bin/su -c "echo -e '\n#Enable IP Routing\nnet.ipv4.ip_forward = 1' > /etc/sysctl.conf"
To verify that the changes have taken place, issue the following command:
sudo sysctl -p
it should return
net.ipv4.ip_forward = 1
Then we can start setting up the iptables firewall to channel all of the network traffic into the VPN tunnel. If necessary, install the iptables package:
sudo apt install iptables
Setting up iptables, especially for users less familiar with networking is not an easy task and wrong manipulations can easily break your entire network or deny access to some services or devices. So be careful when editing those rules. If you want to better understand what happens or tweak the iptables configuration further, I can recommend this post by DigitalOcean to get a better understanding of what is happening.
So let’s go back at our Raspberry Pi and add a NAT rule so that the traffic gets redirected to the correct devices:
sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
Then we let the traffic go from eth0 to the VPN (tun0) interface and back
sudo iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
We allow the traffic on the loopback interface:
sudo iptables -A INPUT -i lo -j ACCEPT
We also need to allow traffic on specific ports for communication (ssh, ping, OpenVPN). Edit the following list as needed:
sudo iptables -A INPUT -i eth0 -p icmp -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
Allow return traffic for outgoing connections initiated by the Raspberry Pi:
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Next, in preparation for the setup with PiHole, we need to enable a few more ports for the local network so that DHCP, DNS, any VPN connections and the PiHole web interface will also work:
sudo iptables -I INPUT -i eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --destination-port 53 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p udp --destination-port 53 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p udp --destination-port 1194 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --destination-port 1194 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --destination-port 80 -j ACCEPT
Then, we block all other network traffic that does not comply with any of the previously mentioned rules:
sudo iptables -P FORWARD DROP
sudo iptables -P INPUT DROP
When this is done, we can print the rules to get a global picture:
sudo iptables -t nat -L -v --line-numbers
sudo iptables -t mangle -L -v --line-numbers
sudo iptables -L -v --line-numbers
Changes to the iptables will not persist after a system reboot. In order to keep the Iptables after the reboot, we need to install a small utility and save the settings we just made:
sudo apt-get install iptables-persistent
sudo systemctl enable netfilter-persistent
sudo netfilter-persistent save
Edit your pihole configuration to set your default network gateway
(See this post for the details on installing pihole).
Go to pihole’s web interface and login to navigate to the settings menu. From there, you can define the gateway for all your connected devices.
Now try disconnecting a device from your home network (by disabling the wifi for example) and reconnect. Then navigate to https://dnsleaktest.com/ and check that your new public IP matches the ProtonVPN exit node.
Optional: Add rules to forward a second OpenVPN traffic
I you have deployed your own private OpenVPN server on a machine sitting in your home network (see this post), you will need to make some adjustments to redirect your home VPN traffic to the correct gateways.
First of all, you need to allow your OpenVPN traffic through the gateway by modifying the iptables rules:
# do port forwarding to the VPN 2 server and allow forward traffic
iptables -t nat -A PREROUTING -p tcp --dport 1194 -j DNAT --to-destination 192.168.1.45:1194
iptables -I FORWARD -i eth0 -o eth0 -p tcp --dport 1194 -j ACCEPT
iptables -I FORWARD -i eth0 -o eth0 -p tcp --sport 1194 -j ACCEPT
Then you need to mark all OpenVPN incoming traffic so that it can be redirected to your home VPN server (and not be redirected to your ProtonVPN tunnel):
# mark all packets that have to be routed through the 192.168.1.1 gateway
iptables -t mangle -A PREROUTING -p tcp --sport 1194 -j MARK --set-mark 1
Then we add a new route for your marked packets to let them go back through your default network gateway so that they can go back the way they came:
# define desired specific route for marked packets
echo 201 openvpn1194.out | tee --append /etc/iproute2/rt_tables
ip rule add fwmark 1 table openvpn1194.out
ip route add default via 192.168.1.1 dev eth0 table openvpn1194.out
Bonus: Survey your traffic using Monitorix
Install the monitorix package
sudo apt install monitorix
Then edit the monitorix configuration file
vim /etc/monitorix/monitorix.conf
Adapt the configuration to your needs, in the net
field, set your gateway to tun0
and enable the traffacct
reporting and list the clients you wish to monitor with their ip-addresses. Note that this requires your devices to have fix ip addresses — you can set them up in the pihole interface.
# NET graph
# -----------------------------------------------------------------------------
<net>
max = 10
list = eth0, tun0
<desc>
eth0 = FastEthernet LAN, 0, 10000000
tun0 = FastEthernet LAN, 0, 10000000
</desc>
gateway = tun0
</net>
# TRAFFACCT graph
# -----------------------------------------------------------------------------
<traffacct>
enabled = y
max = 20
graphs_per_row = 2
list = john-laptop, smart-tv, bob-ipad, alice-laptop, raspberrypi
<desc>
0 = 192.168.1.XX/32, 0@example.com
1 = 192.168.1.XX/32, 1@example.com
2 = 192.168.1.XX/32, 2@example.com
3 = 192.168.1.XX/32, 3@example.com
4 = 192.168.1.XX/32, 4@example.com
</desc>
<reports>
enabled = n
language = en
default_mail = root@localhost
url_prefix = http://localhost:8080
smtp_hostname = localhost
from_address = noreply@example.com
</reports>
rigid = 0
limit = 100
</traffacct>
restart monitorix and check that monitorix is running and that no errors are present by issuing the command
sudo service monitorix restart
sudo service monitorix status
then navigate to the monitorix homepage below to have a live overview of your gateway status and a report of your devices network activity
http://<ip_or_gateway_hostname>:8080/monitorix
Acknowledgments
This tutorial is heavily inspired by a Github page (in German) detailing the steps to create a NordVPN gateway integrated with pihole.