Setting up NSD


either use your distro’s binaries or see NSD from scratch

Prep for remote control

you can also control-enable: no and skip the key setup if you do not plan to transfer (or receive?) any zone

generate two private keys and two self-signed SSL certificates

cd /etc/nsd/
ll /etc/nsd/*.key
ll /etc/nsd/*.pem

eventually generate a secret for zone transfers

dd if=/dev/random count=1 bs=32 | base64
#dd if=/dev/urandom count=1 bs=32 | base64

Setup NSD w/o chroot

how many cores do you have?

grep ^processor /proc/cpuinfo
dmesg | egrep '(^|] )cpu[[:digit:]]+:'

edit the configuration accordingly and define e.g. example.local and its reverse name spaces

vi /etc/nsd/nsd.conf
vi /var/chroot/nsd/nsd.conf

    do-ip4: yes
    do-ip6: no
    verbosity: 1
    #verbosity: 3
    #username: _nsd
    username: nsd
    server-count: HOW_MANY_CORES
    #pidfile: "/var/run/nsd/"
        pidfile: "/var/db/nsd/"
    hide-version: yes
    version: "NSD"
    #round-robin: yes

#   control-enable: no

    control-enable: yes
    control-port: 8952
    server-key-file: "/etc/nsd/nsd_server.key"
    server-cert-file: "/etc/nsd/nsd_server.pem"
    control-key-file: "/etc/nsd/nsd_control.key"
    control-cert-file: "/etc/nsd/nsd_control.pem"

    name: "HOSTkey"
    algorithm: hmac-sha256
    secret: "PASTE SECRET HERE"

    name: "example.local"
    zonefile: "%s.db"

    name: ""
    zonefile: "a.b.c.db"

Note: round-robin would only apply to identical record names pointing to different values/destinations. Besides, it should be for the resolvers to handle the server response properly, whatever the order of the records. So I guess this server-side setup is just a hack against broken clients.

Setup zones

date +%s
vi /var/chroot/var/db/$zone.db

$ORIGIN example.local.
$TTL 1800

@       IN      SOA     example.local. abuse.example.local. (
                        SERIAL-HERE             ; serial number
                        3600                    ; refresh
                        900                     ; retry
                        1209600                 ; expire
                        1800                    ; ttl

                IN NS           ns.example.local.
                IN MX           5 mx
                IN A            INTERNAL_IP
*               IN A            INTERNAL_IP
ns              IN A            INTERNAL_IP
mx              IN A            INTERNAL_IP
host            IN A            INTERNAL_IP
pxe             IN CNAME        host

Additional notes


you will get two errors

unable to open the database /var/db/nsd/nsd.db: Permission denied
failed to unlink pidfile /var/run/ Permission denied

so fix the perms accordingly and create a dedicated folder for pid (draft THOSE NEED TO BE GENERATED BY THE SAME USER THAT RUNS NSD-CONTROL in case it is not root, and which supposedly may not be the same as the running daemon)

pgrep -a nsd

ll /var/run/nsd/
rm -f /var/run/nsd/
chown -R nsd:nsd /var/run/nsd/

ll /var/db/nsd/
rm -f /var/db/nsd/nsd.db
chown -R nsd:nsd /var/db/nsd/


no need for those

rmdir /etc/nsd/
rmdir /var/run/nsd/
rmdir /var/db/nsd/

the dirty way

    pidfile: "/var/chroot/nsd/var/"
    chroot: "/var/chroot/nsd"
    zonesdir: "/var/chroot/nsd/etc"
    zonelistfile: "/var/chroot/nsd/var/zone.list"
    database: "/var/chroot/nsd/var/nsd.db"
    #xfrdfile: ""
    xfrdfile: "/var/chroot/nsd/var/xfrd.state"
    xfrdir: "/var/chroot/nsd/var"

chown root:wheel /var/chroot/nsd/
chmod 755 /var/chroot/nsd/

chown -R root:wheel /var/chroot/nsd/etc/
chmod 755 /var/chroot/nsd/etc/
chmod 644 /var/chroot/nsd/etc/*

chown -R nsd:nsd /var/chroot/nsd/var/
chmod 700 /var/chroot/nsd/var/
chmod 600 /var/chroot/nsd/var/*

–> nsd.conf and ZONE.db are root:wheel while nsd.db and xfer are nsd:nsd

the clean way

#ll /var/chroot/nsd/var/db/
#ll /var/chroot/nsd/var/db/nsd/
#ll /var/chroot/nsd/var/run/
#mkdir /var/chroot/nsd/tmp/
#chown -R root:wheel /var/chroot/nsd/
#chown -R nsd:nsd /var/chroot/nsd/var/db/
#chown -R nsd:nsd /var/chroot/nsd/var/run/
#chown -R nsd:nsd /var/chroot/nsd/tmp/

also getting the error

nsd[31659]: /nsd.db: Permission denied
nsd[31659]: unable to open the database /nsd.db: Permission denied

==> fix perms for nsd.db as shown above in a dedicated and chroot var/ folder

serve Unbound

it seems only Unbound has special restrictions on serving localhost. NSD serves localhost just fine by default

NSD binds to all interfaces by default (incl. localhost) but we want to use Unbound on the same host

vi /etc/nsd/nsd.conf

    ip-address: ::1@5353

Secondary NS

notify & XFR to backup NS

        name: ""
        zonefile: "%s.db"
        notify: x.x.x.x NOKEY
        provide-xfr: x.x.x.x NOKEY

Ready to go w/o remote control

read the logs

tail -F /var/log/messages
tail -F /var/log/syslog


which nsd
nsd -v

#w/o chroot
nsd-checkconf /etc/nsd/nsd.conf && echo OK
nsd-checkzone $domain /etc/nsd/$domain.db
nsd-checkzone $domain /etc/nsd/$domain.db.signed

#w/ chroot
nsd-checkconf /var/chroot/nsd/nsd.conf && echo OK
    nsd-checkzone $domain /var/chroot/nsd/$domain.db
    nsd-checkzone $domain /var/chroot/nsd/$domain.db.signed

warning: DO NOT ENABLE TMEM otherwise you will get

Out of memory: Killed process 3865 (nsd: xfrd) total-vm:109688kB, anon-rss:83596kB, file-rss:0kB, shmem-rss:0kB

enable at startup

vi /etc/rc.local

/usr/local/sbin/nsd -4


pgrep -a nsd
cat /var/run/nsd/
cat /var/db/nsd/
cat /var/chroot/nsd/
netstat -lntup | grep 53


#kill -HUP PID
pkill -HUP nsd


pkill nsd

Ready to go w/ remote control

enable at startup

echo starting nsd
/usr/local/sbin/nsd-control start


nsd-control status

status for the zones

nsd-control zonestatus 


#nsd-control reload [<zone>]
#nsd-control reconfig


verify a few records

host $domain localhost
host -t ns $domain localhost
host -t mx $domain localhost
host ns.$domain localhost
host mx.$domain localhost

dig $domain @localhost +short
dig -t ns $domain @localhost +short
dig -t mx $domain @localhost +short
dig ns.$domain @localhost +short
dig mx.$domain @localhost +short

and proceed with online checking


on-going draft

problems sending reload xfrdtomain: Broken pipe
May 12 13:10:45 malabar nsd[13294]: did not get start signal from main

==> this does not help:

rm -f /var/db/nsd/nsd.db /var/run/ /var/run/nsd/
ll /var/db/nsd/

rm -rf /var/chroot/nsd/nsd.db /var/chroot/nsd/ /var/chroot/nsd/nsd-xfr-*/
ll /var/chroot/nsd/

this neither

CFLAGS="-g -O2"
/usr/local/sbin/nsd -V 5
-F -1 -L 2

friendly MWE

        username: nsd
        pidfile: "/var/run/"

        control-enable: no

        name: "example.local"
        zonefile: "%s.db"

a few more options e.g. for NetBSD

        username: _nsd
        pidfile: "/var/run/nsd/"

start with extreme verbosity

nsd -4 -V 5


apt install nsd

cd /etc/nsd/
mkdir .trash/
mv nsd.conf nsd.conf.d/ .trash/
zcat /usr/share/doc/nsd/examples/nsd.conf.sample.gz > nsd.conf.sample
sed -r '/^[[:space:]]*(#|$)/d' nsd.conf.sample > nsd.conf

systemctl start nsd
#systemctl restart nsd
#systemctl reload nsd


Re: No buffer space available

FS#37588 - Nsd update to 4.0.0-1 causes nsd to fail to start and command nscd not present

NSD not starting after upgrade

[nsd-users] NSD db permissions error after upgrade?

[nsd-users] NSD 4.0.2 released


man 8 nsd /

man 5 nsd.conf /

man 8 nsd-control /

man 8 nsd-checkconf /

man 8 nsd-checkzone /

How To Use NSD, an Authoritative-Only DNS Server, on Ubuntu 14.04

How to get a random string of 32 hexadecimal digits through command line?

backup NS

Secondary DNS at