Unbound DNS Server

OpenBSD is contemplating replacing BIND with the Unbound recursive DNS server and the NSD authoritative DNS server. As I need a client-facing nameserver that performed DNSSEC validations, I decided to try Unbound.

I started by installing the latest OpenBSD amd64 snapshot with the ports tree, then built /usr/ports/net/unbound without any special options. As unbound chroots into /var/unbound after startup, all configuration files and device nodes are under that directory.

You’ll also need a current root hints file. Get it from the Internic FTP server.

# cd /var/unbound/etc
# ftp ftp://FTP.INTERNIC.NET/domain/named.cache

The default configuration, /var/unbound/etc/unbound.conf, includes dozens of options, but all of them have sensible defaults. Most you only set if you run a very heavily loaded server, want to log queries, or need to force the server to bind to a specific IP address. We do need a few unbound.conf settings. First, set the path to the current root server hint file you just downloaded.

root-hints: "/var/unbound/etc/named.cache"

Do not run a recursive DNS server that accepts queries from all IP addresses; your server will be used as a node in a DDOS attack. Use the access-control statement to restrict which addresses can make queries. Start by blocking queries from all addresses, then explicitly list address you will accept queries from, like so:

access-control: refuse
access-control: allow
access-control: allow

At this point, unbound can now answer recursive queries. Start unbound:

# /usr/local/sbin/unbound
[1297787446] unbound[10557:0] warning: increased limit(open files) from 128 to 4140

Now test from a machine with an IP address specified in an access-control statement.

# dig www.michaelwlucas.com @nstest
www.michaelwlucas.com. 7200 IN A

We’re getting answers. You have a working Unbound server! Now that we’ve gotten this far, let’s break it by trying to add DNSSEC validation. While not all top level domains are DNSSEC-signed, and most Web browsers and operating systems are not yet DNSSEC-aware, when that day comes I don’t want to come back and reconfigure my server. To add DNSSEC to Unbound, you must fetch the root zone’s public key and tell Unbound where to find that key. To identify the root zone,

auto-trust-anchor-file: "/var/unbound/etc/root.key"

Now fetch the root key and store it in /var/unbound/etc/root.key.

# /usr/local/sbin/unbound-anchor -a "/var/unbound/etc/root.key"

Restart Unbound, and query for DNSSEC on the root zone. The ad flag indicates that you received a DNSSEC reply. You’ll also see security resource records, or RRSIGs.

# dig . @nstest +dnssec

;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1

. 86400 IN RRSIG NSEC 8 0 86400 20110222000000 20110214230000 21639 . VxTx/DhLO26TClKW4UUby50Qmw3gmUewRzOIVFT2pw34mm6XSW+Fo5uDrUjgpXpQRkTUJlyLpxXm5843xdO9UNQOWIRoRAcaGCdbykc5Bvr2R+ho1yOYmo+3ExpvuIn7xxtm+1Yjl6RiVWckXVuqESKRmd6cvu2uM+nlmxd f/M=

That’s it! Your Unbound recursive DNS server is ready to answer queries and validate DNSSEC.

To automatically update the root key and start Unbound at boot, I added the following to /etc/rc.local:

echo 'anchoring unbound'
/usr/local/sbin/unbound-anchor -a "/var/unbound/etc/root.key"
echo 'starting unbound'

There’s no need for an Unbound shutdown procedure: just killing the process will suffice.

15 Replies to “Unbound DNS Server”

  1. Super useful little guide. I hadn’t even realized this was out there. Thanks, just set it up on my OpenBSD box.

  2. I love it, but the only thing holding me back is the need for DDNS for a stable of dynamic IPs. Well, not so much need as convenience.

  3. i have been aware of the idea of unbound/nsd going into base, but i haven’t found time to try them out yet! your article may give me the excuse to make time, however. thanks!

  4. Thanks for this article. It is, however, unnecessary to download the root hints file. It can be copied from /var/named/etc/root.hints.

  5. Michael,

    I used top of tree clang static analyzer to find out that OpenBSD userland of yesterday has 2566 “Dereference of null pointer” bugs, of which bind has 1715. Bind has a insanely high rate of null deref’s.


  6. I installed the binary package using pkg_add on 4.8-stable – there is no /usr/local/sbin/unbound-anchor as referenced above!

  7. Casey, that’s interesting. The OpenBSD folks expect the binary package to be exactly the same as what you build from a port. You might have found a problem. I’d suggest asking on openbsd-misc.

  8. I’ve installed unbound from the ports tree using an up to date sources:

    # uname -a
    OpenBSD bureau10 4.8 RPS#3 i386

    # pkg_info -d unbound
    Information for inst:unbound-1.4.5

    Unbound is an implementation of a recursive DNS resolver, that does caching
    and DNSSEC validation.

    Maintainer: Jakob Schlyter
    WWW: http://www.unbound.net/

    There does not seem to be any trace of unbound-anchor:

    # ls -l /usr/local/*/*unbou*
    -rw-r–r– 1 root wheel 19870 Mar 28 14:25 /usr/local/include/unbound.h
    -rw-r–r– 1 root wheel 2175758 Mar 28 14:25 /usr/local/lib/libunbound.a
    -rw-r–r– 1 root wheel 891 Mar 28 14:25 /usr/local/lib/libunbound.la
    -rwxr-xr-x 1 root wheel 1424010 Mar 28 14:25 /usr/local/lib/libunbound.so.2.4
    -rwxr-xr-x 1 root wheel 1650576 Mar 28 14:25 /usr/local/sbin/unbound
    -rwxr-xr-x 1 root wheel 1368732 Mar 28 14:25 /usr/local/sbin/unbound-checkconf
    -rwxr-xr-x 1 root wheel 1386843 Mar 28 14:25 /usr/local/sbin/unbound-control
    -rwxr-xr-x 1 root wheel 5255 Mar 28 14:25 /usr/local/sbin/unbound-control-setup
    -rwxr-xr-x 1 root wheel 35627 Mar 28 14:25 /usr/local/sbin/unbound-host

    Also… are you trusting unbound-anchor to get you the correct public key for the root? Should this not be performed with a little bit more care?

    Thanks again for the great write up.


  9. great article i have try it and working and will be happy replace bind in my server.
    any way where i can get root.key ?

Comments are closed.