Nethence Newdoc Olddoc Lab Your IP BBDock  

Setting up NSD from scratch

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[(,

sha256sum nsd-4.1.17.tar.gz
# Checksum sha256: 107fa506d18ed6fd0a922d1b96774afd9270ec38ec6b17cd7c46fb9433a03a6c 
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](,

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/"
    hide-version: yes
        #round-robin: yes

        control-enable: yes

        name: "stdpierrekey"
        secret: PASTE SECRET HERE

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

        name: ""
        zonefile: "zones/10.1.1.db"


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/

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/ Permission denied

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


Home | GitHub | Docker Hub | Donate | Contact