Becoming more proactive in your home network's activity can allow you more privacy, higher availability, and more convenience. At the end of this guide, you will
be able to securely connect to your home network from almost anywhere. We'll assemble a network wide adblocker instead of only limited to your browser in scope.
Key Features
The Raspberry Pi: A tiny, and relatively affordable computer.
Wireguard: A super secure, ficticiously fast VPN.
Pi-hole: A DNS Sinkhole for mitigating Ads, Malware, and Tracking.
Procedures
The Raspberry Pi
We'll be using a Raspberry Pi 4 for this project. I'll walk you through the intial set up of the device. This set up is a headless (no monitor required) set up.
So, admin access to your home router is required! An SD card to USB adapter is also necessary.
Download the Raspberry Pi Imager. Install the imager, and run the imager application.
Insert the SD Card into the adapter, and plug it in to your PC. Back on the Imager, under 'Choose Device', select your Raspberry Pi 4, under 'Choose OS', select
Raspberry Pi OS (other) >> Rasoberry Pi OS Lite (64-bit), and under 'Storage', select your attached SD card storage device. Hit 'Next', then 'Edit Settings'.
Now this part is very important, in the Settings Menu: input a username and password. Then, head over to the 'Services' tab, and check the box for 'Enable SSH'!
Now connect your Raspberry Pi directly to your router using an Ethernet cable. Power on the Raspberry Pi. Allow it about 10 minutes to boot, and to connect to your router and
Internet.
Download the MSI for Putty (an SSH client to connect to your Raspberry Pi). Install and launch it.
Navigate to your router's admin panel. For this tutorial, mine is http://192.168.0.1 | Yours may be different depending on your router. The interface you see there will also differ, but here's mine:
Navigate to the DHCP Clients list, and look for your Raspberry Pi's name. Look for its IP. Copy the IP for your Raspberry Pi, then head back to the Putty SSH application.
Enter the IP into the 'Host Name' box, and hit 'Open'.
Verify the SSH server (your Raspberry Pi), then accept the warning. Enter the username and password that you configured earlier in the Raspberry Pi Imager settings. Then, enter the commands:
sudo apt update && sudo apt upgrade -y
Wireguard
This is easily my favorite VPN. It has robust security. It's really fast. It's free. Be sure to check out their website,
and read a little about how it works. If you have time, read the technical whitepaper. It's about 20 pages.
It's pretty insightful, and reassuring from a safety standpoint. "WireGuard eschews puzzle-solving constructs..."
Now, we can proceed with the installation instructions from the Wireguard website, but the package of shell scripts for installing either Wireguard or OpenVPN,
Pi-VPN, is more useful. To kick off the installation, run the command: curl -L https://install.pivpn.io | bash
Once the menu pops up, hit 'Ok' to continue until we reach the menu asking us about DHCP. We can configure this in the router later. Hit Enter until we are asked to choose either Wireguard or OpenVPN.
Wireguard is the default, so hit Enter and continue. When we get to 'Default Wireguard Port', we can leave it at the default 51820. The next menu we stop at is 'DNS Provider',
where we can leave Quad9 as the default (we'll change this later) and continue.
Now, the menu 'Public IP or DNS' is important. Here, we can leave the default. I may make a tutorial later about using
a dynamic DNS client, but for now, here's a tutorial if you want to get ahead. Hit Enter all the way to the last menu
where we'll select the option to 'Reboot Now'. Then reconnect to your Raspberry Pi through Putty SSH after a couple minutes.
While it's rebooting, let's head back to the router admin panel. We must port forward. Again, your router might be different from mine, but there are lots of tutorials for this online. Take
a look at the image I attached below.
The end goal is to have the 'Service Port' ('External Port' on some devices) forwarding port 51820 to your Pi's internal IP (the IP you use for SSH).
The protocol Wireguard uses is UDP, not TCP. I strongly recommend you do not input TCP/UDP. Now, we can enable the port and save the configuration. Disclaimer:
Port forwarding may be ineffective if your Internet Service Provider uses Carrier Grade-Network Address Translation.
Now, the really fun part! Back on your SSH connection to your Raspberry Pi, run the command:
pivpn --help
Take a read, then enter the command:
pivpn -a Input a name. Then enter the command: pivpn -qr Select your client. That's the QR code you can use to connect your phone through
the Wireguard App. Alternatively, if you have the desktop/laptop Wireguard client application, run the commands:
cd ~/configs then cat [yourClientName].conf Behold! The config file for a single peer, or 'Cryptokey Routing Table' (see the whitepaper).
On the Windows Wireguard application, click 'Add Tunnel' > 'Add Empty Tunel'. Now paste the Cryptokey Routing Table to the config file. Save it, then activate your VPN!
Turn on the client on your phone while connected to LTE, then Google you IP address. It should match your home router's public IP address.
Note the 'DNS = 9.9.9.9' in the config file/Cryptokey Routing Table. We'll change this after Pi-Hole.
Pi-Hole
The Domain Name System is a service that allows computers to resolve human website names into a computer usable format for finding websites.
Now, Pi-hole markets itself as a Network Wide Ad-blocker, though it is much more. What's so good about network wide ad-blocking? Well, imagine you acquired a super cheap TV from a sketchy Craigslist purchase,
you go home, and turn it on, and boom! It doesn't expload, but you're served with ads on the homescreen. You can't install an ad-blocker from the TV app store, but you can install Pi-Hole!
Back on the Putty SSH terminal, let's run the command:
curl -sSL https://install.pi-hole.net | bash
Hit Enter, donate, hit Enter. Once again, we're prompted with configuring a static IP on our router. Let's do that now :)
Head over to your router admin panel, look for 'DHCP' and 'Address Reservation'. Again, this may differ from router to router. We need the MAC address of the Raspberry Pi.
Back on the Raspberry Pi, enter the command: ifconfig
We're looking for the eth0 interface, and the following format. The MAC address is highlighted with bold:
eth0: flags=4163 mtu 1500
inet 192.168.0.102 netmask 255.255.255.0 broadcast 192.168.0.255
ether e4:5f:01:3d:11:47 txqueuelen 1000 (Ethernet)
Made an oopsie here in the photo, meant to input 192.168.0.102.
Now save that configuration, and there you go. Your router will only ever assign your Raspberry Pi that IP. So, hit continue and now you're on 'Choose an interface'. The default eth0 is appropriate.
On the 'Select an Upstream DNS Provider', I typically go with Cloudflare. Though at the time of this typing, I use a Unbound for a recursive DNS server with caching. Continue, and proceed with
'Steven's Blacklist', then continue with installing with Web Admin interface. Allow the installation of lighttpd, and enable query logging while showing everything. Now the installation will complete.
Run the command: pihole -a -p [password]
Now launch your web browser and head to http://[RASPBERRY PI IP ADDRESS]/admin and login using the password you configured.
Navigate to the 'Adslist'. Here we'll see where we can add more lists of known and common ad servers, tracker servers, crypto miners, and so on.
These lists are often updated by the creators, but to make the update effective for us, we must
navigate to 'Tools' >> 'Update Gravity', and update your lists from there.
Finally, let's put this thing to work! Head back to your router, and look for 'DHCP' again.
We want to change the 'Primary' and 'Secondary' DNS Server addresses to our own Raspberry Pi. Mine is at 192.168.0.102. Save the configuration, and restart your router.
Now all your devices' DNS requests will be forwarded to and filtered by your Raspberry Pi.
And there you have it, we blocked our first unwanted DNS querying. Feel free to block any suspicious queries. Though, some things may break (including when using certain or too many adlists).
You can always unblock them from within the 'Domains' menu.
As a last note, rememebr the 'DNS = 9.9.9.9' from the Wireguard config file / Cryptokey Routing Table? Let's change that '9.9.9.9' to '[YOUR RASPBERRY PI IP ADDRESS]'. Now,
when connected/peered to the Raspberry Pi via Wireguard, your ads can be blocked as well.
You will have to configure the DNS separately on every client individually, or you can run the command below to edit the config file for the wg0 interface:
sudo nano /etc/wireguard/wg0.conf
Problems and Troubleshooting
This section highlights issues encountered during the project and the steps taken to resolve them:
Problem 1: The Wireguard Server** we installed on the Raspberry Pi using Pi-VPN can sometimes be a little buggy upon the first installation.
However, Pi-VPN does include a bash script that debugs common issues with the Raspberry Pi peer. On your Putty SSH client, un the command below if you encounter issues:
pivpn -d
** According to the whitepaper, Wireguard does not officially designate a server/client. There is, however, the initiator, and the responder. Both devices in a tunnel are peers.
Problem 2: Wireguard desktop client loops: A few years ago, I ran in to this problem out of the blue on my Windows devices. After looking at Reddit and the Wireguard logs,
I found that the problem was that Windows enables "forwarding" on the IPv4 interfaces after system updates. The issue occurs when the Wireguard tunnel is activated on Windows, and forwarding is enabled.
The solution I found are the following commands within a PowerShell window with admin privileges:
netsh interface ipv4 => (I wrote them separately in the photo below)
show interfaces => Identify your Ethernet or Wi-Fi interface by name or by number.
set interface [interface name/number] forwarding=disabled
Now, here's something I noticed when doing a very risky packet capture (pcap) on the Wireguard virtual interface:
There appears to be a routing loop. The packet lengths get bigger and bigger (+64 bytes each time), and eventually they start segmenting.
The source as destination addresses also changed from the otherwise expected Wireguard Tunnel range for your network (something like 10.5.3.0/24),
to your device's LAN IP, and home network's public IP, respectively.
Finally, look at the number of packets sent and the number dropped at the bottom right. That occurred in less than 3 seconds. Had I continued, my computer would have frozen then restarted! (a third time!)
Again, the technical whitepaper had some good material on this. Read the section about Forwarding Information Base (FIB) Route Lookups.
With forwarding enabled, the local, typical IP Routing Table does not appear to make an exclusion / exception for forwarding all traffic (0.0.0.0/0) over to the Wiregurad (wg0) interface when the WG tunnel is enabled.
The routing exclusion being that the traffic destined for the other peer, your Raspberry Pi, accessed through your public IP:PORT combination.
So, traffic keeps going back to the wg0 interface instead of going out to the Internet, encrypting and encapsulating over and over. Very resource intensive!
Conclusion
There you have it, you can now connect back to your home network securely using the Wireguard VPN. Your network is a litte more private and less disturbed from unncessary DNS
queries. This also makes your network a little faster since less traffic (DNS particularly) goes out to the Internet.