Block ads network-wide via Pi-Hole, FTL engine and DNS over HTTPS (DoH)

These days, advertisements can be found everywhere on the internet and our mobile devices. While some of them may be just fine and unintrusive, others are just a pain in the shitter. Your shitter, to be precise.

The reason for this is not only because ads are annoying. No, they also tend to follow you around and collect data about you to display ads that may be more fitting to you. This is a privacy nightmare! On top of that, they're just a waste of time. I think, most of us will search on the web in order to buy the new waifu pillowcase we desire, right? No need to shove flashing, misleading and intrusive pieces of crap right into our eyeballs. And don't let me get started on ads on YouTube! Damn!

But what should we do about it?

There are certain ways around ads. The most popular way is to just use an adblocker in your browser. However, this only blocks ads in said browser and doesn't work system-, yet network-wide! But don't worry, as I'm going to show you how to perform sclerotherapy on your network, so the pain in the butt will fade away!

In this guide, we're focusing on our whole network instead of installing an adblock solution on every single device respectively. We're going to do this with a marvellous piece of software called Pi-Hole, which acts as a DNS resolver on our local network that checks if the requested domain is on a blacklist. If so, the DNS resolver will answer with an error, resulting the browser to display blank space instead of an ad and if the request is fine, it will be forwarded to the upstream DNS server and is even cached for later on, resulting in even faster loading of your favorite porn websites.

Prerequisites

I should note that whenever I tell you to create / edit files or start / stop services, that you should do it as root (or via temporary escalated privileges, e. g. by using sudo).

The installation

After connecting to the device that'll act as a server via SSH or after planting your thicc ass right in front of it, log in as a regular user. We don't want to run the AUR helper as root.

We're going to pull Pi-Hole itself, as well as the cloudflared daemon, about which I'll talk later on. Now, install the needed packages as follows:

yay -S pi-hole-server cloudflared-bin

This is going to pull all needed dependencies as well. You can install cloudflared instead of cloudflared-bin, if you want. This will compile cloudflared from source instead of pulling the binary version. Might as well install Gentoo if you're into that sort of time-wasting shizzle.

In order to keep DNS resolution working on our local machine, append the following to your /etc/hosts file:

127.0.0.1       pi.hole     hostname

I think it's obvious that hostname has to be replaced with the actual hostname of your computer, so if your computer's name is “big-tiddy-goth-gf”, name it that.

Next up, we're going to configure NGINX and PHP-FPM in order to make the Pi-Hole web interface work. If not already installed for your other sexy projects already, install that shit via following command:

yay -S nginx-mainline php-sqlite

Now, open up /etc/nginx/nginx.conf and enable GZip compression by editing the file to contain the following in the http section:

[...]
gzip                on;
gzip_min_length     1000;
gzip_proxied        expired no-cache no-store private auth;
gzip_types          text/plain application/xml application/json application/javascript application/octet-stream text/css;

include             /etc/nginx/conf.d/*.conf;
[...]

Make sure to create the folder for NGINX vhost configuration files:

mkdir /etc/nginx/conf.d

The pi-hole-server package actually contains a premade file for an NGINX vhost, so just copy that …

cp /usr/share/pihole/configs/nginx.example.conf /etc/nginx/conf.d/pi-hole.conf

… and edit the file to make use of UNIX sockets (faster) and configure the vhost accordingly. Change the following lines to look something like this:

[...]
fastcgi_pass    unix:/run/php-fpm/php-fpm.sock;
fastcgi_param   VIRTUAL_HOST "192.168.44.6";
[...]

Once again, change the IP adress in the VIRTUAL_HOST parameter to whatever IP your server has (or use a hostname, if you use hostnames in your LAN).

Note that PHP has to have the SQLite extension enabled in order to work, because Pi-Hole stores it's statistics in a SQLite database and the webinterface pulls data from there for all the fancy-ass graphics. So go ahead and create /etc/php/conf.d/pihole.ini and paste the following in it:

[PHP]
extension=pdo_sqlite
extension=sockets
extension=sqlite3

Due to PHP being hardened like a Thai tranny's dick since version 7.4, we'll have to override the systemd service unit for PHP-FPM in order to make it work and not bitch around like a hooker you smash and dashed. To create an override, run:

systemctl edit php-fpm

and paste these lines to specifically allow read and write operations to the files in question:

[Service]
ReadWritePaths = /srv/http/pihole
ReadWritePaths = /run/pihole-ftl/pihole-FTL.port
ReadWritePaths = /run/log/pihole/pihole.log
ReadWritePaths = /run/log/pihole-ftl/pihole-FTL.log
ReadWritePaths = /etc/pihole
ReadWritePaths = /etc/hosts
ReadWritePaths = /etc/hostname
ReadWritePaths = /etc/dnsmasq.d/
ReadWritePaths = /proc/meminfo
ReadWritePaths = /proc/cpuinfo
ReadWritePaths = /sys/class/thermal/thermal_zone0/temp
ReadWritePaths = /tmp

(On some systems, /sys/class/thermal/thermal_zone0 doesn't exist, which will cause the service startup to fail. In this case, just comment out or remove that line)

Congratulations, you installed Pi-Hole!

Encrypt your DNS requests

Now, let's talk about DNS over HTTPS (DoH). Well, to put it straight gay: Your ISP can see all DNS requests you make. Since I use CloudFlare as my DNS provider of choice, I use their Cloudflared Argo tunnel to tunnel all DNS requests to them, encrypted via HTTPS. This also makes it impossible for evil dudes to use DNS cache poisoning on you. Another plus is that CloudFlare has tons of server locations all over the world, usually making DNS requests faster.

We already installed cloudflared-bin before, so let's just configure it by editing /etc/cloudflared/cloudflared.yml. Change the following settings:

[...]
proxy-dns-port: 5053
proxy-dns-address: 127.0.0.1
[...]

Almost done! Finishing up …

We're almost there. If you're running Pi-Hole on a Raspberry Pi with a delicate SD card as boot media or even if you run it on a server with an SSD, you should reduce the commits to Pi-Hole's database to prevent frequent writes to the file system. This will prolong the life span of your flash-based media just in the same way shady ads promise to make your PP longer. Edit /etc/pihole/pihole-FTL.conf, uncomment (remove the “#” at the beginning of the line) and change the following value to have it commit queries every 60 minutes:

[...]
DBINTERVAL=60.0
[...]

Now, shut down and disable systemd's DNS resolver systemd-resolved, as Pi-Hole's FTL engine is a fork of dnsmasq and it will conflict with that:

systemctl disable --now systemd-resolved

Next, start and enable NGINX, PHP-FPM (if not running already), as well as Pi-Hole and Cloudflared:

systemctl enable --now nginx php-fpm pihole-FTL cloudflared@cloudflared

If you have crotch goblins at home, you might want to set a password for your web interface, as Pi-Hole can conveniently be used to restrict access to sites for specifc computers or groups of computers. Do it like this:

pihole -a -p

Enter the web interface

Great. Pi-Hole and Clouflared are up and running. The webinterface can be reached via http://your-vhost-name-or-IP/admin. Once there, type in the password you just set and head to Settings ➡️ DNS. Uncheck all the upstream DNS servers and add your own custom one on the right hand side. Enter the address and port of your local Cloudflared instance like this:

127.0.0.1#5053

Also, be sure to check “Never forward non-FQDNs” and “Never forward reverse lookups for private IP ranges” to enhance security. You can check “Use DNSSEC”, but it doesn't work with Cloudflared anyway. Once done, it should look like this:

Another thing you should definitely do is to go to your router's webinterface and look for it's DNS settings to make all DHCP clients use your Pi-Hole as default DNS server. Put your Pi-Hole's IP address there. For me, it looks like this, but it differs from router to router:

Tip: Some devices (like the Google Chromecast) have hardcoded DNS servers to circumvent DNS filtering. To prevent this, you can add static routes to redirect 8.8.8.8 and 8.8.4.4 to your Pi-Hole:

Some closing words

Running Pi-Hole feels great. It's like standing naked on your front porch and feeling a summer breeze around your dick. Less ads, less trackers, no ads in mobile apps, etc. However, it's not all fun and games.

Due to the way some ads and trackers work, this solution isn't going to block everything. For example, YouTube ads can't be blocked using this approach, as ads are served through the same domain as regular videos. You'll sometimes get ugly error messages in web browsers, etc. This is why I recommend using a regular adblocker in conjunction with Pi-Hole where feasible. I recommend uBlock Origin for Firefox or Chrome. For Android, I recommend using the new Firefox Fenix build (or the FOSS variant IceRaven with more extensions supported, not yet on F-Droid, though) with uBlock Origin, again. Great browsers. Such great. If you're using an iPhone, this website is not for you. Just go the fuck away.

Some other things you should look into are Pi-Hole's other features. You could retire your router's DHCP server and let Pi-Hole take over this job. You can also set filtering rules for specific devices, etc.

If you're looking for a way to manage your Pi-Hole from Android, look no further than Flutterhole. It makes my hole flutter. And it's fully open source.

One last thing

As once said by a popular artist for j-pop music:

“Thou shalt not run Pi-Hole as an open resolver!”

Shakespeare

Because if you do, you're an asshole and I'll kick you in the face. “But why?”, you may ask. Valid question. Your Pi-Hole could be easily abused for a DNS amplification attack and other shit, making your ass liable.

If you want to make your Pi-Hole available from everywhere, you should look into WireGuard. I'll cook up another guide for that later on.

Last updated: 16.10.2020, Iceweasel for Android was rebranded to IceRaven, because it doesn't have any actual correlation to the Iceweasel browser