on Ubuntu Server xenial or artful


Either install some binary package,

apt install nsd

Or build from scratch as follows.

Install a few needed libraries,

apt install build-essential \
    libevent-dev \

Fetch the latest [version[(https://www.nlnetlabs.nl/downloads/nsd/),

wget https://www.nlnetlabs.nl/downloads/nsd/nsd-4.1.17.tar.gz
sha256sum nsd-4.1.17.tar.gz
# Checksum sha256: 107fa506d18ed6fd0a922d1b96774afd9270ec38ec6b17cd7c46fb9433a03a6c 
#wget https://www.nlnetlabs.nl/downloads/nsd/nsd-4.1.17.tar.gz.asc
tar xzf nsd-4.1.17.tar.gz 
cd nsd-4.1.17/
#./configure --help|less
make install

Create an account for NSD to drop privileges (nsd by default),

useradd -r nsd
grep nsd /etc/passwd
grep 999 /etc/group
chown -R nsd:nsd /var/db/nsd/

Also create a dedicated folder for NSD's PID file,

mkdir /var/run/nsd/
chown nsd:nsd /var/run/nsd/

Generate the SSL keys and certificates](https://www.digitalocean.com/community/tutorials/how-to-use-nsd-an-authoritative-only-dns-server-on-ubuntu-14-04),

ls -lhF /etc/nsd/*.{key,pem}


Check the version you just got installed,

nsd -v

Note. we have 4.1.16 as provided by artful and 4.1.17 from source.

Check how much cores you got,

grep ^processor /proc/cpuinfo 

Generate a secret for zone transfers,

dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64

Edit the configuration accordingly, and define e.g. the example.local and reverses name spaces,

cd /etc/nsd/
#cp -pi nsd.conf.sample nsd.conf
mkdir trash
mv nsd.conf nsd.conf.d/ trash
zcat /usr/share/doc/nsd/examples/nsd.conf.sample.gz > nsd.conf.sample

vi nsd.conf

        server-count: HOW_MANY_CORES
        #binds to all interfaces by default
    verbosity: 2
        pidfile: "/var/run/nsd/nsd.pid"
    hide-version: yes
        #round-robin: yes

        control-enable: yes

        name: "stdpierrekey"
        secret: PASTE SECRET HERE

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

        name: "1.1.10.in-addr.arpa"
        zonefile: "zones/10.1.1.db"


  • 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.

Create the zone files accordingly e.g.,

mkdir /etc/nsd/zones/
cd /etc/nsd/zones/

date +%s
vi example.local.db

$ORIGIN example.local.
$TTL 1800

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

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

Ready to go

Always watch the logs in another window,

tail -F /var/log/syslog

Check your NSD configuration and start/restart the daemon,

nsd-checkconf /etc/nsd/nsd.conf
nsd-checkzone example.local /etc/nsd/zones/example.local.db 

#from source
nsd-control start
#nsd-control reconfig

#cat >> /etc/rc.local <<-EOF
#echo -n Starting NSD...
#/usr/local/sbin/nsd-control start

#as binary
systemctl restart nsd
#systemctl reload nsd

Check the status and see if port 53 is used or not,

nsd-control status

#from source
#ls -alhF /var/db/nsd/

#as binary
ls -alhF /var/lib/nsd/

ls -alhF /var/run/nsd/
cat /var/run/nsd/nsd.pid

ps auxfw | grep ^nsd
netstat -antupe --inet --inet6 | grep -E ':53[[:space:]]'

Check the status of the served zones,

nsd-control zonestatus example.local

To reload an edited zone,

nsd-control reload example.local

Acceptance Testing

Verify a few records e.g.,

host example.local localhost
host pxe.example.local localhost
host -t ns example.local localhost
host -t mx example.local localhost

dig example.local @localhost +short
dig pxe.example.local @localhost +short
dig -t ns example.local @localhost +short
dig -t mx example.local @localhost +short


If you get this error while stopping the daemon,

failed to unlink pidfile /var/run/nsd.pid: Permission denied

simply make sure you have created a dedicated folder for NSD's PID file as stated above.