HomeLab: AdGuard: Setup Unbound as Iterative DNS

Life-is-short--so--enjoy-it
4 min readNov 2, 2023

--

Bringing up Unbound DNS and adding it to AdGuard as a upstream DNS servers

HomeLab: AdGuard: Setup Unbound as Iterative DNS

Intro

In one of the previous posts, I talked about the one reason why I might consider to use Unbound DNS in my homelab.

It’s mainly not to use the public DNS like Google DNS, Cloudflare DNS, etc. to increase the privacy.

Actually, this reason is not really compelling because Quad9 provides higher privacy as well, and also Quad9 is faster than Google DNS and Cloudflare DNS based on the stats I’ve seen through AdGuard.

Using Quad9 with DoH ( DNS over HTTPS ) might be enough in general.

How does Unbound increase Privacy?

You don’t ask DNS Question to Public DNS.

You asks DNS Question to Unbound DNS, and Unbound DNS will answer to the DNS Question after Unbound DNS ask the question to Root servers, TLD servers, Authoritative DNS servers. ( Iterative DNS Query )

Basically what Unbound DNS does is what Public DNS does.

The downside is that it’s slower since the Unbound DNS has to go through the chains. However, it gets faster since the asked DNS Question is cached.

AdGuard: Unbound DNS replaces public DNS servers in the upstream
Unbound DNS processing time got faster over time. 30ms > 7ms in 48hr

Current Design: AdGuard and Unbound DNS

I am using

In a Raspberry Pi 4 ( 8GB ), AdGuard and Unbound DNS containers are running.

How to Bring up UnBound DNS?

By using the available Dockefile which builds the Unbound DNS from the source, I’ve built the ARM/ARM64 Images.

https://hub.docker.com/r/wowbro/unbound-dns-rpi

And, I also prepared the Docker-Compose YAML file as well.

https://github.com/Gatsby-Lee/moon-rapi/blob/main/unbound_dns/compose.yaml

Step 1: Clone the GitHub Repository

First, clone the GitHub repository that holds the initial configuration for Unbound DNS and Docker-Compose YAML file.

git clone https://github.com/Gatsby-Lee/moon-rapi.git

Step2: Create a Docker bridge network

This is an optional. You can either create the docker bridge network, or remove the “networks” section in the Docker-Compose YAML.

docker network create --driver bridge wowbro-dns-net

Step 3: Bring up Unbound DNS container

  1. go into the unbound_dns sub-directory
  2. run `docker-compose up -d`

Step 3: Test Unbound DNS

Based on the config I set on the docker-compose, the Unbound DNS will expose port=5335.

By using the port, DNS Question can be sent.

dig wowbro.party @127.0.0.1 -p5335

Update AdGuard

There might be more, but in my case I updated three things in AdGuard.

  1. Keep the Unbound DNS as sole upstream DNS server. ( 127.0.0.1:5335 )
  2. Disable DNS Cache in AdGuard. It’s because the DNS Cache will be in Unbound DNS.
  3. Disable DNSSEC. It’s because Unbound DNS will do it.

Add Unbound DNS as sole Upstream DNS servers

Added the Unbound DNS ( 127.0.0.1:5335 ) and commented out all other public DNS servers in the upstream DNS servers.

Once applied, the added upstream status can be tested by executing “Test upstreams”

AdGuard: Unbound DNS is added and all other public dns servers are disabled
Test upstream DNS servers

Disable DNS Cache in AdGuard

The DNS Cache in AdGuard is no longer necessary because Unbound DNS will cache DNS Answers.

Set the “cache size” to 0.

Disable DNS Cache in AdGuard

Disable DNSSEC

The AdGuard doesn’t need to do “DNSSEC” because Unbound DNS will do it while Iterative DNS Query.

Disable DNSSEC

Loads / Performance

In a small homelab, the load in AdGuard and Unbound DNS might not be high.

Loads in AdGuard and Unbound DNS

And, the average DNS lookup time looks ok as well. The average processing time of Quad9 + DoH is around 9ms and Cloudflare + DoH is 13ms.

The Unbound DNS’s performace is 13ms.

Unbound DNS ( Iterative DNS ) performance

--

--

Life-is-short--so--enjoy-it

Gatsby Lee | Data Engineer | City Farmer | Philosopher | Lexus GX460 Owner | Overlander