benjamin.computer

The Holy Trinity of Wireguard, hosts and PiHole

17-09-2020

side note - you can now get my blog posts direct to your email. Simply sign-up to the mailing list here

Since the pandemic of 2020 started, I've been working remotely up in Scotland, away from my A.I. box down in London. Even before COVID-19 struck, I've often been working remotely, attached to some network I don't know or trust. In such cases, a Virtual Private Network (VPN) is absolutely necessary. Not only that but given the appalling state of the internet at the moment, I need a little bit of extra protection. I'd like to talk about three tools I've started using that have really improved things for me over the last few months: wireguard, hosts and Pihole.

Wireguard

In the past, I used Openvpn all the time. I had my own virtual server out on the internet, a couple of machines in my home and my roving laptop. I found keeping the certificates organised a real pain. The speed wasn't great and having to do an awkward split of port 443 traffic was no fun either. When ipv6 entered the mix, OpenVPN became almost unusable, at least for me.

Most people hear about VPNs through adverts and sponsors who talk about privacy, getting around region blocks and protecting your data. But really, a VPN is about connecting certain computers together into a private network, over the top of some existing network. It just so happens that one of your computers on this network can act as a gateway to the wider world. This is the setup I have with Wireguard.

Just before the lockdown started in London, I figured I needed to get remote access to my AI box sorted before I left for Scotland. I spent several frantic hours trying to get OpenVPN to work but to no avail. In the end, I abandoned it and switched to Wireguard.

I couldn't be happier!

Wireguard is so much simpler and elegant! Straight off the bat it worked with only a few minor hiccups. Once I'd ironed these out, I had a reliable connection I could use, despite lacking a static IP address on the AI Box. Oh yes, I forgot to mention - my decent internet connection had failed. With lockdown looming, an engineer wasn't going to be arriving anytime soon. I had to settle for a 4G router and hope for the best! Thankfully Wireguard is pretty quick. It claims to be one of, if not the fastest, VPN solutions out there. Since I've been using it for the past 6 months, I've not noticed any significant lag.

Setting up wireguard is quite straight-forward if you are doing peer-to-peer. Their website has a little video and a guide telling you how it's done. The first thing to note is that there is no concept of a server and client, per-se. Rather the server box is peered with all the peers on your network whereas each client only peers with one peer acting as the server.

The server setup might look something like this:

[Interface]
Address = 10.9.9.1/24
Address = <PUBLIC IP>/22
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 443
PrivateKey = <PRIVATE KEY>

[Peer]
PublicKey = <PUBLIC KEY>
PresharedKey = <PRESHARED KEY>
AllowedIPs = 10.9.9.2/32
Endpoint = <FILLED IN BY WG>

[Peer]
PublicKey = <PUBLIC KEY>
PresharedKey = <PRESHARED KEY>
AllowedIPs = 10.9.9.3/32
Endpoint = <FILLED IN BY WG>

Each client's config also looks somewhat similar:

[Interface]
PrivateKey = <PRIVATE KEY>
Address = 10.9.9.2/24
DNS = 10.9.9.1

[Peer]
PublicKey = <PUBLIC KEY>
PresharedKey = <PRESHARED KEY>
AllowedIPs = 0.0.0.0/0
Endpoint = <SERVER IP>:443

I use port 443 as it's rarely blocked. This does mean the server can't really run a https server but that's fine for now.

One thing I haven't quite figured out is how the routing works in depth. Quite often, local LAN traffic is also sent over wireguard too, which isn't very efficient at all. I'm still working that out but I believe it's something to do with the AllowedIPs setting.

The utility wg-quick will setup the service when given a configuration file. It's also a service on systemd based distributions.

One important issue reared it's ugly head when I was setting up redundancy. Once my internet had been repaired, I began setting up a second backup internet gateway; if the primary connection failed, the second would take over. This seemed fine, until I realised the wireguard tunnels wouldn't reconnect. For whatever reason, no matter which settings I used, wireguard would not reconnect to the server if the gateway changed. In the end, I wrote a watch-dog script that I placed in my root user crontab, running every minute:

#!/bin/bash
handshake=`/usr/bin/wg show wg0 latest-handshakes`
tokens=($handshake)
ctime=`date +%s`
diff=$((ctime-${tokens[1]}))
echo $diff
if (( $diff > 180 )); then
systemctl restart wg-quick@wg0.service
fi

This script checks how long it has been since the last handshake. If it's over 3 minutes then it restarts the service. This worked reasonably well, though there is of course, a small amount of downtime if the connection fails over to the backup. Better than nothing at least. Hopefully, someone else will come up with a better idea in the future.

PiHole

Pihole is a set of programs, bundled together in a nice installer that sets up an alternative DNS server, blocking trackers, advertisers, and other undesirables. It acts as a sinkhole for such things, detecting DNS requests for these ne'er-do-wells and sending them into the void. It's designed to run on a RaspberryPi, hence the name, but it can run on pretty much anything.

I thought I'd give this a try on my local network. Installing on a Pi is really easy, and I was up and running in minutes. The problem was, once I'd plugged it all in, the wifi in our flat really took a drop in performance! I'm still not sure why. It could be the power-supply to the Pi, or the Pi itself; both were in close proximity to the router.

I thought again, and decided I'd run PiHole on the wireguard machine. That way, any machine that connects to the wireguard VPN could also use that machine for it's DNS. This seemed like quite an elegant solution. I added the following line to each peer:

DNS = 10.9.9.1

Boom! That easy! Except it's not really. Most of my Linux machines have a bit of trouble setting the DNS correctly when they connect to a network. Typically, the DNS gets set to whatever the local network says it should be set to, despite the wireguard interface being up. Particularly with my laptop - when it wakes from sleep or connects to a new network - has a tendency to reset the DNS to whatever the default is. One method I've found looks like this:

sudo apt-get install resolvconf
sudo gedit /etc/resolvconf/resolv.conf.d/base

In this file you can alter the defaults and it should work. I've not had it work for me however. There is another method involving dhcpcd:

sudo vim /etc/dhcp/dhclient.conf
prepend domain-name-servers 10.9.9.1;

You'll find that second line commented out with a hash-sign. Delete the hash and hopefully, the changes to resolv.conf should stick.

PiHole has a web interface that allows you to see which of your machines are connecting and what has been blocked. In my case it seems that smarteucookiebanner.upsell-apps.com.herokudns.com is the worst offender. Glad to see it being blocked at least!

hosts

A chap called Steven Black, over on github, has made a repository called hosts. This program collects hostnames and the associated ip addresses from various published lists, collating them into your /etc/hosts file. These entries are redirected to 0.0.0.0, effectively blocking them.

I've found hosts to be really useful when used with cron. During the day, I have been distracted by things like twitter and I've wanted to block social media sites generally, while I'm working. This program groups sites into categories such as social media, spyware, advertising etc, and lets you choose which ones you want to block. You can setup something like this:

0 10 * * * python3 /home/you/hosts/updateHostsFile.py -a -r -w /home/you/hosts/whitelist.txt -e social fakenews gambling && service network-manager restart  
0 17 * * * python3 /home/you/hosts/updateHostsFile.py -a -r -w /home/you/hosts/whitelist.txt -e fakenews gambling && service network-manager restart

This works on ubuntu like distributions, but the manual has guides for other operating systems. I quite like the fakenews option. I feel like we could all do with a little less misinformation in our lives these days.

Have things changed?

I've noticed that my productivity has gone up a little, but more than anything else, I just feel a little more chipper. Keeping off social media, not having as many adverts thrown at me, and the knowledge that I'm a little harder to track and market at has made me feel just a little bit happier. Given current events I'll take whatever little victories I can. I'd highly recommend these tools.


benjamin.computer