Set Up Unbound DNS Resolver on Ubuntu 20.04 Server

This tutorial will be showing you how to set up a local DNS resolver on Ubuntu 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 20.04

Run the following command to install Unbound on Ubuntu 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 20.04 Server

We need to make Ubuntu 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 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"

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 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: 2 Average: 5]

9 Responses to “Set Up Unbound DNS Resolver on Ubuntu 20.04 Server

  • Very nice 🙏

  • Philip Miller
    1 month 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.

  • sir can you show me right way how to config private server for run mail server bye myself I have some problem with local IP with public IP I’m not sure of concept of direct connection I have a public IP from my isp but I don’t know how to map it to my local IP

  • Philip Miller
    1 month ago

    additional comment.

    this step should be done at the beginning not where you have suggested. Because the setup is not complete and therefore installation will not proceed.

    This worked perfectly for 2 hours and then stopped. somehow is missing.

    Nice try. But I had to revert to previous resolver.

    • It can be installed at any stage, you just need to know what is really the problem you are facing and be resourceful to fix it.

      Find out why it stopped and prevent it from happening in the future.

    • My unbound resolver has been running for 2 days. (I manually restarted it once.)

      systemctl status unbound ubuntu

      If you installed BIND9 resolver, then you need to stop and disable it, so Unbound can listen to the UDP port 53.

      sudo systemctl disable bind9 --now

      On newer version of Ubuntu, the command is

      sudo systemctl disable named --now

      To find out why Unbound stopped, check its log.

      sudo journalctl -eu unbound

      The syslog (/var/log/syslog) might also be helpful for debug.

  • Philip Miller
    1 month ago

    Thank you for these answers. I had to revert to my previous configuration. It just stopped. And suddenly my firewall was stopping everything.

    I maintain that you have to install openresolv at the beginning and not at the point you suggest. Because the server is not adequately configured at that point. So it would not communicate with or download the source file.

    It was working for a few hours and then stopped. I noted that the file /run/resolvconf/resolv.conf was missing. It just disappeared. /etc/resolv.conf was “inactivated”

    In the end my current DNS server is 10.0.0.2 with domain us-west-1.compute.internal. So it appears that I am not using any commercial resolvers such as Google or Cloudflare. And, as such, it doesn’t seem that I gained much from installing unbound. DNSSEC not supported. DNSover TLS not supported.

    The journalctl didn’t give me any “aha” answers.

    I’d liked the elegance and simplicity of your routine. But it failed after only a few hours.

    Thank you for the response.

    • Quote: "I maintain that you have to install openresolv at the beginning"

      openresolv is just a utility to change the DNS resolver on the server. It’s not a must to install it at the beginning.

      Quote: "/etc/resolv.conf was inactivated"

      Even if this file was deleted, you can manually create this file like this:

      sudo nano /etc/resolv.conf

      And add a simple line like

      nameserver 127.0.0.1

      So your server will use 127.0.0.1 as the resolver.

      Quote: "as such, it doesn’t seem that I gained much from installing unbound"

      That’s because you didn’t set 127.0.0.1 as the resolver, so your system isn’t using Unbound.

      Quote: "DNSSEC not supported. DNS over TLS not supported." 

      I wonder why would you say that.

      No offense intended, but looking at all your comments on this website, I think you tend to make a hasty judgment and not willing to learn deeper to fully understand a subject.

      To have a working unbound resolver, you need to make sure
      1.) unbound is running and listens on 127.0.0.1:53
      2.) Your system is using 127.0.0.1 as the resolver.

      When an error happens, find out why it happens, and post the error message in the comments section, so others can help. Don’t jump to conclusions.

  • Philip Miller
    1 month ago

    Thank you so kindly for your responses. I will persist. They were valid questions. You have been helpful. This is a good and elegant solution.

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.