HOWTO turn Unbound into a Validating Resolver

Written by Rick van Rein in category: Procedures, Security, Technical, Users
Time to pin down the safety of DNS

WikiMedia Commons

This instruction explains how to setup DNSSEC validation with the Unbound resolver for DNS. A companion article on BIND also exists. Note that Unbound has been written for security from the ground up, and carries less history than BIND.

Install. We used Unbound 1.4.5 on Debian Linux. Variations should work; there is even a prebuilt executable installer for Windows. Aside from the general practice to always run the latest Unbound for security reasons, it is specifically good to use 1.4.0 and beyond because it can keep up to date with root zone keys as they roll over.

The best option on Linux is to build it from source code (some distributions offer pre-built packages and Unbound is included in several BSD ports treess). This can be obtained from or where the latter is protected by a CACert-signed certificate in name of the maker’s primary domain,

The build is straightforward enough; by default it installs everything under /usr/local which we will assume because you may not like overriding any old setup in /etc/ and /usr. So you would do:

make install

Configure trust. First, find the the trust anchor for the root zone and verify that it is reliable. Then edit the configfile for Unbound in /usr/local/etc/unbound/unbound.conf. At the very least, set auto-trust-anchor-file: /usr/local/etc/unbound/root-trust-anchor. This file will be automatically updated by Unbound when the root zone publishes updates. Make sure it can find and change it with:

useradd unbound -s /sbin/nologin
mkdir -p           /usr/local/etc/unbound/
touch              /usr/local/etc/unbound/root-trust-anchor
chown unbound:root /usr/local/etc/unbound/root-trust-anchor
chmod go-wx        /usr/local/etc/unbound/root-trust-anchor

This pairs up with configuration settings as follows:

username: "unbound"

Fill /usr/local/etc/unbound/root-trust-anchor with the initial DS record(s) for the root zone. This will usually be needed once, only to be repeated after extended periods of downtime of all your resolvers. What you do is download and possibly validate the XML file as described in and then you construct a DS record by filling in this pattern:


This will end up looking like this (assuming you do this before the root signing key is rolled):

.   IN DS   19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5

You probably want to ensure that the older DLV setup option dlv-anchor-file is disabled unless you have decided to mix this alternate channel with the trust paths for the root zone. Also check that any other trust-anchor-files are gone, as should be the case in a pristine setup of Unbound. If you have been relying on ITAR in the past, this is the time to clean up that temporary trust anchor.

Configure Unbound. Second, instruct Unbound to actually require DNSSEC on all zones that are said to be signed from the root down. Note that this does not apply to the “islands of trust” that may hang somewhere under the root zone but without a trust link all the way up; these can still be validated only through ISC DLV.

Requiring DNSSEC is setup with the following options in the configuration file:

module-config: "validator iterator"

Run. Now fire up Unbound:


Unbound should now pickup the DNSKEY for the configured trust anchor and overwrite the file with it. In doing so, it has used the configured DS record to validate the key. This is a good test to see if updating the file works, and if Unbound accepted your homegrown DS record.

A successful DNS reply would include an Authenticated Data or AD flag, which serves as an assurance to stub resolvers that are not DNSSEC-aware, in this case human eyeballs. A small session showing this flag would look like:

jip$ dig @localhost +dnssec br ds
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

Why query for DS, you wonder? Like any parent/child transition in DNS, the TLDs in the root zone are present in both parent and child name servers. The DS record is the only one that is normally only present in the parent, so this answer is certain to come from the parent, which is the root zone because we are asking for a TLD name. Further down, things start depending on more complex constructions. More on that later!

And that’s all, you’re done. The only thing you may want to ensure is that the new signing keys are pulled in when the root zone rolls over its keys, and specifically, its Key Signing Key. The procedure should be automatic with the setup given
here, but it’s probably better to be safe than sorry.

2 Comments to “HOWTO turn Unbound into a Validating Resolver”

  1. Nick says:

    Very well but:

    useradd unbound -s /sbin/nologin
    mkdir -p /usr/local/etc/unbound/
    touch /usr/local/etc/unbound/root-trust-anchor
    chown unbound:root /usr/local/etc/unbound/root-trust-anchor
    chown go-wx /usr/local/etc/unbound/root-trust-anchor

    The last chown should be chmod

  2. admin says:

    Thanks, well spotted, the post has been corrected!