Artemis | Blog | Portfolio | About & Contact

2019 / 11 / 11 (raw)

Dnsmasq-based DNS blocking

Ads and trackers sucks (nothing new).

They destroy websites, slow down the web, exclude mobile / low power computer users, and trace users in a way no sec. agency could achieve.

I've been using Pihole[^pihole] for a long time, but I really have some issues with their tool:

For this reason, I decided to re-do my DNS-based ad blocking setup and go for a raw dnsmasq[^dnsmasq] server, coupled with the hosts-blocklists project.

This article documents my setup.

Server setup and configuration

As said, I'm using dnsmasq, and the hosts-blocklists project.

The first step is to create a directory in which I'll put the domains and host names.

$ mkdir /usr/lib/blocklists

The README provides the two direct raw links towards the list, which is nice. I'm putting both links in a file, one link per line, at /etc/blocklists-sources.txt, then I'm downloading them into my local directory.

$ cat <<EOF > /etc/blocklists-sources.txt
https://raw.githubusercontent.com/notracking/hosts-blocklists/master/hostnames.txt
https://raw.githubusercontent.com/notracking/hosts-blocklists/master/domains.txt
EOF
$ wget -i /etc/blocklists-sources.txt -P /usr/lib/blocklists

Since I never used dnsmasq on this server, I can just destroy the entire configuration file, and make an almost-empty one with what I want.

$ mv /etc/dnsmasq.conf{,.original}
$ cat <<EOF > /etc/dnsmasq.conf
conf-file=/usr/lib/blocklists/domains.txt
addn-hosts=/usr/lib/blocklists/hostnames.txt
EOF

I can now restart the dnsmasq server.

$ systemctl stop dnsmasq
$ systemctl start dnsmasq

And just to keep it up even after a restart, I'll enable it.

$ systemctl enable dnsmasq

Now we can test it!

Works fine for my own DN.

$ dig @127.0.0.1 artemix.org

; <<>> DiG 9.11.5-P4-5.1-Raspbian <<>> @127.0.0.1 artemix.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56331
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;artemix.org.           IN  A

;; ANSWER SECTION:
artemix.org.        3600    IN  A   104.198.14.52

;; Query time: 155 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Nov 11 18:47:14 GMT 2019
;; MSG SIZE  rcvd: 56

And successfully blocks the cancer that is Google!

$ dig @127.0.0.1 googletagmanager.com

; <<>> DiG 9.11.5-P4-5.1-Raspbian <<>> @127.0.0.1 googletagmanager.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48980
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;googletagmanager.com.      IN  A

;; ANSWER SECTION:
googletagmanager.com.   0   IN  A   0.0.0.0

;; Query time: 32 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Nov 11 18:47:18 GMT 2019
;; MSG SIZE  rcvd: 65

Automating updates

Now I want to be kept up to date, and I don't want to bother with ssh'ing every time.

A quick script called by cron can easily do the job. Note that there is no file ownership control going on here.

#!/usr/bin/env bash

SOURCE_FILES=/etc/blocklists-sources.txt
CACHE_DIR=/usr/lib/blocklists/
DNS_SERVICE=dnsmasq

# Cleanup
rm -rf /usr/lib/blocklists/*.txt
# Download
wget -i "$SOURCE_FILES" -P "$CACHE_DIR"
# Service restart
systemctl restart "$DNS_SERVICE"

Now, I can make it executable and add a cron job for it.

$ chmod +x /usr/bin/update-blocklists
$ crontab -l > $HOME/tmp-crontab
$ echo "0 * * * * /usr/bin/update-blocklists" >> $HOME/tmp-crontab
$ crontab $HOME/tmp-crontab
$ rm $HOME/tmp-crontab

Note that dealing with temporary files is better done with mktemp[^mktemp] instead of by hand. I didn't, for convenience, and instead created the temporary file in the user's home directory.

Now, I have an easy-to-setup, easy-to-maintain ad-blocking server!

^pihole: DNS-based ad blocking, see the official website. ^dnsmasq: DNS masquerade, DNS server project made to simulate and proxy answers (official website). ^mktemp: "Safely creating and using temporary files" - source