A local DNS resolver answers your server's own DNS lookups – for mail delivery, API calls, package updates and blocklist checks – and caches the results. Unbound is a fast, secure, validating resolver that is easy to run privately. This guide sets up Unbound for a single server or a private network.
Before you start
- A Linux server with root access.
- Understand the difference: Unbound is a recursive resolver, not an authoritative server for your domains.
Important: Never let the whole internet query your resolver. Open resolvers are abused for DDoS amplification and may get your IP blocked.
Why run a local resolver?
- Mail servers do many DNS lookups (MX, SPF, DKIM, DNSBL). Public resolvers are often rate-limited by DNS blocklists, so spam filtering works better with your own resolver.
- Speed – cached answers come back in microseconds.
- Privacy and control – lookups don't go to a third party.
Install Unbound
- Ubuntu/Debian:
sudo apt install -y unbound - AlmaLinux/Rocky:
sudo dnf install -y unbound
Configure Unbound
Create /etc/unbound/unbound.conf.d/local.conf (on AlmaLinux add the settings to /etc/unbound/unbound.conf or a file in /etc/unbound/conf.d/):
server:
interface: 127.0.0.1
interface: ::1
port: 53
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
access-control: 0.0.0.0/0 refuse
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
qname-minimisation: yes
prefetch: yes
cache-min-ttl: 60
num-threads: 2DNSSEC validation is on by default in the distribution packages via the root trust anchor (auto-trust-anchor-file).
To serve a private network too, add interface: 10.0.0.1 and access-control: 10.0.0.0/24 allow with your own subnet.
Free port 53 on Ubuntu
Ubuntu's systemd-resolved listens on 127.0.0.53. Either keep it and bind Unbound only to 127.0.0.1 (both can coexist), or disable its stub listener by setting DNSStubListener=no in /etc/systemd/resolved.conf and restarting systemd-resolved.
Start and test
- Check the config:
sudo unbound-checkconf. - Start:
sudo systemctl enable --now unbound(restart if already running). - Query it:
dig @127.0.0.1 example.com. Run it twice – the second query time should be near 0 ms. - Test DNSSEC validation:
dig @127.0.0.1 dnssec-failed.orgshould returnSERVFAIL, while a signed domain shows theadflag.
Point the server at Unbound
- With systemd-resolved: set
DNS=127.0.0.1in/etc/systemd/resolved.confand restart it. - Without it: set
nameserver 127.0.0.1in/etc/resolv.conf, or in your Netplan/NetworkManager DNS settings so it survives reboots.
Troubleshooting
- "address already in use": another resolver (systemd-resolved, dnsmasq, BIND) holds port 53 on that address.
- All lookups SERVFAIL: server time is wrong (breaks DNSSEC) – enable NTP – or outbound UDP/TCP 53 is blocked.
- Clients on the LAN refused: add their subnet to
access-controland aninterfaceline.
FAQ: Unbound DNS resolver
Can Unbound forward to Cloudflare or Google instead of recursing?
Yes, with a forward-zone for ".", optionally over DNS-over-TLS. Full recursion avoids depending on a third party.
Should cPanel servers run their own resolver?
cPanel servers manage /etc/resolv.conf through WHM's Resolver Configuration; follow WHM's options rather than editing by hand.
Is Unbound an authoritative DNS server?
It can serve small local zones, but for public domains use BIND or PowerDNS.
