DNSSEC Validation with Unbound on a Raspberry

To overcome the chicken-or-egg problem for DNSSEC (“I don’t need a DNSSEC validating resolver if there are no signed zones”), let’s install the DNS server Unbound on a Raspberry Pi for home usage. Up then, domain names are DNSSEC validated. I am listing the commands to install Unbound on a Raspberry Pi as well as some further commands to test and troubleshoot it. Finally I am showing a few Wireshark screenshots from a sample iterative DNS capture. Here we go:

This blogpost is part of a series about DNSSEC. Refer to this list for all articles.

It is really simple to operate an Unbound DNS resolver locally on a Raspberry Pi. Merely an installation and some config changes. That’s it. The Unbound package on a Raspbian Linux of Unbound validates DNSSEC by default. Great!


I am using an “old” Raspberry Pi 1 Model B with Raspbian GNU/Linux 7 (wheezy) and kernel 4.1.13+. The version of Unbound which comes with this OS is not the newest one (1.4.17-3+deb7u2), but it fits. The installation is really simple:

The Unbound server starts automatically. Have look at the listening ports with:

Unbound works out of the box for queries from the localhost. In order to allow queries from any host, the configuration file must be edited. It is stored at /etc/unbound/unbound.conf . Note that the config has already DNSSEC validation enabled!

Now, to allow queries add the following lines within the “server:” paragraph:

check the config:

and restart the server:

That’s it! To see a list of all configuration options click here. If you only wanted to install Unbound you’re already done!

-> The following information are only for further analysis etc.

Root Hints & Root Key

Unbound uses a list of the root servers as well as the root dnskey for its DNSSEC validation. Both should be updated regularly to avoid DNS problems in case of real root server changes. To update and use the root-hints file (for the list of root-servers), download the official list:

and use it within the unbound.conf configuration file:

To update the root.key, use the simple “unbound-anchor” program which downloads the root.key file into /etc/unbound/:

And change the auto-trust-anchor-file within the unbound.conf from the default to:

Restart Unbound: sudo service unbound restart .

Done. Click here for more information about the root.hints etc. You SHOULD update the root.hints and root.key files on a regular basis to not run into trouble!

Tests & Status

Here’s a basic test from another Linux machine that queries the Unbound server. Note the ad flag in line 8 which indicates the DNSSEC validation:

Of course, a failure in DNSSEC leads to a SERVFAIL (line 7) without any answer:


In order to view the status of Unbound, use the following commands:  unbound-control status  and unbound-control stats_noreset :

To list the current values of options, e.g. the default values, use unbound-checkconf with the “-o parameter” option, such as:

To dump the cache for further investigations, use this:

Per default, the log messages are sent to syslog. That is, they are stored in the default /var/log/syslog file which can be followed with:

To increase the verbosity level, add/change the verbosity line in the unbound.conf file. The default is “1”. A level of “2” already logs every DNS request. Use it for troubleshooting but be careful with it!

All other details about the Unbound options are listed here.

DNS Server on LAN

To use this Unbound DNS server for all clients in the LAN, it must be announced via DHCP as the DNS server. In my home network I have an AVM FRITZ!Box router which connects to the Internet via FTTH. The settings are as follows. I am using the static IPv4 address as well as the link-local IPv6 address as the DNS server address:

Tested from another Raspberry Pi, this leads to the following resolv.conf entries:

This is a test from a Linux client. Once more, note the “ad” flag in line 7:

However, there are problems when querying the IPv6 address via the “-6” switch:

But it works when the link-local IPv6 address is specified (with the %eth0 interface suffix) directly:

So maybe it’s not a good idea to use the link-local address for the DNS server. Maybe I will disable the “IPv6 DNS Server” option in my home network since the availability of a legacy IP DNS server perfectly fits for dual-stacked clients.

And a web browser GUI test to http://dnssec.vs.uni-due.de looks like that:

DNSSEC Resolver Test okGreat!

Sample Wireshark Screenshots

This is a small tcpdump capture on the Raspberry Pi, displayed with Wireshark. It shows an iterative (!) lookup of “licher.de” with its initial request from the client to the Raspberry Pi, the iterative lookup and the final answer to the client. Also note the “Statistics -> DNS” summary within Wireshark which can be used for troubleshooting, too:


Now, all DNS answers are DNSSEC validated. Really all DNS answer? Well, actually, no. Only those which are DNSSEC signed. However, we solved the chicken-egg problem and are now able to validate DNSSEC answers.

Featured image “IMG_5691” by Sebastian Grasegger is licensed under CC BY-SA 2.0.

4 thoughts on “DNSSEC Validation with Unbound on a Raspberry

  1. Great stuff.

    I’m quite surprised how easy to install and – the first impression – the web response is much faster.
    A very good step by step documentation.
    The best is, it works.

    Thanks for the good description,

  2. Thanks for that .

    Do you also have in your logs message like :

    info: NSEC3s for the referral proved no DS.
    unbound: [7905:0] info: Verified that unsigned response is INSECURE

    I have this almost for each dns query .
    But when I go there : https://www.rootcanary.org/test.html

    it says it’s fine .

Leave a Reply

Your email address will not be published. Required fields are marked *