Troubleshooters.Com®, Linux Library and Unbound and NSD Present:

NSD, an Authoritative Server to go with Unbound

CONTENTS

Introduction

Unbound is the new kid on the block when it comes to DNS resolvers. NSD is the Authoritative DNS nameserver, by the same developers, made to match Unbound. More and more people are are finding out that NSD is as easy to set up as BIND9, and a lot less complicated. In many cases, zone files for BIND9 work with NSD.

NSD is a true authoritative nameserver, perfectly suited to be authoritative over a group of computers, or a group of groups of groups. Like BIND, it can do master/slave to provide redundancy.

Glossary

Due to the complete mess that's been made of DNS related terminology, it's essential to read my DNS Glossary while reading this document.

Troubleshooting Tools

A few troubleshooting tools enable you to "look inside" what would otherwise be a black box, in order to quickly diagnose problems. The first such tools are a pair of tools that pretty much replicate each others' features: dig and nslookup. I use both, because the redundancy can sometimes prevent me following a bad assumption. Also, I've recently begun to use drill, a nice tool similar to dig from NLnet Labs, the same folks who make nsd and unbound. To install it, try your distro's ldnsutils or ldns package.

A few troubleshooting tools enable you to "look inside" what would otherwise be a black box, in order to quickly diagnose problems. The first such tools are a pair of tools that pretty much replicate each others' features: dig and nslookup. I use both, because the redundancy can sometimes prevent me following a bad assumption. Also, I've recently begun to use drill, a nice tool similar to dig from NLnet Labs, the same folks who make nsd and unbound. To install it, try your distro's ldnsutils or ldns package.

The following is how you use these programs to look up forward DNS at the server pointed to in your /etc/resolv.conf:

dig firewall.home.lan
nslookup firewall.home.lan

The following is how you do reverse DNS at the server listed in your /etc/resolv.conf:

dig -x 192.168.47.171
nslookup 192.168.47.171

In the preceding, note that dig makes you declare it to be a reverse lookup with the -x option, while nslookup deduces it's a reverse lookup by the dot4 notation of its argument.

What's been discussed so far dealt with inquiring at the resolver at the IP address contained in /etc/resolv.conf. We all know half the DNS problems we encounter are wrong values in /etc/resolv.conf, especially with various "resolv.conf tools" sneaking in and changing the file's contents. So both of these troubleshooting tools give you a way to do the query at any specific server you want:

# Look up on auth-only NSD server at 189 NSD:
dig  @192.168.47.189  firewall.home.lan  
nslookup firewall.home.lan  192.168.47.189

# Look up on the Unbound recursive 
#  nameserver at 102, which refers to 
#  192.168.47.189 for queries in the 
#  home.lan domain:
dig  @192.168.47.102  firewall.home.lan  
nslookup firewall.home.lan  192.168.47.102

If something resolves at one IP address but not at another, you can exploit the differences to quickly find the root cause.

The unbound-checkconf, nsd-checkconf, and nsd-checkzone syntax-check their respective files, to find syntax errors. Finding a syntax error with one of these can save you a half hour over narrowing things down until the conf or zone file is finally implicated. Every time you change a conf or zone file, you should run the appropriate checker before continuing.   Every   single   time!

Conf Reloaders

As a habit, every single time, when you change a conf or zone file, you should either stop and restart the corresponding service, or get the service to reload the config without stopping and starting. Stopping and starting is the sure way to make sure you start with a clean slate, but isn't always needed.

The most surefire way is to use your init system (runit, s6, sysvinit, systemd, OpenRC) or process supervisor (damontools, daemontools-encore). You can also send a HUP signal to nsd, or use the unbound-control reload command to get Unbound to reload its config and drop its cache.

NSD Installation

Unbound is fast becoming the go-to DNS resolver, and NSD is meant to go with Unbound, so it's very likely your Linux distribution will have an excellently crafted NSD package. If not, you'll need to compile, but let's assume you have a package.

Configuration is performed in the main config file, and in the zone files: One zone file for each DNS authoritative nameserver. The main config file usually defaults to nsd.conf. Look for it in directories such as /usr/local/etc/nsd/, which is the default by the developers of NSD, as well as in /etc/nsd, or perhaps even /etc On my computer defaulting to /etc/nsd/nsd.conf on my computer. Depending on your distro, your milelage may value., including authoritative DNS definitions, is done in the unbound.conf file, which is typically in the /etc/unbound directory. You need to be user root to edit it.

Pay HUGE Attention to the Config Directory

It's easy to be led astray by config directory problems. My suggestion is this: No matter what your distro and/or tutorial have in mind, keep your main config file and all zone files in a single directory. That directory should NOT be /etc, but it can be under /etc: Perhaps /etc/nsd, for instance. /usr/local/etc/nsd is also fine. Also make sure all your key files go in that same directory. Tremendous confusion can ensue if your zone files are in a different directory than your main config file.

The makers of NSD have chosen /usr/local/etc/nsd/ as the directory in which to put the nsd.conf config file. Various distros decide to put it in other directories, which is fine. However, if your distro insists on putting it directly in /etc, I strongly suggest you run your nsd command pointing to a config file in a different directory, and make sure all zone files and key files are looked for in that directory. This will involve making all filenames in all configs and zones absolute, but it's worth it. You don't want NSD's config intermingled with that of 200 other applications.

DANGEROUS MENACE!

The NSD tutorial from Calomel.Org has nsd.conf point to /etc/nsd3 for zone files, yet, at least on my distro, the default config dir is /etc/nsd, not /etc/nsd3.

This can cause all sorts of time consuming problems if you're not looking for it. I'd recommend setting all zone file locations to the default NSD conf directory.

Resolv.Conf Has Nothing to do with NSD

The /etc/resolv.conf file should point to a resolver like your local Unbound resolver or perhaps a public DNS resolver like 8.8.8.8. It should never point at an authoritative-only authoritative nameserver like NSD or tinydns.

An NSD auth-only authoritative nameserver should always be able to resolve the local domain's hosts at whatever IP address it's set to listen to, and that's the sum and total of NSD's responsibility.

If a local recursive resolver such as Unbound, which does need to match the IP address in /etc/resolv.conf, wants to get local DNS from NSD, then that Unbound must include a stub reference to the NSD authoritative nameserver. But that's Unbound's business, not NSD's.

Use nsd-checkconf and nsd-checkzone Early and Often

The nsd-checkconf and nsd-checkconf programs check your config and zone files. They must be run with full paths to the config or zone files, so the current directory is never an issue.

Run this program every time you change any config or zone files. Fix any errors. This saves a lot of troubleshooting.

WARNING!

When running nsd-checkzone on the reverse DNS zone, your command must have a zone name argument of a form similar to 47.168.192.in-addr.arpa. If you were to use a zone name of the form home.lan, nsd-checkzone

would give you the dreaded "SOA record with invalid domain name" error, followed by the dreaded "out of zone data" error. If you're not aware of what causes this error, you can traverse some mighty winding paths trying to figure it out.

The NSD Tutorial and its Landmines

The best way of learning NSD is via the tutorial from Calomel, makers of NSD, at https://calomel.org/nsd_dns.html. In order to make your tutorial usage stress free, let's discuss a few of the tutorial's landmines to avoid:

Be sure to check your config file:

Telling the Unbound Resolver to Use the NSD server

Let's say you have a local domain, called home.lan, that has its own authoritative DNS nameserver. A real authoritative nameserver, not just a few domain definitions grafted on to a resolver. Let's say the home.lan DNS authoritative nameserver is at 192.168.47.189. This section shows how to direct queries for anything on domain home.lan to that nameserver at 192.168.47.189:

Add the following to the very bottom of /etc/unbound.conf in order that Unbound can respond to forward DNS queries on domain home.lan:

stub-zone:
  name: "home.lan"
  stub-addr: 192.168.47.189

BE SURE not to accidentally put the preceding in the middle of the server section. Be sure to use unbound-checkconf after the edit and before running Unbound.

But what about reverse queries, where the IP address is given and the fully qualified domain name is needed? This is a little more complicated:

local-zone: "168.192.in-addr.arpa." nodefault #FANTASTIC MAGIC!
stub-zone:
  name: "home.lan"
  stub-addr: 192.168.47.189
stub-zone:
  name: "47.168.192.in-addr.arpa."
  stub-addr: 192.168.47.189

In the preceding, a reverse DNS stub zone has been added. That's pretty straightforward. But what the heck is that local zone? It's needed because Unbound's default behavior is to send all IP addresses to the root nameservers to be resolved, rather than resolving them on a local NSD authoritative nameserver.

OK, that makes sense, but why does the local zone not have a 47 before the 168? Short answer: It's fantastic magic, just do it that way. Long answer, see the Referring Queries To A Real Authoritative nameserver section of Troubleshooters.Com's Unbound document.

Appendix A: The /etc/nsd/nsd.conf File

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

  # 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: "Steves Stuff"

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


zone:
    name: home.lan
    zonefile: /etc/nsd/home.lan.forward


zone:
    name: 100.168.192.in-addr.arpa.
    zonefile: /etc/nsd/home.lan.reverse

Appendix B: The /etc/nsd/home.lan.forward File

;## ;## NSD authoritative only DNS
;## home.lan.zone .:. https://calomel.org
;## 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    192.168.47.171
firewall   IN     TXT  "Testing...1...2...3"
laptop     IN     A    192.168.47.172
xbox360    IN     A    192.168.47.173
ps3        IN     A    192.168.47.174
dhcp5      IN     A    192.168.47.175
guest      CNAME       dhcp5
mail       IN     A    192.168.47.176
ns1        IN     A    192.168.47.189
*          IN     A    192.168.47.254

;## NSD authoritative only DNS
;## home.lan.zone .:. https://calomel.org
;## FORWARD Zone - home.lan.forward;## NSD authoritative only DNS
NSD authoritative only DNS
;## home.lan.zone .:. https://calomel.org
;## 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    192.168.47.171
firewall   IN     TXT  "Testing...1...2...3"
laptop     IN     A    192.168.47.172
xbox360    IN     A    192.168.47.173
ps3        IN     A    192.168.47.174
dhcp5      IN     A    192.168.47.175
guest      CNAME       dhcp5
mail       IN     A    192.168.47.176
ns1        IN     A    192.168.47.189
*          IN     A    192.168.47.254

Appendix C: The /etc/nsd/home.lan.reverse File

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


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

171.47.168.192.in-addr.arpa.     IN PTR firewall
172.47.168.192.in-addr.arpa.     IN PTR laptop
173.47.168.192.in-addr.arpa.     IN PTR xbox360
174.47.168.192.in-addr.arpa.     IN PTR ps3
175.47.168.192.in-addr.arpa.     IN PTR dhcp5
176.47.168.192.in-addr.arpa.     IN PTR mail
189.47.168.192.in-addr.arpa.     IN PTR ns1

[ Training | Troubleshooters.Com | Email Steve Litt ]