First of all – we add the required packages :
( If running on an rpi2 – we first install pkg properly using ports :
cd /usr/ports/ports-mgmt/pkg
make && make install
)
Now we install the required packages :
pkg install base64 nsd
Then we prepare the chrooted environment :
mkdir -p /usr/local/etc/nsd/var/db/nsd
mkdir -p /usr/local/etc/nsd/var/run/nsd
mkdir /usr/local/etc/nsd/var/log
mkdir /usr/local/etc/nsd/tmp
Third we add the required line to rc.conf :
echo  'nsd_enable="YES"' >> /etc/rc.conf
We can then proceed with the generation of a nice TSIG key :
first make sure we are in the right directory :
 cd /usr/local/etc/nsd
dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64
1+0 records in
1+0 records out
32 bytes transferred in 0.000035 secs (913046 bytes/sec)
A_long_and_garbled_key_for_TSIG
then run :
nsd-control-setup
This generates a lot of “security” output .. which can usually be ignored 🙂
We must now edit the nsd.conf file to do what we want it to :
vi /usr/local/etc/nsd/nsd.conf
My file looks like this on the master server :
server:
        ip-address: 127.0.0.1
        ip-address: aaa.bbb.3.241
        debug-mode: no
        verbosity: 9
        username: nsd
        chroot: "/usr/local/etc/nsd"
        zonelistfile: "var/db/nsd/zone.list"
        database: "var/db/nsd/nsd.db"
        logfile: "/usr/local/etc/nsd/var/log/nsd.log"
        pidfile: "var/run/nsd/nsd.pid"
        xfrdfile: "var/db/nsd/xfrd.state"
        xfrdir: "tmp"
        hide-version: yes
        identity: "tentacled server"
        nsid: "ascii_ns1.lab.example.com"
remote-control:
        control-enable: yes
        server-key-file: "/usr/local/etc/nsd/nsd_server.key"
        server-cert-file: "/usr/local/etc/nsd/nsd_server.pem"
        control-key-file: "/usr/local/etc/nsd/nsd_control.key"
        control-cert-file: "/usr/local/etc/nsd/nsd_control.pem"
 key:
        name: "sec1_key"
        algorithm: hmac-sha256
        secret: "A_long_and_garbled_key_for_TSIG"
pattern:
        name: "TellTheMinions"
        notify: aaa.bbb.ccc.240 sec1_key
        provide-xfr: aaa.bbb.ccc.240 sec1_key
        notify-retry: 10
zone:
        name: "lab.example.com"
        zonefile: "lab.example.com.zone"
        include-pattern: "TellTheMinions"
zone:
        name: "3.bbb.aaa.in-addr.arpa"
        zonefile: "3.bbb.aaa.rev"
        include-pattern: "TellTheMinions"
An example zone-file :
$TTL 86400
$ORIGIN lab.example.com.
@  1D  IN SOA lab.example.com. adm.example.com. (
      2015120404
      1D
      2H
      7D
      1D)
@  IN  NS  ns1.lab.example.com.
@  IN  NS  ns2.lab.example.com.
@  IN  A  aaa.bbb.ccc.241
ucs1       IN      A       aaa.bbb.3.1
ucm01      IN      A       aaa.bbb.3.2
ucm02      IN      A       aaa.bbb.2.3
esxi-1     IN      A       aaa.bbb.2.11
esxi-2     IN      A       aaa.bbb.2.12
esxi-3     IN      A       aaa.bbb.2.13
An example reverse-zone file ( 3.bbb.aaa.rev ):
$TTL 1800
$ORIGIN 24/3.bbb.aaa.IN-ADDR.ARPA.
@ IN SOA ns1.lab.example.com. adm.example.com. (
 2015120410 ; serial number
 3600 ; refresh
 900 ; retry
 1209600 ; expire
 1800 ; ttl
 ) 
               IN NS ns1.lab.example.com.
               IN NS ns2.lab.example.com.
1  IN      PTR     ucs1.lab.example.com.
2  IN      PTR     ucs2.lab.example.com.
3  IN      PTR     ucs3.lab.example.com.
11 IN      PTR     esxi-1.lab.example.com.
12 IN      PTR     esxi-2.lab.example.com.
13 IN      PTR     esxi-3.lab.example.com.
Time to change ownership :
chown -R nsd:nsd /usr/local/etc/nsd
We should now be able to start the nameserver :
/usr/local/etc/rc.d/nsd start
OR 
nsd-control start
Verify that the server is running :
drill esxi-1.lab.example.com @localhost ANY
Output should look like :
;; ->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 29774
;; flags: qr aa rd ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 
;; QUESTION SECTION:
;; esxi-1.lab.example.com. IN      TYPE255
;; ANSWER SECTION:
esxi-1.lab.example.com. 86400 IN A       aaa.bbb.3.11
;; AUTHORITY SECTION:
lab.example.com.   86400   IN      SOA     lab.example.com. adm.example.com. 2015120404 86400 7200 604800 86400
;; ADDITIONAL SECTION:
;; Query time: 0 msec
;; SERVER: 127.0.0.1
;; WHEN: Fri Dec  4 14:51:09 2015
;; MSG SIZE  rcvd: 78
For some obscure reason I keep getting refused when attempting a reverse lookup like :
drill aaa.bbb.3.1 @localhost ANY
OR
drill aaa.bbb.3.1 @
nisse