Table of Contents

Unbound

Changelog

  • 2022: Init
  • 2024-11-05: Elucidate for new setup.

Introduction

Unbound is many things nowadays, with the following functionality:


Why?

Setting up a local DNS resolver, because it gets too tedious mapping IP addresses across different computers, and talking to IT to add DNS entries will not work for fast updating.

Documentation is here: https://unbound.docs.nlnetlabs.nl/en/latest/

There is a network resolver in Ubuntu, but does not provide out-of-the-box DNS functionality.


Installation

For Ubuntu 22.04, Unbound is available via the package manager:

# Install Unbound
sudo apt install unbound

# Root key for DNSSEC automatically created
# Disable world-readability of DNSSEC root key
sudo chmod o-rwx /var/lib/unbound/root.key

Sensible defaults are already provided. We set up a minimal user configuration by adding the following file:

/etc/unbound/unbound.conf.d/user-server.conf
# DNSSEC auto-enabled, with QNAME minimisation
server:
    port: 53
    interface: 127.0.0.1
    access-control: 127.0.0.0/8 allow
 
    # DNS server additional (non-default) settings
    directory: "/etc/unbound"
    do-ip6: no
    hide-version: yes
 
# For localhost unbound control
# Defaults to localhost:8953
remote-control:
        control-enable: yes

Check for configuration errors, then restart to load changes:

# Configuration checking
sudo unbound-checkconf /etc/unbound/unbound.conf.d/user-server.conf

# Start unbound, and enable start on boot
sudo systemctl enable --now unbound

Verify DNS server is running:

# Run DNS query through local DNS server
# Should return: ";; SERVER: 127.0.0.1#53(localhost) (UDP)"
dig example.com @localhost

Congratulations, your DNS server is now up and running.


Setting default DNS server

At this point, running dig example.com without specifying the localhost as the DNS server will not use Unbound. For Ubuntu, there is a systemd resolver, systemd-resolved.service, that will need its configuration modified.

Modify the following resolution configuration file to include the following section:

/etc/systemd/resolved.conf
[Resolve]
DNS=127.0.0.1
DNSSEC=yes
DNSStubListener=no

then restart the system resolver:

sudo systemctl restart systemd-resolved

No need to overwrite /etc/resolv.conf (and other outdated solutions)

The system now checks with the local Unbound DNS server for name resolution first, before checking the other DNS servers provided by the DHCP server. Check it with dig example.com (note this does not specify the DNS server as before).

OpenSUSE configuration


Allowing DNS queries from local network

Modify the Unbound configuration to allow it to bind with the 0.0.0.0 interface instead, as well as specify which IP addresses it allows querying from:

# Rest of the file contents truncated
server:
    interface: 0.0.0.0
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.1.0/24 allow

Restart the Unbound server for local network goodness. Don't forget to add the corresponding firewall rule, e.g. sudo ufw allow 53 comment "Unbound DNS (2023-07-16)"


Add local DNS records

Add to the server block the following:

/etc/unbound/unbound.conf.d/user-records.conf
# Local DNS zones
server:
    # For pseudo-resolution of subdomains
    local-zone: "hotsake." redirect
 
    # DNS A record
    local-data: "hotsake. A 192.168.1.240"
 
    # Reverse DNS PTR record
    local-data-ptr: "192.168.1.240 hotsake."

For CNAME and wildcard support, one needs to use an authoritative nameserver, e.g. BIND or NSD. Most of the time, this is not particularly needed.

If using DNS resolution for ssh, consider following more proper domain name conventions (e.g. hotsake.internal. instead of the TLD hotsake.) and set canonical domains in the SSH client configuration, i.e.

~/.ssh/config
Host *
    CanonicalizeHostname yes
    CanonicalDomains internal

Redirect DNS queries for specific domains

These are called forward zones.

forward-zone:
    name: "pyuxiang.com."
    forward-addr: 192.168.10.1

Flush caches

This flushes all caches

unbound-control flush www.google.com
unbound-control flush_zone .
1)
note this likely means the DNS query path itself is recursive and not iterative, but the multiple DNS queries to narrow down the A record is iterative
2)
Unbound depends on a root.hints file that is usually supplied as a dns-root-data package dependency in package managers src
3)
i.e. DNS cache poisoning and DNS amplification, consider looking at a DNSSEC introduction