Install Unbound
You can use any package manager of your choice. For me it’s pacman.
sudo pacman -Syu unbound
Backup the default configuration file, which is located at /etc/unbound/unbound.conf.
sudo cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak
Edit /etc/unbound/unbound.conf file.
include: "/etc/unbound/conf.d/*.conf"
server:
num-threads: 4
interface: ::1
interface: 127.0.0.1
port: 53
so-rcvbuf: 4m
msg-cache-size: 50m
msg-cache-slabs: 4
rrset-cache-size: 100m
rrset-cache-slabs: 4
infra-cache-slabs: 4
do-ip4: yes
do-udp: yes
do-tcp: yes
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
access-control: ::ffff:127.0.0.1 allow
chroot: "/etc/unbound"
username: "unbound"
directory: "/etc/unbound"
use-syslog: yes
log-time-ascii: yes
log-queries: yes
log-servfail: yes
root-hints: "root.hints"
hide-identity: yes
hide-version: yes
hide-http-user-agent: yes
harden-glue: yes
qname-minimisation: yes
prefetch: yes
prefetch-key: yes
minimal-responses: yes
auto-trust-anchor-file: "root.key"
key-cache-slabs: 4
tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
Fetch Root Hints and DNSSEC Key
Unbound needs to know where the “root” servers of the internet are.
Download Root Hints:
sudo curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
Initialize DNSSEC:
sudo unbound-anchor -a /etc/unbound/root.key
Fix permissions:
sudo chown unbound:unbound /etc/unbound/root.key
sudo chown unbound:unbound /etc/unbound/
sudo mkdir -p /etc/unbound/conf.d/
Directing System Traffic to Unbound
We need to tell our network configuration tool to use 127.0.0.1 (local Unbound server) for DNS lookups. NetworkManager is the standard and most used in Linux.
Edit /etc/NetworkManager/NetworkManager.conf:
[main]
dns=none
Edit /etc/resolv.conf:
nameserver 127.0.0.1
nameserver ::1
options edns0 trust-ad
Optional:
To prevent overwriting this file, run:
sudo chattr +i /etc/resolv.conf
Start and Enable the Unbound Service
Now, fire up the Unbound engine:
sudo systemctl enable --now unbound
Verify the status of the Unbound service:
systemctl status unbound
If it says active (running), you are good to go!
Verify the Setup
Run a DNS lookup and check the “SERVER” field in the output. It should point to 127.0.0.1.
drill google.com
Expected output:
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 29355
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 142.250.70.78
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 102 msec
;; SERVER: 127.0.0.1
;; WHEN: Wed Jan 7 17:26:01 2026
;; MSG SIZE rcvd: 44
Using “Forward Zones”
You can use forwarding if you prefer to let a faster provider handle the recursion while you still enjoy Unbound’s local caching and DNSSEC validation.
For me i need to use forwarder for some wifi AP because the ISP keeps hijacking DNS requests, so the DNSSEC would fail. To solve this i use DNS forwarding over tls so ISP can’t hijack the DNS requests.
To do this just add new .conf file in /etc/unbound/conf.d/ directory. I’m using cloudflare dns over tls, so the setup would look like this:
File: /etc/unbound/conf.d/cloudflare.conf
# Forward all DNS queries to Cloudflare over TLS
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
And, restart the Unbound service:
sudo systemctl restart unbound
To stop the forwarding, simply rename the extension of the file to something else:
sudo mv /etc/unbound/conf.d/cloudflare.conf /etc/unbound/conf.d/cloudflare.conf.bak
DNS blocklist
If you want to use dns blocklist like oisd, download the unbound conf file for that and place it in /etc/unbound/conf.d/ directory.
sudo curl -o /etc/unbound/conf.d/block-oisd_big.conf https://big.oisd.nl/unbound
Troubleshooting
Check Unbound Logs
If you encounter any issues, check the logs:
journalctl -u unbound
Happy Hacking