- Unbound has supplanted the Berkeley Internet Name Domain (BIND) as the default, base-system name server in several open source projects, where it is perceived as smaller, more modern, and more secure for most applications.
- 1 Installation
- 2 Configuration
- 3 Usage
- 4 Tips and tricks
- 5 Troubleshooting
- 6 See also
Install the package.
Additionally, the #DNSSEC validation.package is required for
A default configuration is already included at
/etc/unbound/unbound.conf. Additionally, there is a commented sample configuration file with other available options located at
/etc/unbound/unbound.conf.example. The following sections highlight different settings for the configuration file. See for other settings and more details.
Unless otherwise specified, any options listed in this section are to be placed under the
server section in the configuration like so:
server: ... setting: value ...
See also #Example configuration.
Local DNS server
See Resolv.conf#Testing on how to test your settings.
Check specifically that the server being used is
127.0.0.1 after making permanent changes to resolv.conf.
You will also need to setup unbound such that it is #Forwarding queries to the DNS servers of your choice.
For querying a host that is not cached as an address the resolver needs to start at the top of the server tree and query the root servers to know where to go for the top level domain for the address being queried. Unbound comes with default builtin hints, but it is good practice to use a root-hints file since the builtin hints may become outdated.
First point unbound to the
Then, put a root hints file into the unbound configuration directory. The simplest way to do this is to run the command:
# curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
It is a good idea to update
root.hints every six months or so in order to make sure the list of root servers is up to date. This can be done manually or by using Systemd/Timers. See #Roothints systemd timer for an example.
To use DNSSEC validation, point unbound to the server trust anchor file by adding the following setting under
Also make sure that if general #Forwarding queries have been set to DNS servers that do not support DNSSEC, then comment them out; otherwise, DNS queries will fail. DNSSEC validation will only be done if the DNS server being queried supports it.
To test if DNSSEC is working, after starting
$ unbound-host -C /etc/unbound/unbound.conf -v sigok.verteiltesysteme.net
The response should be the ip address with the word
(secure) next to it.
$ unbound-host -C /etc/unbound/unbound.conf -v sigfail.verteiltesysteme.net
Here the response should include
(BOGUS (security failure)).
Additionally you can use drill to test the resolver as follows:
$ drill sigfail.verteiltesysteme.net $ drill sigok.verteiltesysteme.net
The first command should give an
SERVFAIL. The second should give an
trusted-key.key can become out of date. To have unbound automatically update the file, use the following instead of the above configuration:
unbound user needs write permissions to the directory:
# chown root:unbound /etc/unbound # chmod 775 /etc/unbound
Lastly, one can also automatically check for updates before unbound is run by adding the following to the systemd unit under the
[Service] section using a drop-in snippet:
ExecStartPre=/usr/bin/unbound-anchor -a /etc/unbound/trusted-key.key
If you only want to forward queries to an external DNS server, skip ahead to #Forward all remaining requests.
Allow local network to use DNS
If you have a local network which you wish to have DNS queries for and there is a local DNS server that you would like to forward queries to then you should include this line:
Include local DNS server
To include a local DNS server for both forward and reverse local addresses a set of lines similar to these below is necessary with a forward and reverse lookup (choose the IP address of the server providing DNS for the local network accordingly by changing 10.0.0.1 in the lines below):
local-zone: "10.in-addr.arpa." transparent
This line above is important to get the reverse lookup to work correctly.
forward-zone: name: "mynetwork.com." forward-addr: 10.0.0.1
forward-zone: name: "10.in-addr.arpa." forward-addr: 10.0.0.1
You can set up the localhost forward and reverse lookups with the following lines:
local-zone: "localhost." static local-data: "localhost. 10800 IN NS localhost." local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" local-data: "localhost. 10800 IN A 127.0.0.1" local-zone: "127.in-addr.arpa." static local-data: "127.in-addr.arpa. 10800 IN NS localhost." local-data: "127.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 2 3600 1200 604800 10800" local-data: "184.108.40.206.in-addr.arpa. 10800 IN PTR localhost."
Forward all remaining requests
To use specific servers for default forward zones that are outside of the local machine and outside of the local network add a forward zone with the name
. to the configuration file. In this example, all requests are forwarded to Google's DNS servers:
forward-zone: name: "." forward-addr: 220.127.116.11 forward-addr: 18.104.22.168
You can specify the interfaces to answer queries from by IP address. The default, is to listen on localhost.
To listen on all interfaces, use the following:
To control which systems can access the server by IP address, use the
access-control: subnet action
access-control: 192.168.1.0/24 allow
action can be one of
deny (drop message),
refuse (polite error reply),
allow (recursive ok), or
allow_snoop (recursive and nonrecursive ok). By default everything is refused except for localhost.
unbound.service systemd service.
Remotely control Unbound
unbound ships with the
unbound-control utility which enables us to remotely administer the unbound server. It is similar to the pdnsd-ctl command of .
Setting up unbound-control
Before you can start using it, the following steps need to be performed:
1) Firstly, you need to run the following command
which will generate a self-signed certificate and private key for the server, as well as the client. These files will be created in the
2) After that, edit
/etc/unbound/unbound.conf and put the following contents in that. The
control-enable: yes option is necessary, the rest can be adjusted as required.
remote-control: # Enable remote control with unbound-control(8) here. # set up the keys and certificates with unbound-control-setup. control-enable: yes # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. control-interface: 127.0.0.1 # port number for remote control operations. control-port: 8953 # unbound server key file. server-key-file: "/etc/unbound/unbound_server.key" # unbound server certificate file. server-cert-file: "/etc/unbound/unbound_server.pem" # unbound-control key file. control-key-file: "/etc/unbound/unbound_control.key" # unbound-control certificate file. control-cert-file: "/etc/unbound/unbound_control.pem"
Some of the commands that can be used with unbound-control are:
- print statistics without resetting them
# unbound-control stats_noreset
- dump cache to stdout
# unbound-control dump_cache
- flush cache and reload configuration
# unbound-control reload
Please refer to
man 8 unbound-control for a detailed look at the operations it supports.
Tips and tricks
You can use the following file and simply include it in your unbound configuration: adservers
server: ... include: /etc/unbound/adservers
For users who wish to run both a validating, recursive, caching DNS server as well as an authoritative DNS server on a single machine then it may be useful to refer to the wiki page nsd which gives an example of a configuration for such a system. Having one server for authoritative DNS queries and a separate DNS server for the validating, recursive, caching DNS functions gives increased security over a single DNS server providing all of these functions. Many users have used bind as a single DNS server, and some help on migration from bind to the combination of running nsd and bind is provided in the nsd wiki page.
WAN facing DNS
It is also possible to change the configuration files and interfaces on which the server is listening so that DNS queries from machines outside of the local network can access specific machines within the LAN. This is useful for web and mail servers which are accessible from anywhere, and the same techniques can be employed as has been achieved using bind for many years, in combination with suitable port forwarding on firewall machines to forward incoming requests to the right machine.
Roothints systemd timer
Here is an example systemd service and timer that update
root.hints monthly using the method in #Root hints:
[Unit] Description=Update root hints for unbound After=network.target [Service] ExecStart=/usr/bin/curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
[Unit] Description=Run root.hints monthly [Timer] OnCalendar=monthly Persistent=true [Install] WantedBy=timers.target
roothints.timer systemd timer.
[Service] CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE MemoryDenyWriteExecute=true NoNewPrivileges=true PrivateDevices=true PrivateTmp=true ProtectHome=true ProtectControlGroups=true ProtectKernelModules=true ProtectKernelTunables=true ProtectSystem=strict ReadWritePaths=/etc/unbound /run RestrictAddressFamilies=AF_INET AF_UNIX RestrictRealtime=true SystemCallArchitectures=native SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete
CapabilityBoundingSetdefines a whitelisted set of allowed capabilities
CAP_IPC_LOCK= Prevents paging by allowing unbound to lock data in memory
- Not a hard requirement for unbound but rather a personal security choice
CAP_NET_BIND_SERVICE= Allows for socket binding to privileged ports < 1024
CAP_SETGID CAP_SETUID= Modifies the user group to nobody nobody
CAP_SYS_CHROOT= Allows the creation of a chroot at
ReadWritePathsspecifies paths to override from
/etc/unbound= Allows the ExecStartPre command to complete
/run= Allows access to the PID file at
- The @mount system call set includes chroot() which is required by unbound to build its environment
unmount2require explicit listing if they are to be blacklisted apart from the @mount macro
- The above example blacklists
CAP_SYS_ADMwhich should be one of the goals of a secure sandbox
server: auto-trust-anchor-file: /etc/unbound/trusted-key.key root-hints: /etc/unbound/root.hints forward-zone: name: "." forward-addr: 22.214.171.124 forward-addr: 126.96.36.199
Issues concerning num-threads
The man page for
outgoing-range: <number> Number of ports to open. This number of file descriptors can be opened per thread.
and some sources suggest that the
num-threads parameter should be set to the number of cpu cores. The sample
unbound.conf.example file merely has:
# number of threads to create. 1 disables threading. # num-threads: 1
However it is not possible to arbitrarily increase
1 without causing unbound to start with warnings in the logs about exceeding the number of file descriptors. In reality for most users running on small networks or on a single machine it should be unnecessary to seek performance enhancement by increasing
1. If you do wish to do so then refer to official documentation and the following rule of thumb should work:
num-threadsequal to the number of CPU cores on the system. E.g. for 4 CPUs with 2 cores each, use 8.
outgoing-range to as large a value as possible, see the sections in the referred web page above on how to overcome the limit of
1024 in total. This services more clients at a time. With 1 core, try
950. With 2 cores, try
450. With 4 cores try
num-queries-per-thread is best set at half the number of the
Because of the limit on
outgoing-range thus also limits
num-queries-per-thread, it is better to compile with , so that there is no
1024 limit on
outgoing-range. If you need to compile this way for a heavy duty DNS server then you will need to compile the programme from source instead of using the package.