Setting up Unbound with DNSSEC

Install

slackware

grep ^unbound /etc/group
grep ^unbound /etc/passwd

groupadd -g 304 unbound
useradd -r -u 304 -g unbound -d /etc/unbound/ -s /sbin/nologin unbound

ls -lF /var/log/packages/unbound-* # not yet
sbopkg -s unbound
sbopkg -i unbound

we want a place that has a shorter path for the chroot - and this one will be a symlink to the chroot anyhow

cp -pi /etc/rc.d/rc.unbound /etc/rc.d/rc.unbound.dist
chmod -x /etc/rc.d/rc.unbound.dist
vi /etc/rc.d/rc.unbound

#config="/etc/unbound/unbound.conf"
config="/etc/unbound.conf"

from source

see unbound-source

shared

    mkdir -p /var/chroot/unbound/db/
    mkdir -p /var/chroot/unbound/etc/
    chown unbound:unbound /var/chroot/unbound/db/
    chmod 750 /var/chroot/unbound/db/

Optional – generate some key pairs for unbound-control to work

    unbound-control-setup
    ls -lF /usr/local/etc/unbound/unbound*.{key,pem}
    ls -lF /etc/unbound/unbound*.{key,pem}

Optional – otherwise using named pipe

    ls -alF /run/unbound/
    mkfifo /run/unbound/control.pipe
    ls -lF /run/unbound/control.pipe

Hints and trust anchor

Grab the one and only root anchor

ls -lF /var/chroot/unbound/db/root.key # not yet
unbound-anchor -a /var/chroot/unbound/db/root.key

this file gets updated by the daemon itself (see auto-trust-anchor-file)

chown unbound:unbound /var/chroot/unbound/db/root.key
# daemon will revert it to 644 anyway
#chmod 640 /var/chroot/unbound/db/root.key

Grab the root hints and signature

cd /var/chroot/unbound/
wget https://www.internic.net/domain/named.cache
wget https://www.internic.net/domain/named.cache.sig

also import InterNIC’s PGP pubkey and verify the file

gpg --version # 2.2.19
gpg --keyserver pgp.mit.edu --receive-key 937BB869E3A238C5
gpg --verify named.cache.sig
# F0CB 1A32 6BDF 3F3E FA3A  01FA 937B B869 E3A2 38C5

gpg --version # 1.4.23
gpg --keyserver pgp.mit.edu --recv-keys 937BB869E3A238C5
    gpg --verify named.cache.sig
# F0CB 1A32 6BDF 3F3E FA3A  01FA 937B B869 E3A2 38C5

It’s best the hints remain with root ownership, as those aren’t managed by the daemon.

Caching and validating resolver setup

for the sake of the void

cd /etc/unbound/
mv -i unbound.conf unbound.conf.dist
grep -vE '^[[:space:]]*(#|$)' unbound.conf.dist > unbound.conf.clean

we’ve got a chroot and we need to keep a consistent path within the host system

ln -s ../var/chroot/unbound/etc/unbound.conf /etc/unbound.conf
cd /var/chroot/unbound/etc/
vi unbound.conf

additional handy symlink

ln -s /var/chroot/unbound/db/unbound.log /var/log/unbound.log

how many cores do you have? And proceed

grep ^processor /proc/cpuinfo
vi /var/chroot/unbound/etc/unbound.conf

assuming an internal host hence listening on all interfaces here

server:
    verbosity: 2
    num-threads: HOW_MANY_CORES
    interface: 0.0.0.0
    #interface: ::0
    access-control: 0.0.0.0/0 allow
    #access-control: ::/0 allow
    pidfile: "/run/unbound.pid" # not within chroot
    hide-identity: yes
    hide-version: yes
    #rrset-roundrobin: yes
    qname-minimisation: yes
    do-not-query-localhost: no

    username: "unbound"
    chroot: "/var/chroot/unbound"
    # pathes within chroot
    directory: "/"
    root-hints: "/named.cache"
    auto-trust-anchor-file: "/db/root.key"
    logfile: "/db/unbound.log"

remote-control:
    control-enable: no

otherwise

remote-control:
    control-enable: yes
    control-interface: /run/unbound/control.pipe

in case you wanna restrict to a few interfaces

        interface: 127.0.0.1
        interface: 10.1.255.254
        access-control: 127.0.0.1/32 allow
        access-control: 10.1.0.0/16 allow

sample domain

assuming an authoritative server to bind to on alternate port 5353

    domain-insecure: "example.local"
    domain-insecure: "1.1.10.in-addr.arpa"
    #local-zone: "example.local" transparent
    #local-zone: "1.1.10.in-addr.arpa" transparent

stub-zone:
    name: "example.local"
    stub-addr: ::1@5353

stub-zone:
    name: "1.1.10.in-addr.arpa"
    stub-addr: ::1@5353

Ready to go (standalone)

read the logs

tail -n50 -F /var/log/unbound.log &

check the configuration

unbound-checkconf /etc/unbound.conf

start and enable at boot time

slackware

ll /etc/rc.d/rc.unbound
chmod +x /etc/rc.d/rc.unbound
/etc/rc.d/rc.unbound start

source

vi /etc/rc.local

echo -n unbound...
unbound -c /etc/unbound.conf && echo done || echo FAILED

status – main process runs as unbound user

pgrep -a unbound
ps auxfww | grep unbound | grep -vE 'grep|tail'
cat /run/unbound.pid
netstat -lntup | grep unbound

stop

pkill unbound && rm -f /var/run/unbound.pid

Ready to go (remote control)

start and enable at boot time

echo -n unbound-control...
rm -f /run/unbound/control.pipe
mkfifo /run/unbound/control.pipe
# same path within chroot
unbound-control -c /etc/unbound.conf start && echo done || echo FAIL

you will notice the perms are updated by the daemon as such

ls -lF /run/unbound/control.pipe

srw-rw---- 1 unbound unbound 0 Oct  2 12:53 /var/unbound.control.pipe=

status (no need to enforce the config path here)

unbound-control status
unbound-control stats_noreset

reload (idem)

unbound-control reload

Acceptance

locally

The managed dnssec root key is in da place (there’s no way to make it 640?)

ls -lF /var/chroot/unbound/db/root.key
cat /var/chroot/unbound/db/root.key

Testing local-zone

host localhost localhost
host 127.0.0.1 localhost

Testing cached public zone

host nethence.com localhost
host 62.210.110.7 localhost

Testing cashed stub-zone

host example.local localhost
host INTERNAL-IP localhost

Tracing iterative queries

dig nethence.com +trace @localhost

Testing DNSSEC (do and ad flags)

dig nethence.com +dnssec @localhost

More options

+multiline

remotely

nmap -sU -p 53 DNS-SERVER
nmap -p 53 DNS-SERVER

and re-iterate a few tests from above.

Maintenance

Flush the cache against a specific zone

unbound-control flush_zone example.local

Flush the overall cache

unbound-control reload

Analyze the cache

unbound-control dump_cache > cache.dump
less cache.dump

Easy family-shield forwarder

    #root-hints: "/named.cache"

    forward-zone:
            name: "."
    # OpenDNS Family Shield
            forward-addr: 208.67.222.123
            forward-addr: 208.67.220.123
    # CleanBrowsing Family Filter
            # 185.228.168.168
            # 185.228.169.168

acceptance

host some-pr0n-website

should return

146.112.61.106
::ffff:146.112.61.106
106.61.112.146.in-addr.arpa domain name pointer hit-adult.opendns.com.

oh and when ever your browser connects there, it will get an un-trusted certificate

srv=hit-adult.opendns.com
port=443

echo Q | openssl s_client -servername $srv -connect $srv:$port 2>&1 | openssl x509 -noout -text

Keep the cache upon reboot

BEFORE you kill the daemon

vi /etc/rc.local_shutdown

echo -n dumping dns cache...
unbound-control dump_cache > /var/tmp/cache.dump && echo done || echo FAIL

echo -n shutting down unbound...
pkill unbound && echo done || echo FAIL

AFTER you start the daemon

vi /etc/rc.local

echo -n loading dns cache...
unbound-control load_cache < /var/tmp/cache.dump && echo done || echo FAIL

it’s worth noting an empty cache db looks as such

START_RRSET_CACHE
END_RRSET_CACHE
START_MSG_CACHE
END_MSG_CACHE
EOF

Troubleshooting

If Unbound service is listening but refusing to answer queries, fix access-control: as shown in the example above.

With verbosity 3, if you get

configured stub servers failed -- returning SERVFAIL

==> check do-not-query-localhost

Against a stub zone too, if you get

info: query response was nodata ANSWER

==> if it is not signed, domain-insecure helps

Resources

unbound.conf - Unbound configuration file. https://nlnetlabs.nl/documentation/unbound/unbound.conf/

build

Unbound-1.9.1 http://www.linuxfromscratch.org/blfs/view/svn/server/unbound.html

hints and anchors

Root Files https://www.iana.org/domains/root/files

Trust Anchors and Keys https://www.iana.org/dnssec/files

unbound-anchor - Unbound anchor utility. https://nlnetlabs.nl/documentation/unbound/unbound-anchor/

Howto enable DNSSEC https://nlnetlabs.nl/documentation/unbound/howto-anchor/

guides

Unbound https://wiki.archlinux.org/title/Unbound

unbound/doc/example.conf.in https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in old http://unbound.nlnetlabs.nl/svn/trunk/doc/example.conf.in

[Unbound-users] reverse lookup stub zone https://www.unbound.net/pipermail/unbound-users/2009-May/000583.html

maintenance

Unbound DNS Server Cache Control https://abridge2devnull.com/posts/2016/03/unbound-dns-server-cache-control/

Unbound DNS Server Cache Control https://abridge2devnull.com/posts/2016/03/unbound-dns-server-cache-control/

dnssec

How to test and validate DNSSEC using dig command line https://www.cyberciti.biz/faq/unix-linux-test-and-validate-dnssec-using-dig-command-line/

A Short Practical Tutorial of dig, DNS and DNSSEC https://metebalci.com/blog/a-short-practical-tutorial-of-dig-dns-and-dnssec/

How To Test Recursive Server (So You Think You Are Validating) https://dnsinstitute.com/documentation/dnssec-guide/ch03s02.html

What are all the flags in a dig response? https://serverfault.com/questions/729025/what-are-all-the-flags-in-a-dig-response/729121

upon reboot

Preserving unbound cache across reboots https://misc.openbsd.narkive.com/gk9c44Ga/preserving-unbound-cache-across-reboots

[SOLVED] Can unbound dns server use persistent caching? https://bbs.archlinux.org/viewtopic.php?id=205494

family-shield

Configuring Unbound as a simple forwarding DNS server https://www.redhat.com/sysadmin/forwarding-dns-2

Configure DNS forwarding on Unbound https://learn.akamai.com/en-us/webhelp/enterprise-threat-protector/enterprise-threat-protector/GUID-50A942A0-B474-488E-9A79-3ED0E5E88226.html

8 Free DNS Services to Block Porn Sites without Installing Software https://www.raymond.cc/blog/how-to-block-pornographic-websites-without-spending-money-on-software/

HOW TO BLOCK PORN ON ANY DEVICE. FOR FREE. https://protectyoungeyes.com/how-to-block-porn-on-any-device-for-free/

Anyone know of a good blocklist for porn / adult content? https://www.reddit.com/r/pihole/comments/a6crei/anyone_know_of_a_good_blocklist_for_porn_adult/

5 DNS Services to Block Porn Sites without Installing Software https://jamiat.org.za/5-dns-services-to-block-porn-sites-without-installing-software/

How does DNS blacklisting work https://superuser.com/questions/1144929/how-does-dns-blacklisting-work –> DIY

About Blacklists https://docs.infoblox.com/display/NAG8/About+Blacklists –> DIY

Add porn blocking to your Pi-hole https://mangolassi.it/topic/16905/add-porn-blocking-to-your-pi-hole –> DIY

todo

Config for running Unbound as a caching DNS forwarder (performance settings optimized for Raspberry Pi 2). https://gist.github.com/MatthewVance/5051bf45cfed6e4a2a2ed9bb014bcd72 –> forward-tls-upstream: yes


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5
Copyright © 2022 Pierre-Philipp Braun