This is an old revision of the document!
unbounddns
This tutorial is for users of Debian GNU/Linux who want to run their own recursive DNS server using the Unbound project. In this scenario, I am using GL.iNet MT6000 router and a separate AP. The router handles all dhcp/dns for the LAN / private subnet. In the openWRT config on the router's dhcp server, I specify two custom DNS servers in Interfaces / LAN / DHCP Server / Advanced / 6,10.1.1.100,10.1.1.101. These DNS servers are Debian VMs on two different production servers in the home office space; each of them is running a pihole server. The pihole-FTL takes care of adblocking and DNS sinkhole duties. If left with default settings, it uses your specified third-party DNS servers for upstream requests (Level 3, Cloudflare, etc.). This tutorial is how to replace those third-party DNS servers with Unbound, running locally on each pihole and on port 5335 instead of port 53, which is already used by pihole-FTL.
sudo apt install unbound sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf
In that file, enter something like the following, adjusting as necessary for your use-case.
server:
logfile: "/var/log/unbound/unbound.log"
log-time-ascii: yes
use-syslog: yes
directory: "/etc/unbound"
username: unbound
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
verbosity: 3
interface: 0.0.0.0
interface: ::0
port: 5335
do-ip4: yes
do-udp: yes
do-tcp: yes
module-config: "validator iterator"
do-ip6: yes
prefer-ip6: no
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: no
edns-buffer-size: 1232
prefetch: yes
num-threads: 8
msg-cache-slabs: 16
rrset-cache-slabs: 16
infra-cache-slabs: 16
key-cache-slabs: 16
rrset-cache-size: 512m
msg-cache-size: 256m
outgoing-range: 32768
num-queries-per-thread: 8192
infra-cache-numhosts: 100000
#so-rcvbuf: 1m
#so-sndbuf: 2m
so-reuseport: yes
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
private-address: fd00::/8
private-address: fe80::/10
#access-control: 127.0.0.1/32 allow_snoop
#access-control: ::1 allow_snoop
#access-control: 127.0.0.0/8 allow
access-control: 192.168.0.0/16 allow
access-control: 10.0.0.0/8 allow
access-control: 127.0.0.1/24 allow
access-control: 2001:DB8::/64 allow
aggressive-nsec: yes
hide-identity: yes
hide-version: yes
cache-max-ttl: 14400
cache-min-ttl: 11000
In my case, I prefer traditional rotated logs with rsyslog, so I do the following:
sudo apt install rsyslog sudo nano /etc/rsyslog.d/unbound.conf <if $programname == 'unbound' then /var/log/unbound/unbound.log> <& stop> nano /etc/logrotate.d/unbound
In the log rotate file, enter the following:
/var/log/unbound/unbound.log {
daily
rotate 7
missingok
create 0640 root adm
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
Additionally, some Debian systems have resolvconf installed, so many install recipes recommend disabling that service so that it does not overwrite the DNS settings we are making here.
systemctl disable --now unbound-resolvconf.service sed -Ei 's/^unbound_conf=/#unbound_conf=/' /etc/resolvconf.conf rm /etc/unbound/unbound.conf.d/resolvconf_resolvers.conf
To make sure logs are working properly:
nano /etc/apparmor.d/local/usr.sbin.unbound </var/log/unbound/unbound.log rw,> sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.unbound sudo service apparmor restart sudo mkdir -p /var/log/unbound sudo touch /var/log/unbound/unbound.log sudo chown unbound /var/log/unbound/unbound.log
Enforce edns settings specified in config:
nano /etc/dnsmasq.d/99-edns.conf <edns-packet-max=1232>
The last step is configuring the unbound server in the pihole GUI. Alternately, you can do this without a pihole by simply specifying this address as your WAN's upstream DNS server in openWRT. Alright, and in case you don't need LAN-based DNS, but just want a public facing virtual appliance to use its own DNS, just install unbound and enter the following in /etc/unbound/unbound.conf:
server:
interface: 127.0.0.1
cache-max-ttl: 14400
cache-min-ttl: 1200
num-threads: 4
msg-cache-slabs: 8
rrset-cache-slabs: 8
infra-cache-slabs: 8
key-cache-slabs: 8
rrset-cache-size: 256m
msg-cache-size: 128m
#prefetch: yes
harden-dnssec-stripped: yes
use-syslog: yes
aggressive-nsec: yes
hide-identity: yes
hide-version: yes
use-caps-for-id: yes
do-tcp: yes
do-udp: yes
Then, just add nameserver 127.0.0.1 to /etc/resolv.conf. This latter step only works on classic/minimal Debian. Use netplan properly and/or resolvconf package and the correct .d directory if not using proper DNS management.
— oemb1905 2025/04/04 03:20