Nethence Newdoc Olddoc Lab Your IP BBDock  

Setting up Unbound from scratch

on Ubuntu Server xenial or artful

Preliminary Step

Make sure you do NOT have those installed: dnsmasq, resolvconf, NetworkManager. If so, disable or remove them.


Either install some binary package,

apt install unbound

Or build from scratch as follows.

Install a few required libraries,

apt install libevent-dev libexpat1-dev

Note. libevent is optional but as stated in the README, it may be useful in case of using many outgoing ports (1000+). Use with --with-libevent at compilation time.

Package description (apt show libevent-dev) says,

Description: Asynchronous event notification library (development files)
 Libevent is an asynchronous event notification library that provides a
 mechanism to execute a callback function when a specific event occurs
 on a file descriptor or after a timeout has been reached.
 This package includes development files for compiling against libevent.

Fetch the latest version of Unbound and compile it,

#SHA256 checksum: e297aa1229015f25bf24e4923cb1dadf1f29b84f82a353205006421f82cc104e
sha256sum unbound-1.6.5.tar.gz
tar xzf unbound-1.6.5.tar.gz
cd unbound-1.6.5/
./configure --with-libevent
make install

Create a system user for Unbound to drop its priviledges,

useradd -r unbound
grep unbound /etc/passwd
grep unbound /etc/group

Generate the TLS key files for the unbound-control tool to work,

ls -lhF /usr/local/etc/unbound/unbound*.{key,pem}


Check how many cores you have got,

grep ^processor /proc/cpuinfo

Setup the caching name server,

cd /etc/
#ln -s /usr/local/etc/unbound
cd /etc/unbound/
mkdir trash/
mv unbound.conf unbound.conf.d/ trash/

#grep -Ev '^[[:space:]]*(#|$)' unbound.conf > unbound.conf.dist.clean
vi unbound.conf

        verbosity: 2
        num-threads: HOW_MANY_CORES
        interface: ::0
        access-control: allow_snoop
        access-control: ::/0 allow_snoop
        pidfile: "/var/run/"
        root-hints: "named.cache"
        hide-identity: yes
        hide-version: yes
        #do-not-query-localhost: no
        #rrset-roundrobin: yes
        qname-minimisation: yes
        auto-trust-anchor-file: "/var/lib/unbound/root.key"
        domain-insecure: "example.local"
        domain-insecure: ""
        local-zone: "" transparent

        control-enable: yes

        name: "example.local"

        name: ""


Always watch the logs in another window,

tail -F /var/log/syslog

Check the configuration,

unbound-checkconf /etc/unbound/unbound.conf

Run the daemon,

#unbound-control start
systemctl restart unbound

Check the status and see if port 53 is used,

unbound-control status
ls -alhF /var/run/
cat /var/run/
ps auxfw | grep ^unbound
netstat -antupe --inet --inet6 | grep -E ':53[[:space:]]'

To load the configuration changes,

unbound-control reload


Testing local-zone,

host localhost localhost
host localhost

Testing cached public zone,

host localhost
host localhost

Testing cashed stub-zone,

host example.local localhost
host pxe.example.local localhost
host localhost


If Unbound service is listening but refusing to answer queries, fix access-control: as shown in the example above.


Home | GitHub | Docker Hub | Donate | Contact