DNS ad blocking service

By candoizo on Apr 21, 2022
Image post 8

Blocking ads is the only sensible way to use the internet with the advent of tracking, bloat, and reduced browsing speeds. As different advertising markets like Facebook, Google, and Microsoft seek to play catch up against the advent of modern browser extensions through making everything a native app, creating walled gardens of software that cannot be modified, or new creative techniques to integrate them.

Domain name resolution is used to translate human readable domains like example.com into the computer’s ip address which hosts the files from the web server such 1.1.1.1. The operators of domain name resolvers open port 53 to incoming traffic, often on UDP and respond to clients such as computers, phones, and IoT appliances when running their own would be impractical.

How can we block ads without a browser extension? One technique we can leverage is inspecting DNS traffic to identify ads which are served from commonly known ad companies. Generous open source communities and contributors are dedicated to reporting and assembling master lists to protect their networks from these harmful services. Setting up your own local resolver throug dnscrypt-proxy is an easy way to secure this primitive service from a simpler time and supercharges it with support for things like chaining requests, new protocols like DoH, and for our case blocklists.

Requirements

  • service running Linux
  • equivalents of dnscrypt-proxy, wget, unzip, bash, systemd

Steps

  1. Ensure the required packages are installed, I’m using Arch Linux ARM.
sudo pacman -S dnscypt-proxy wget bash unzip
  1. Enable the service at boot
systemctl enable dnscrypt-proxy
  1. Edit the config to enable the blocklist
blocklist_file = "/etc/dnscrypt-proxy/blocklist.txt"

Using a custom DNS resolver

To make use of your new DNS resolver is to make the client devices of yours use this resolver, when in most cases they will use the default one assigned by the device or the router. There are many different ways to accomplish this. On iOS devices, you can change the WiFi setting from Automatic to Manual and enter the local IP address of your device. On certain routers you can install dnscrypt-proxy directly and control it at that source. This is generally most effective to save time fiddling in smart TV settings / etc.

If you cannot set the DNS at a router level, I believe the next best solution is by using a VPN such as WireGuard to enforce the devices to make DNS requests through it, where a dnscrypt-proxy service can be running.

Updating the blocklist

With steps taken to setup our local DNS resolver and force our devices to make request to it, the icing on top is coming up with a good blocklist. Generally the most important qualities of a blocklist are: low false-positive rate, regularly updated, unbiased. In my opinion there are many good candidates for this, and I find it hard to choose between them. To have it both ways I use a Bash script to update my blocklist into one master file from many sources.

Here is a sample of that script. Note many primitive bins are used and other alternatives may be more common on other systems. For example, curl or git instead of wget.

#!/bin/bash
cd /etc/dnscrypt-proxy

# download notracking/hosts-blocklists without git for portability
wget https://github.com/notracking/hosts-blocklists/archive/refs/heads/master.zip -O master.zip
unzip master.zip

# download oisd blocklist
wget https://dblw.oisd.nl/ -O hosts-blocklists-master/dnscrypt-proxy/oisd.txt

# combine unique entries
cat hosts-blocklists-master/dnscrypt-proxy/*.txt | uniq -u > blocked-names.txt

# cleanup downloads
rm master.zip hosts-blocklists-master -rf

# restart DNS resolver to apply new blocklist
systemctl restart dnscrypt-proxy.service

Conclusion

Do yourself the favour so you can enjoy a life with 99% less online advertisements. Use a systemd timer or cronjob to run this weekly to keep your blocklist fresh!