DNS Adblocking with OpenBSD

You can set up your own DNS resolver, and have an automatically updating adblock list, using only the OpenBSD base system, without any extra packages.

Configuring Unbound

OpenBSD ships with unbound, a DNS resolver. First, configure unbound to listen and allow connections on the appropriate interfaces at /var/unbound/etc/unbound.conf.

server:
    ...
    interface: 0.0.0.0 # binds all ip4 addresses
    ...
    access-control: 192.168.0.0/24 # or the appropriate subnet

Enable forwarding DNS queries to an upstream DNS server:

...
forward-zone:
    ...
    forward-addr: 8.8.8.8 # or whatever upstream you prefer
    forward-addr: 8.8.4.4
    ...

Enable and start unbound by ~# rcctl enable unbound && rcctl start unbound.

Configuring Adblocking

Add an include line to /var/unbound/etc/unbound.conf for a blacklist configuration:

server:
    ...
    include: "/var/unbound/etc/blacklist.conf"
    ...

Entries in blacklist.conf take the form local-zone: "blacklisted.example" always_refuse (to unbound, you are just creating a local zone which handles the name).

It is possible to write a script which will download a blacklist and formats that blacklist appropriately. For example, this one uses this script to automatically set up StevenBlacks blacklist:

#!/bin/sh
ftp -o - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts \
  | sed -e '1,/Start StevenBlack/d' \
  | grep '^0\.0\.0\.0' \
  | awk '{print "local-zone: \""$2"\" always_refuse"}' \
  > /var/unbound/etc/blacklist.conf \
  && rcctl reload unbound

Save this to /root/update-adblocking.sh, set the execute bit, and add a cron entry as root:

~ 0 * * * /root/update-adblocking.sh

Bonus: Tailscale

It is undesirable to have this DNS server exposed to the public. Instead, this one only expose it on its tailnet, which all of its devices are part of anyways. Setting up tailscale on OpenBSD is easy and should just work:

~# pkg_add tailscale
~# rcctl enable tailscaled && rcctl start tailscaled
~# tailscale up

Make sure you modify /var/unbound/etc/unbound.conf to listen on your tailscale interface and accept connections for your tailnet subnet (100.64.0.0/10). Reload unbound.

Both the commerical tailscale control server and headscale support setting nameservers for the tailnet. For the commercial control server, navigate to https://login.tailscale.com/admin/dns and add the tailscale address of your Unbound host to Global nameservers and toggle Override local DNS ON.

Now, unbound will be available to all devices on your tailnet, and tailscale will auomatically configure your devices to use that DNS server.