Set Up Unbound DNS Resolver on Ubuntu 22.04/20.04 Server

This tutorial will be showing you how to set up a local DNS resolver on Ubuntu 22.04/20.04 with Unbound. A DNS resolver is known by many names, some of which are listed below. They all refer to the same thing.

  • full resolver (in contrast to stub resolver)
  • recursive DNS server
  • recursive name server
  • recursive resolver
  • DNS recursor

Examples of DNS resolver are 8.8.8.8 (Google public DNS server) and 1.1.1.1 (Cloudflare public DNS server). The OS on your computer also has a resolver, although it’s called stub resolver due to its limited capability. A stub resolver is a small DNS client on the end user’s computer that receives DNS requests from applications such as Firefox and forward requests to a recursive resolver. Almost every resolver can cache DNS response to improve performance, so they are also called caching DNS server.

Set Up Unbound DNS Resolver on Ubuntu 20.04 Server

Why Run Your Own DNS Resolver

Usually, your computer, router or server uses your ISP’s DNS resolver to query DNS names, so why run a local DNS resolver?

  • It can speed up DNS lookups, because the local DNS resolver only listens to your DNS requests and does not answer other people’s DNS requests, so you have a much higher chance of getting DNS answers directly from the cache on the resolver. The network latency between your computer and DNS resolver is eliminated (almost zero), so DNS queries can be sent to root DNS servers more quickly.
  • If you run a mail server and use DNS blacklists (DNSBL) to block spam, then you should run your own DNS resolver, because some DNS blacklists such as URIBL refuse requests from public DNS resolvers.
  • If you run your own VPN server on a VPS (Virtual Private Server), it’s also a good practice to install a DNS resolver on the same VPS.
  • You may also want to run your own DNS resolver if you don’t like your Internet browsing history being stored on a third-party server.

Hint: Local doesn’t mean your home computer. Rather, it means the DNS resolver runs on the same box or the same network as the DNS client. You can install Unbound DNS resolver on your home computer. It’s local to your home computer. You can also install Unbound DNS resolver on a cloud server, and it’s local to the cloud server.

Unbound DNS Resolver

Unbound is an open-source DNS validating resolver, meaning it can do DNSSEC validation to ensure the DNS response is authentic. Unbound features:

  • Lightweight and extremely fast, as it doesn’t provide full-blown authoritative DNS server functionality. On one of my servers, Unbound uses a quarter of the memory required by BIND9.
  • DNS response cache
  • Prefetch: fetch data that is about to expire so that client does not get spike in latency when lookup needs to be redone when TTL expires on data.
  • DNS over TLS
  • DNS over HTTPS
  • Query Name Minimization: Send minimum amount of information to upstream servers to enhance privacy.
  • Aggressive Use of DNSSEC-Validated Cache
  • Authority zones, for a local copy of the root zone
  • DNS64
  • DNSCrypt
  • DNSSEC validation: It’s enabled by default on Ubuntu 🙂
  • EDNS Client Subnet
  • Can run as a DNS forwarder.
  • Supports local-data and response policy zone to give a custom answer back for certain domain names.

Step 1: Install Unbound DNS Resolver on Ubuntu 22.04/20.04

Run the following command to install Unbound on Ubuntu 22.04/20.04 from the default repository.

sudo apt update
sudo apt install unbound

Check version.

unbound -V

Sample output:

unbound ubuntu 20.04 server

By default, Unbound automatically starts after installation. You check its status with:

systemctl status unbound

unbound.service - Unbound DNS server ubuntu 20.04

If it’s not running, then start it with:

sudo systemctl start unbound

And enable auto-start at boot time:

sudo systemctl enable unbound

Note: If there’s another service listening on UDP port 53, then unbound might not be able to start. You need to stop that service before starting unbound. To find out what service is already using UDP port 53, run the following command.

sudo ss -lnptu | grep 53

If you installed BIND9 resolver before, then you need to run the following command to stop and disable it, so Unbound can listen to the UDP port 53. By default, Unbound listens on 127.0.0.1:53 and [::1]:53

sudo systemctl disable named --now

Step 2: Configure Unbound

The main configuration file for Unbound is /etc/unbound/unbound.conf. Out of the box, the Unbound server on Ubuntu provides recursive service for localhost only. Outside queries will be denied.

Edit the config file.

sudo nano /etc/unbound/unbound.conf

By default, there’s only one config line in this file.

include: "/etc/unbound/unbound.conf.d/*.conf"

This is to include the config files under /etc/unbound/unbound.conf.d/ directory, which contains two config files.

  • qname-minimisation.conf: enables QNAME minimization.
  • root-auto-trust-anchor-file.conf: Enables DNSSEC validation.

You don’t have to touch these two files. Just know that they will do good to your DNS resolution. Now we need to add our custom configurations. You can take a look at the example config file /usr/share/doc/unbound/examples/unbound.conf to learn how to configure Unbound. For your convenience, I compiled a minimal config for you. Add the following lines in the /etc/unbound/unbound.conf file.

server:
      # the working directory.
      directory: "/etc/unbound"
 
      # run as the unbound user
      username: unbound

      verbosity: 2      # uncomment and increase to get more logging.

      # listen on all interfaces, answer queries from the local subnet.
      interface: 0.0.0.0
      # comment out the following line if your system doesn't have IPv6.
      interface: ::0

      # perform prefetching of almost expired DNS cache entries.
      prefetch: yes

      access-control: 10.0.0.0/8 allow
      access-control: 127.0.0.1/24 allow
      access-control: 2001:DB8::/64 allow

      # hide server info from clients
      hide-identity: yes
      hide-version: yes

remote-control:
      # Enable remote control with unbound-control(8) here.
      control-enable: no

      # what interfaces are listened to for remote control.
      # give 0.0.0.0 and ::0 to listen to all interfaces.
      # set to an absolute path to use a unix local name pipe, certificates
      # are not used for that, so key and cert files need not be present.
      control-interface: 127.0.0.1
      # control-interface: ::1

      # port number for remote control operations.
      control-port: 8953

The above configurations are self-explanatory. There are two things you might need to consider.

(1) By default, Ubuntu runs the systemd-resolved stub resolver which listens on 127.0.0.53:53. You need to stop it, so unbound can bind to 0.0.0.0:53.

sudo systemctl disable systemd-resolved --now

(2) If your local network range is not 10.0.0.0/8, you need to change that, for example,

access-control: 192.168.0.0/24 allow

so unbound will accept DNS queries from the 192.168.0.0/24 network.

Save and close the file. Then restart Unbound.

sudo systemctl restart unbound

Check the status. Make sure it’s running.

systemctl status unbound

If you have UFW firewall running on the Unbound server, then you need to open port 53 to allow LAN clients to send DNS queries.

sudo ufw allow in from 10.0.0.0/8 to any port 53

This will open TCP and UDP port 53 to the private network 10.0.0.0/8.

Step 3: Setting the Default DNS Resolver on Ubuntu 22.04/20.04 Server

We need to make Ubuntu 22.04/20.04 server use 127.0.0.1 as DNS resolver, so unbound will answer DNS queries. The unbound package on Ubuntu ships with a systemd service unbound-resolvconf.service that is supposed to help us accomplish this. However, I found it won’t work.

Instead, you can create a custom unbound-resolvconf.service file.

sudo nano /etc/systemd/system/unbound-resolvconf.service

Add the following lines in this file.

[Unit]
Description=local unbound via resolvconf
After=unbound.service
ConditionFileIsExecutable=/sbin/resolvconf

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'echo nameserver 127.0.0.1 | /sbin/resolvconf -a lo.unbound'
ExecStop=/sbin/resolvconf -d lo.unbound

[Install]
WantedBy=unbound.service

Save and close this file. Then reload systemd.

sudo systemctl daemon-reload

Make sure your system has the resolvconf binary.

sudo apt install openresolv

Next, restart this service.

sudo systemctl restart unbound-resolvconf.service

Now check the content of /etc/resolv.conf.

cat /etc/resolv.conf

Setting unbound as Default DNS Resolver on Ubuntu 20.04 Server

As you can see, 127.0.0.1 (Unbound) is default DNS resolver.

Troubleshooting

If you see a different value in the /etc/resolv.conf file, that means Unbound is still not your default DNS resolver. Note that some hosting providers like Linode may use a network helper to auto-generate the /etc/resolv.conf file. To change the default DNS resolver, you need to disable that network helper in the hosting control panel.

If this method still doesn’t work, perhaps it’s due to the fact the /etc/resolv.conf file on your Ubuntu server is not a symbolic link to /run/resolvconf/resolv.conf. You need to delete the /etc/resolv.conf file and create a symbolic link.

sudo rm /etc/resolv.conf

sudo ln -s /run/resolvconf/resolv.conf /etc/resolv.conf

If you have WireGuard VPN client running on the Ubuntu server, then you need to use the following DNS setting in the WireGuard client configuration file.

DNS = 127.0.0.1

Then restart the WireGuard VPN client.

Step 4: Setting Default DNS Resolver on Client Computers

On Ubuntu desktop, you can follow the above instructions to set the default DNS resolver, but remember to replace 127.0.0.1 with the IP address of Unbound server. The steps of setting default DNS resolver on MacOS and Windows can be found on the Internet.

How to Disable IPv6 in Unbound

If your server doesn’t have IPv6 connectivity, it’s a good idea to turn off IPv6 in Unbound to reduce unnecessary DNS lookups over IPv6. To disable IPv6 in Unbound on Ubuntu, simply add the following line in the server: clause in the /etc/unbound/unbound.conf file.

do-ip6: no

Save and close the file. Then restart Unbound.

sudo systemctl restart unbound

Unbound DNSSEC

DNSSEC is a way to validate that the DNS response doesn’t get tamper with. It’s enabled by default if your install Unbound from the default Ubuntu repository. Let’s do a quick DNS query on the Ubuntu 22.04/20.04 server.

dig A linuxbabe.com

You can see the ad flag in the DNS response. AD means authentic data.

unbound dnssec ubuntu

Note that the domain name must enable DNSSEC for the validation to work. If you don’t see the ad flag, it could mean that the domain name hasn’t enabled DNSSEC.

Local-data

You can use the local-data feature in Unbound to serve local internal hostnames or override public DNS records.

For example, if I install unbound on my blog web server, I can add the following four lines in the server: clause in the Unbound configuration files, so that the domain always resolves to localhost.

local-data: "linuxbabe.com      A   127.0.0.1"
local-data: "www.linuxbabe.com  A   127.0.0.1"
local-data: "linuxbabe.com      AAAA   ::1"
local-data: "www.linuxbabe.com  AAAA   ::1"

If you want to add multiple IP addresses for a hostname (round-robin DNS load balancing), you can do it like so:

local-data: "smtp.linuxbabe.com     A     10.0.0.1"
local-data: "smtp.linuxbabe.com     A     10.0.0.2"

No servers could be reached

If you see the following error when using the dig command on client computers

;; connection timed out; no servers could be reached

It could be that your firewall rule is wrong or the Unbound resolver isn’t running.

Conclusion

I hope this tutorial helped you set up a local DNS resolver on Ubuntu 22.04/20.04 with Unbound. Because it will be used on a localhost/local network, no encryption (DNS over TLS or DNS over HTTPS) is needed. For setting up a DoT resolver or DoH resolver, please read the following tutorials.

As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks. Take care 🙂

Rate this tutorial
[Total: 13 Average: 5]

14 Responses to “Set Up Unbound DNS Resolver on Ubuntu 22.04/20.04 Server

  • Very nice 🙏

  • Philip Miller
    3 years ago

    Very very nice. Took me many passes but finally it worked like a charm. Now is it really faster and more reliable? I have my own private email server.

  • Arturitu12
    3 years ago

    Hello idk why all seems to be ok, but resolver can’t get any address. Unbound are running active, cat /etc/resolv.conf shows 127.0.0.1. I was previously running BIND9 resolver from your tutorial and swithced it off.

  • Andorra
    3 years ago

    Thanks for this masterpiece!

  • JojieRT
    2 years ago

    Thanks for this. For “defeating” systemd-resolved though, I used pi-hole’s method @ https://github.com/pi-hole/docker-pi-hole#installing-on-ubuntu

  • Many thanks for this. I set up Debian 11.5 on an old PC to run a second instance of OpenMediaVault v6 (for rsync backups) and DNS worked to begin with, using DHCP, but then stopped for no reason I could see — something to do with systemd-resolved I think. I was able to get this working. Procedurally it’s more complete than some other things I found–thank you. What I’d really like now is a pointer to a high level tutorial on DNS, unbound, as implemented different distros (the files and apps involved etc)! — On YouTube or wherever.

  • When running the following command:

    ~$ unbound-control status

    It returns:

    [1673405088] unbound-control[5382:0] warning: control-enable is 'no' in the config file.
    [1673405088] unbound-control[5382:0] error: connect: Connection refused for 127.0.0.1 port 8953
    unbound is stopped

    In your tutorial,

    control-enable:

    is set to no. Should it be set to yes instead to avoid this error?

  • Instead of disabling systemd-resolved, I just added

    DNSStubListener=no

    to

    /etc/systemd/resolved.conf

    . This works. However, after following your tutorial I run the command:

    systemd-resolve --status | grep "DNS Servers" -A2

    to check my dns servers. And it returns the following:

             DNS Servers: 127.0.0.1
    Fallback DNS Servers: 192.168.1.1
    --
             DNS Servers: 192.168.1.1
    --
             DNS Servers: 192.168.1.1
    

    192.168.1.1 is my routers IP/DNS, and it looks like my Ubuntu Server is getting these 192.168.1.1 IP/DNS addresses from netplan. Should I be adding 127.0.0.1 as my DNS server in netplan or is that not necessary? Could you explain why or why not?

  • Any chance you can answer my question? ^^^^^^^^^^ This is still unresolved for me.

  • You didn’t cover DNS over TLS, which includes certificate installation and compatibility with Android. Which makes this tutorial as good as thousands of others.

  • The current apt package for Unbound is version 1.13.1.
    I have tried installing this but found that its config files were not in /etc/unbound.conf nor in /etc/unbound/unbound.conf.d/ . . .
    Well, that’s a bit of show-stopper. Even by the standards of NLNet / Unbound . . .

  • TROUBLESHOOTING ON UBUNTU 22.04 and UP!

    On Ubuntu 22.04 and up,

    /etc/resolv.conf

    is not symbolically linked to

    /run/resolvconf/resolv.conf

    , but rather it is symbolically linked to

    /run/systemd/resolve/stub-resolv.conf

    So if you are having issues resolving DNS on Ubuntu 22.04 and up you should run the following command:

    sudo rm /etc/resolv.conf
    sudo ln -s /run/systemd/resolve/stub-resolv.conf  /etc/resolv.conf
    

    and NOT

    sudo ln -s /run/resolvconf/resolv.conf /etc/resolv.conf
    

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here