Unbound DNS with ad-blocking

For those who want to try a different approach to a selfhosted DNS with ad- blocking Unbound can be a good alternative.

I’ve been using Pihole for some time now but was not quite 100% happy with its performance. I use a dedicated Odroid XU4 SBC as my main DNS machine and DHCP server and Pihole undoubtedly is a great solution. It has an amazing interface, it is very efficient and has a great very active community.

One thing that bothered me though about Pihole was the Upstream DNS settings. Although there are several options, none of them assured me that my queries where not being directly or indirectly monitored somehow. So I decided to try the Pihole+Unbound combination and followed this tutorial. I encourage you to read it.

I followed the tutorial but instead of an improvement what I experienced was a mix of performance with several domain resolution issues. I decided to simplify my setup with Unbound only. I was the best thing I could have done.

I use Ubuntu server 18.04 and installing Unbound was easy. Please run this as root.

apt update
apt -y install unbound

It is quite likely that Unbound won’t start right away. You might have to uninstall dnsmaq or whatever is using port 53 on your server. For the configuration of Unbound I used the following tutorial as a reference. My configuration looks like this:

server:
  chroot: ""
  verbosity: 1
  logfile: /var/log/unbound/unbound.log
  log-queries: yes
  use-syslog: no
  interface: 0.0.0.0
  interface-automatic: yes
  port: 53
  do-ip4: yes
  do-ip6: no
  do-udp: yes
  do-tcp: yes
  access-control: 127.0.0.0/8 allow
  access-control: 10.0.0.0/8 allow
  access-control: 172.16.0.0/16 allow
  access-control: 192.168.0.0/16 allow
  access-control: 101.0.0.0/8 allow
  root-hints: "/var/lib/unbound/root.hints"
  hide-identity: yes
  hide-version: yes
  harden-glue: yes
  harden-dnssec-stripped: yes
  use-caps-for-id: yes
  cache-min-ttl: 604800
  cache-max-ttl: 1209600
  prefetch: yes
  num-threads: 8
  msg-cache-slabs: 8
  rrset-cache-slabs: 8
  infra-cache-slabs: 8
  key-cache-slabs: 8
  rrset-cache-size: 256m
  msg-cache-size: 128m
  so-rcvbuf: 1m
  unwanted-reply-threshold: 10000
  do-not-query-localhost: no
  val-clean-additional: yes
forward-zone:
  name:"."
  forward-addr:9.9.9.9@853
  forward-ssl-upstream:yes

You can download the commented version here if you want to understand in more detail the configuration. I named this config file main.conf and placed it on the /etc/unbound/unbound.conf.d/ folder. But before restarting Unbound though we need to download the root.hints file from www.internic.net and place on the /var/lib/unbound folder. I wrote a little script that automates the download. Before running the script you will have to create the log folder for Unbound:

mkdir -p /var/log/unbound

The script for downloading the named.root file:

!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
wget -O /tmp/root.hints https://www.internic.net/domain/named.root
mv /tmp/root.hints /var/lib/unbound/
service unbound restart

I named this script update_named.sh and placed it on the /usr/local/bin folder. Unbound should restart right after the script. You can download it from here if you prefer. Make sure you change the script to executable with the chmod +x command.

As for the ad-blocking I also wrote a script that helps automate things. I named it ads-block.sh and placed it in the same /usr/local/bin as the update_named.sh script.

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
rm /tmp/hosts*
wget -O /tmp/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling/hosts
echo "server:" > /tmp/ads.conf
cat hosts | grep '^0\.0\.0\.0' | awk '{print "local-zone: \""$2"\" redirect\nlocal-data: \""$2" A 127.0.0.1\""}' >> /tmp/ads.conf
cp /tmp/ads.conf /etc/unbound/unbound.conf.d/ads.conf
service unbound restart

You can download this script here. This script downloads the hosts file from the Energized github repository and converts to the Unbound format. I am using the Ultimate version with 700k+ domains. Please check their website https://energized.pro, it’s very cool.

Now let’s automate things with crontab. Run the following:

crontab -e

And now put the next two lines after the editor opens:

@weekly /usr/local/bin/update_named.sh #update root.hints
@weekly /usr/local/bin/ads-block.sh #update ads blocking list

Running these two scripts on a weekly basis should be enough.

Websites load quicker, downloads are faster. Everyone at home noticed the difference. Enjoy!