In the previous post, I wrote an extensive guide on deploying Cloudflare as the upstream DNS for Pi-Hole over HTTPS. This is a follow-up where Cloudflare is replaced with Unbound as the upstream DNS server.

Unbound is a recursive DNS that sits between Pi-Hole and authoritative DNS servers. Cloudflare's 1.1.1.1 and Google's 8.8.8.8 are examples of recursive DNS services. By making Unbound the upstream DNS server for Pi-Hole, you're cutting out other third parties from tracking your web presence. A more detailed read-up of this setup can be found on the official Pi-Hole Unbound guide.

Back on June 11, 2021, Cloudflare DNS experienced outages in the Los Angeles and Chicago area. The result was over an hour of downtime with its DNS service. I was able to avoid that outage by switching over to Unbound and letting it handle domain resolution directly with authoritative DNS servers. This method can be a little slow but DNS caching in Pi-Hole becomes beneficial on subsequent lookups.

Deploying Unbound with Pi-Hole

In the previous post, Pi-Hole and Cloudflare DNS were deployed using Docker Swarm and managed through Portainer with Traefik as the reverse proxy. This will follow the previous guide closely. Let's start by cloning the project:

git clone https://github.com/foureight84/traefik-pihole-doh.git && cd traefik-pihole-doh

This guide assumes that your Docker Swarm, Portainer, and Traefik have been properly configured. If not, follow this guide.

Go to your Portainer web portal and click on App Templates -> Custom Templates and click on the "+ Add Custom Template" button.

This stack uses Unbound Docker image created by Kyle Harding (https://github.com/klutchell)
Image: https://hub.docker.com/r/klutchell/unbound
Github: https://github.com/klutchell/unbound-docker

You'll need to fill in a relevant title for the template. I called mine recursive_dns. Add a description - Pi-hole and Unbound. Make sure the template Type is set to Swarm. Then click on the Upload option and choose the docker-compose.yaml in the dns-unbound folder in the cloned project.

Uploading dns-unbound/docker-compose.yaml as a Swarm template

After it has been uploaded, find the newly created custom template in the list of templates and click edit.
We will need to check that PIHOLE_DNS_=172.18.0.1#5053 environment variable matches your docker_gwbridge IPV4 IPAM Gateway address. Once verified, deploy the stack. That's it!

Deploy the stack once the custom template has been uploaded. The klutchell/unbound Docker image now listens on port 53 by default. Setting the PIHOLE_DNS environment variable to the unbound service name is all that's needed.

While uncached DNS queries may be slower than using Google's public DNS (8.8.8.8) we can see that Pi-Hole's caching outpaces all other public DNS services by far. Plus the millisecond differences in uncached queries are not noticeable in a real use case scenario. It's actually faster than using Cloudflare!

  192.168.  1.  4 |  Min  |  Avg  |  Max  |Std.Dev|Reliab%|
  ----------------+-------+-------+-------+-------+-------+
  + Cached Name   | 0.000 | 0.001 | 0.001 | 0.000 | 100.0 |
  + Uncached Name | 0.015 | 0.060 | 0.187 | 0.052 | 100.0 |
  + DotCom Lookup | 0.015 | 0.049 | 0.081 | 0.022 | 100.0 |
  ---<O-OO---->---+-------+-------+-------+-------+-------+
                     pihole.home
                Local Network Nameserver


    1.  1.  1.  1 |  Min  |  Avg  |  Max  |Std.Dev|Reliab%|
  ----------------+-------+-------+-------+-------+-------+
  - Cached Name   | 0.012 | 0.013 | 0.018 | 0.001 | 100.0 |
  - Uncached Name | 0.014 | 0.069 | 0.355 | 0.077 | 100.0 |
  - DotCom Lookup | 0.014 | 0.022 | 0.048 | 0.009 | 100.0 |
  ---<-------->---+-------+-------+-------+-------+-------+
                     one.one.one.one
                    CLOUDFLARENET, US
                    
    8.  8.  8.  8 |  Min  |  Avg  |  Max  |Std.Dev|Reliab%|
  ----------------+-------+-------+-------+-------+-------+
  - Cached Name   | 0.012 | 0.015 | 0.023 | 0.002 | 100.0 |
  - Uncached Name | 0.014 | 0.038 | 0.158 | 0.040 | 100.0 |
  - DotCom Lookup | 0.014 | 0.016 | 0.025 | 0.002 | 100.0 |
  ---<-------->---+-------+-------+-------+-------+-------+
                       dns.google
                       GOOGLE, US