Lead Image © Antonella Grandoni , Fotolia.com

Lead Image © Antonella Grandoni , Fotolia.com

DNSSEC-aware DNS caching with Unbound

Name Game

Article from ADMIN 52/2019
If you don't have access to a DNSSEC-aware name server, you can set up your own with Unbound.

DNSSEC [1] protects against falsified DNS records by cryptographically signing DNS information. The root servers sign the record. One step lower in the hierarchy, the .com DNS servers sign records leading to the servers that provide A records for domains like hanscees.com . DNSSEC was designed to protect against intrusion techniques that result in client systems receiving forged or manipulated DNS data. Because all DNS operations pass through a hierarchy of cryptographically signed records, any computer on the Internet can determine whether a DNS record it receives is valid: it is valid if the signature matches the public key. (Look online for more on how DNSSEC works [2].)

In this way, DNSSEC helps protect against DNS poisoning or man-in-the-middle (MITM) attacks. Even if a false TLS certificate exists, your browser cannot be led to a false IP address, because DNSSEC will reject the spoofed DNS records.

The number of DNS records signed with DNSSEC is continually on the rise. However, because most ISPs don't offer their customers DNSSEC-aware name resolution, chances are, your computers are not yet protected by DNSSEC.

Unbound to the Rescue

Even if your ISP does not offer DNSSEC security, you can easily set it up yourself. This article describes how to build a private DNSSEC-aware DNS resolver, so you won't have to use your ISP's resolver.

I use the Unbound DNS resolver because of its secure-by-design stance. Unbound is a modern successor to Dan Bernstein's djbdns [3], because its design is focused on security and it includes DNSSEC. Developer NLnet Labs describes Unbound as a validating, recursive, caching DNS resolver [4].

I will set up Unbound to resolve DNSSEC and also serve some local zones to my LAN (my local timeserver). Unbound won't perform add-blocking, because I will use a Pi-hole DNS server [5] for that.

I run Unbound on Docker and Docker on Photon OS. Containerizing makes solutions portable and easy to set up. Since I use VMware, I will set up Docker inside a Photon OS virtual machine (VM). Photon OS [6] is a specialized small Linux built for Docker, Kubernetes, and security.

A Photon VM is about 150MB on disk: Photon runs on VMware, as well as Amazon and Azure. Of course, you are free to use another Docker-friendly OS for your implementation. To build the Unbound DNSSEC system, I take the following steps:

  1. Build the Docker layer with docker-compose.
  2. Build and test the Unbound server.
  3. Add some iptables rules and control stuff and update precautions (for Docker)
  4. Be happy and drink coffee

Building the Docker Layer

The first step is to install Docker and docker-compose and test whether Docker restarts after a reboot. For Photon OS, I'll use the following commands (adapt as needed for your operating system):

tdnf install docker docker-compose
systemctl enable docker

After the reboot, the ps command should turn up numerous Docker processes:

ps waux | egrep docker

If Docker does not restart, you should enable it, probably with a systemd command.

To run Unbound in a container, you need to write a YAML definition file. Find a suitable image at Docker Hub and place it in its own directory. (The image I selected from the Docker Hub is mvance/unbound:latest .)

mkdir -p /root/containers/unbound
cd /root/containers/unbound

Now place the contents of Listing 1 into a YAML file:

vi docker-compose.yml

Listing 1

YAML File Contents

version: '2'
    image: mvance/unbound:latest
    restart: always
    container_name: unbound
      - "953:953/tcp"
      - "53:53/tcp"
      - "53:53/udp"
      - unbound_conf:/opt/unbound/etc/unbound/

Now fire up the Unbound container:

cd /root/containers/unbound/
docker-compose up

Usually when you define a YAML file and start the container for the first time, you will see some errors. If you made typos in the YAML file, Docker will complain (and stop). When I launched the container, a problem occurred because systemd was listening on the DNS port (UDP 53).

Google helped me find this solution:

systemctl stop systemd-resolved
systemctl disable systemd-resolved.service
rm /etc/resolv.conf
echo "nameserver" > /etc/resolv.conf

Now port 53 is free and the system can still resolve DNS itself (for updates). When you know your config file is error-free, you can start the container with the -d option to run the container in the background:

docker-compose up -d

However, in the early stages, it is better to omit the -d so you can discover errors that could cause Unbound to stop directly.

Unbound should be working now. You can test the Unbound DNS resolver from another computer with dig:

dig @ www.cnn.com

If you don't have dig, you can install it by installing dnsutils on any Linux system.

The DNS server (at in the preceding example) answered the query successfully, so name resolution is working.

Configuring Unbound

To see if Unbound is resolving DNSSEC correctly, go to the Root Canary test page (Figure 1) [7] and see if you pass.

Figure 1: Check for DNSSEC resolution at the Root Canary website.

This test will only work on your computer if it uses the Unbound DNS server ( in this example) to resolve DNS. On my Ubuntu 18, I changed /etc/resolv.conf to read:


Then, reboot.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.