home January 01, 2017

NSD DNS Tutorial


A Fast, Secure Authoritative Only DNS Server

NSD is an authoritative only, memory efficient, highly secure and simple to configure open source domain name server. NSD (name server daemon) is a server implementation for the Domain Name System (DNS). It is developed and maintained by NLnet Labs of Amsterdam in cooperation with the RIPE NCC. NSD was conceptually built from scratch as a purely authoritative name server; not implementing the recursive caching function by design. A dedicated validating, resolving caching DNS program like Unbound DNS (unbound.conf) is a perfect compliment to NSD allowing you to split your authoritative and resolving servers for significantly better security.

NSD uses BIND-style zone-files; zone-files used under BIND (named) can usually be supplied unmodified in NSD once declared in the nsd.conf configuration. NSD manages zone information compiled via 'zonec' into a binary database file (nsd.db) which allows lightning fast start up of the NSD name-service daemon, syntax structural verification and flagging of errors at database compile-time. All this before being made available to NSD service itself. Once NSD is running the database file grants the DNS server a very light memory footprint and incredibly fast domain name service ability even under extremely high network load. Much faster than BIND could ever achieve.

NSD is currently implemented on at least three(3) of the primary Internet ROOT name servers:

NSD is a powerful DNS solution and has been running in operation on the root servers for years. Lets take a look at some configuration examples.

HELPFUL HINT: Make sure to check out our Unbound DNS Tutorial (unbound.conf) for a secure validating, resolving caching DNS server. You can combine this NSD example server with a Unbound cluster for a bullet-proof DNS solution.

NSD DNS server install

The first task is to install NSD. We are going to use NSD v3.2.8 for this example. Make to get the latest version since you want to have all the newest features and bug fixes. Most modern operating systems have prebuilt packages (rpm, deb, tgz). You can always install NSD from source if you want. Here are a few package manager lines just to get started:

## CentOS
yum install nsd3

## Ubuntu
apt-get install nsd3

## OpenBSD
pkg_add -i nsd

For this example the basic setup of NSD is composed of the nsd.conf configuration file and two zone files for our domain "home.lan". Once those are in place you can rebuild the nsd.db database and start the daemon.

NSD server configuration (nsd.conf)

We have included both configuration files for a Primary and Secondary NSD server setup. If you only need a single NSD authoritative server without a backup then you only need to use the first config file for the Primary or "Master" NSD server.

This is the Primary or "Master" NSD configuration file. We set NSD to listen on the ip address of the external interface and set the port to 53, which is the default. For security, we are not going to allow external clients to query the name of our server software or the version number. The last few lines are for the zone "home.lan" and is what NSD is going to be authoritative for. The ip addresses are in the block of 10.0.0.0/8 . These ips are only allowed on private internal LANs.

The parent zone directory is "/etc/nsd3" and this is the directory all files will be located. You can change this directory if you need to. We put our nsd.conf and the zone configuration files, home.lan.forward and home.lan.reverse, in "/etc/nsd3" for easy maintenance and backup.

The directives "notify" and "provide-xfr" are only needed if you are also going to setup a secondary NSD server. Uncomment out these lines to use them.

## NSD authoritative only DNS
## nsd.conf .:. https://moneyslow.com/html/webconf
## Primary or "Master" NSD server
#

server:
  # uncomment to specify specific interfaces to bind (default all).
    ip-address: 10.0.0.111

  # port to answer queries on. default is 53.
    port: 53

  # Number of NSD servers to fork.
    server-count: 1

  # listen only on IPv4 connections
    ip4-only: yes

  # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries
    hide-version: yes

  # identify the server (CH TXT ID.SERVER entry).
    identity: ""

  # The directory for zonefile: files.
    zonesdir: "/etc/nsd3"

key:
   name: "sec_key"
   algorithm: hmac-md5
   secret: "6KM6qiKfwfEpamEq72HQdA=="

zone:
    name: home.lan
    zonefile: home.lan.forward
  # notify: 10.0.0.222@53 sec_key
  # provide-xfr: 10.0.0.222 sec_key


zone:
    name: 0.0.10.in-addr.arpa
    zonefile: home.lan.reverse
  # notify: 10.0.0.222@53 sec_key
  # provide-xfr: 10.0.0.222 sec_key


#
## NSD authoritative only DNS
## nsd.conf .:. https://moneyslow.com/html/webconf
## Primary or "Master" NSD server

This is the Secondary or "Slave" NSD configuration file. It can be used on the backup authroitative dns server. Zone transfers which are encrypted with the same "sec_key" are allowed from the primary on 10.0.0.111 to this box on 10.0.0.222. Again, this configuration is only needed if you are setting up a seconday NSD dns server.

## NSD authoritative only DNS
## nsd.conf .:. https://moneyslow.com/html/webconf
## Seconday or "Slave" NSD server
#

server:
  # uncomment to specify specific interfaces to bind (default all).
    ip-address: 10.0.0.222

  # port to answer queries on. default is 53.
    port: 53

  # Number of NSD servers to fork.
    server-count: 1

  # listen only on IPv4 connections
    ip4-only: yes

  # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries
    hide-version: yes

  # identify the server (CH TXT ID.SERVER entry).
    identity: ""

  # The directory for zonefile: files.
    zonesdir: "/etc/nsd3"

key:
   name: "sec_key"
   algorithm: hmac-md5
   secret: "6KM6qiKfwfEpamEq72HQdA=="

zone:
    name: home.lan
    zonefile: home.lan.forward
    allow-notify: 10.0.0.111 sec_key
    request-xfr: AXFR 10.0.0.111@53 sec_key

zone:
    name: 0.0.10.in-addr.arpa
    zonefile: home.lan.reverse
    allow-notify: 10.0.0.111 sec_key
    request-xfr: AXFR 10.0.0.111@53 sec_key

#
## NSD authoritative only DNS
## nsd.conf .:. https://moneyslow.com/html/webconf
## Seconday or "Slave" NSD server

NSD Forward zone configuration

Here is the NSD forward zone file for the domain home.lan were we define the hostname to ip address correlations. For example, firewall.home.lan will resolve to the ip address 10.0.0.1 . Included are text (TXT) records, NS, MX and CNAME pointers just for an example.

It is absolutely critical to set your "NS" name server hostname (ns1.home.lan to 10.0.0.111 in this example) to the same ip address NSD is listening on. In the nsd.conf you see above NSD is listening on 10.0.0.111. The reason this is so important is an resolving DNS server, like Unbound, will ask NSD what the current authoritative name server ip address is. NSD will say the name server for "home.lan" is "ns1.home.lan and its ip is 10.0.0.111. 10.0.0.111 is what the Unbound resolver will try to connect to.

This configuration is slightly different from a standard BIND (named) zone file. The example shows that NSD will accept variables for the ORIGIN hostname and the default TTL for all entries making the syntax a bit easier to read and change later.

Make special note of the record "* IN A 10.0.0.254". This is a glob or global catch all record. If a client asks for a hostname that does NOT exist this record will be returned to the client instead of an error. So, if a client asks for the ip address associated with the hostname blahblah.home.lan, which does not exist, the ip 10.0.0.254 is returned. You may or may not have a need for this type of record. The glob option was included just so you can see that this function is available.

;## NSD authoritative only DNS
;## home.lan.zone .:. https://moneyslow.com/html/webconf
;## FORWARD Zone -  home.lan.forward

$ORIGIN home.lan.    ; default zone domain
$TTL 86400           ; default time to live

@ IN SOA ns1.home.lan. admin.home.lan. (
           2011010203  ; serial number
           28800       ; Refresh
           7200        ; Retry
           864000      ; Expire
           86400       ; Min TTL
           )

           NS      ns1.home.lan.
           MX      10 mail.home.lan.

firewall   IN     A    10.0.0.1
firewall   IN     TXT  "Testing...1...2...3"
laptop     IN     A    10.0.0.2
xbox360    IN     A    10.0.0.3
ps3        IN     A    10.0.0.4
dhcp5      IN     A    10.0.0.5
guest      CNAME       dhcp5
mail       IN     A    10.0.0.6
ns1        IN     A    10.0.0.111
*          IN     A    10.0.0.254

;## NSD authoritative only DNS
;## home.lan.zone .:. https://moneyslow.com/html/webconf
;## FORWARD Zone - home.lan.forward

NSD Reverse zone configuration (rDNS)

The last file is the NSD reverse zone file for the domain home.lan where the ip to hostname reverse look-up is defined. When a client asks for the what ip address "10.0.0.3" resolves to, the NSD server will return xbox360.domain.lan .

The format of the file is similar to the BIND format, but we are taking advantage of using some default variables line ORIGIN and TTL.

;## NSD authoritative only DNS
;## home.lan.zone .:. https://moneyslow.com/html/webconf
;## REVERSE Zone - home.lan.reverse

$ORIGIN home.lan.  ; default zone domain
$TTL 86400         ; default time to live

0.0.10.in-addr.arpa. IN SOA ns1.home.lan. admin.home.lan. (
           2011010203  ; serial number
           28800       ; Refresh
           7200        ; Retry
           864000      ; Expire
           86400       ; Min TTL
           )

1.0.0.10.in-addr.arpa.   IN PTR firewall
2.0.0.10.in-addr.arpa.   IN PTR laptop
3.0.0.10.in-addr.arpa.   IN PTR xbox360
4.0.0.10.in-addr.arpa.   IN PTR ps3
5.0.0.10.in-addr.arpa.   IN PTR dhcp5
6.0.0.10.in-addr.arpa.   IN PTR mail
111.0.0.10.in-addr.arpa. IN PTR ns1

;## NSD authoritative only DNS
;## home.lan.zone .:. https://moneyslow.com/html/webconf
;## REVERSE Zone - home.lan.reverse

NSD configuration finished

Now that the nsd.conf and two zone files are in place the configuration is done. The final step is to compile the nsd database from the zone files and start the daemon. This is easily done and explained in the next section.

NSD database compile and reload

Anytime you make changes to the NSD forward or reverse zone files you must recompile the database for NSD (nsd.db) with "nsdc rebuild". When you make changes to the nsd.conf primary configuration file you need to notify he running NSD daemon to re-read nsd.conf and nsd.db database file by use "nsdc reload" . Another option is you could also just restart the NSD service after rebuilding the db file. Here is a quick reference to the commands:

## Recompile nsd database (nsd.db) after any changes 
## This is only done on the MASTER server
$ nsdc rebuild

## Notify the SECONDARY nsd servers to do a zone transfer
## This is only done on the MASTER server
$ nsdc notify

## reload nsd daemon
$ nsdc reload

## Dump the contents of the nsd.db file to the zone files
## This is usually done on the SECONDARY server
$ nscd patch

## RHEL, CentOS or Unbuntu server restart
/etc/init.d/nsd3 restart

HELPFUL HINT: Make sure to take a look at our simple DNS Verify script. It will verify forward and reverse name resolution of you local LAN hostnames. This is a very quick way to make sure your DNS setup is correct.

Questions?

I get the error, "xfrd: zone 0.0.10.in-addr.arpa received error code NOT IMPL from 10.0.0.111"

Make sure you specify that the seconday NSD server wants to do a AXFR transfer from the primary. This is done by adding AXFR to the transfer request line on the secondary NSD server like so, "request-xfr: AXFR 10.0.0.222@53 sec_key". This is just like the example we have above.

Is there another DNS testing tool other than dig ?

There is a tool called ldns. "dig" is a tool which normally comes with BIND or at least the dnsutils package. Both dig and named use similar libraries. For this reason it is a good idea to do testing with a DNS library independent tool like "ldns".

The goal of ldns is to simplify DNS programming as it supports recent RFCs like the DNSSEC documents and allows developers to easily create software conforming to current RFCs relating to experimental software for current Internet Drafts. A secondary benefit of using ldns is speed; ldns is written in C it should be a lot faster than Perl.

NOTE: the latest version of ldns depends on OpenSSL 1.0.0 or greater for many of its crypto functions. It can be compiled without OpenSSL, but of course you'll lose the ability to perform any cryptographic functions.

You can find find ldns at nlnetlabs.nl or through your OS's package manager.

How can I more easily sign my zones with DNSSEC ?

OpenDNSSEC is a tool which simplifies the process of signing one or more zones with DNSSEC. OpenDNSSEC handles the entire process from an unsigned to a signed zone automatically, including secure key management and timing issues. With OpenDNSSEC, fewer manual operations are needed by the operator. OpenDNSSEC makes sure that all the steps in signing process are done in the correct order and at the right time, making sure that nothing breaks. The issue of handling the private keys associated with DNSSEC signing has been secured by using so called HSM's (Hardware Security Modules), so that the private keys can not be leaked to an unauthorized third party, just keeping them secured in hardware.

OpenDNSSEC is an open source solution under a BSD license which gives a green light to suppliers of commercial products who want to utilize the open source code and include it in their own software, without having to open up their own code. OpenDNSSEC works in all Unix-like operating systems and is suitable for those who will only sign a single large zone (e.g. TLDs) and as well as those who have many small zones (e.g. web hosting companies, ISPs).

Will NSD ever be like BIND and resolve domains too ?No. NSD was conceived and built as an authoritative server only. It does one job and it does this very well. Being an authoritative only server segregates the job of DNS queries to only answering domain names which this server owns. Frequently, you will here of a BIND server which was incorrectly setup or compromised and allowing resolving queries from the general public. This type of violation can not happen on NSD as NSD can not do anything other than be authoritative for its zones.

How can I easily watch DNS traffic in real time ?

A program called "dnstop" is a nice tool. It is available though most package managers in your OS. Once installed just execute the binary with the argument of the interface you want to watch for DNS traffic. For example, we would execute "dnstop eth0" to watch traffic on the external network interface. There a few pages of options in dnstop that can be accessed using the number keys. The author's page has some examples of some DnsTop screen output looks like.

How much memory is NSD going to use ?

NLnet Labs has a really nice NSD memory estimate tool you can use. Each setup is going to be different and this tool will give you a general idea what you can expect.