Skip to main content

Quick Start Guide

This guide will help you get NSD serving DNS queries in just a few minutes. We’ll set up a basic authoritative name server for an example domain.
This guide assumes you have already installed NSD on your system.

Overview

In this quick start, you will:
  1. Create a basic NSD configuration
  2. Set up remote control with nsd-control
  3. Create a zone file for your domain
  4. Start the NSD server
  5. Test DNS queries
  6. Verify everything is working

Step 1: Initial Setup

1

Create Configuration Directory

First, ensure the NSD configuration directory exists:
sudo mkdir -p /etc/nsd/zones
sudo chown -R nsd:nsd /etc/nsd/zones
2

Generate Control Keys

Set up nsd-control for managing NSD:
sudo nsd-control-setup
This creates TLS certificates in /etc/nsd/ for secure communication with nsd-control.
3

Check NSD Version

Verify NSD is installed:
nsd -v
You should see output like:
NSD 4.14.2

configured with:
  --enable-ratelimit
  --with-libevent

Step 2: Create NSD Configuration

Create a basic configuration file at /etc/nsd/nsd.conf:
/etc/nsd/nsd.conf
# NSD configuration file

server:
    # Run as the nsd user
    username: nsd
    
    # Listen on all interfaces
    # ip-address: 0.0.0.0
    # ip-address: ::0
    
    # Use 1 server process (increase for multi-core systems)
    server-count: 1
    
    # IPv4 and IPv6 support
    do-ip4: yes
    do-ip6: yes
    
    # Port to answer queries on
    port: 53
    
    # Logging
    logfile: "/var/log/nsd.log"
    verbosity: 1
    
    # PID file location
    pidfile: "/var/run/nsd.pid"
    
    # Zone files directory
    zonesdir: "/etc/nsd/zones"
    
    # Database directory for state files
    database: ""
    xfrdfile: "/var/lib/nsd/xfrd.state"
    zonelistfile: "/var/lib/nsd/zone.list"

# Remote control configuration
remote-control:
    # Enable nsd-control
    control-enable: yes
    
    # Listen only on localhost for security
    control-interface: 127.0.0.1
    control-interface: ::1
    
    # Control port
    control-port: 8952
    
    # TLS certificates (generated by nsd-control-setup)
    server-key-file: "/etc/nsd/nsd_server.key"
    server-cert-file: "/etc/nsd/nsd_server.pem"
    control-key-file: "/etc/nsd/nsd_control.key"
    control-cert-file: "/etc/nsd/nsd_control.pem"

# Define a zone
zone:
    name: example.com
    zonefile: example.com.zone
Configuration highlights:
  • server-count: 1 - Runs one server process. Increase this to match CPU cores for better performance.
  • zonesdir - All zone file paths are relative to this directory
  • control-enable: yes - Enables nsd-control for management
  • control-interface: 127.0.0.1 - Only allows local control for security

Configuration for Multiple CPU Cores

For production systems with multiple cores, optimize performance:
Multi-core configuration
server:
    # Use one process per CPU core
    server-count: 4
    
    # Pin each server to a dedicated CPU core
    server-1-cpu-affinity: 0
    server-2-cpu-affinity: 1
    server-3-cpu-affinity: 2
    server-4-cpu-affinity: 3
    
    # Pin xfrd to its own core
    xfrd-cpu-affinity: 4
    
    # Enable socket reuse for better performance
    reuseport: yes

Step 3: Create a Zone File

Create your first zone file at /etc/nsd/zones/example.com.zone:
/etc/nsd/zones/example.com.zone
; Zone file for example.com
$ORIGIN example.com.
$TTL 3600

; SOA Record (Start of Authority)
@   IN  SOA  ns1.example.com. admin.example.com. (
              2024030801  ; Serial (YYYYMMDDNN format)
              3600        ; Refresh (1 hour)
              1800        ; Retry (30 minutes)
              604800      ; Expire (1 week)
              86400 )     ; Minimum TTL (1 day)

; Name Server Records
    IN  NS   ns1.example.com.
    IN  NS   ns2.example.com.

; A Records (IPv4)
@       IN  A    192.0.2.1
ns1     IN  A    192.0.2.10
ns2     IN  A    192.0.2.11
www     IN  A    192.0.2.1
mail    IN  A    192.0.2.20

; AAAA Records (IPv6)
@       IN  AAAA 2001:db8::1
www     IN  AAAA 2001:db8::1

; MX Record (Mail Exchange)
@       IN  MX   10 mail.example.com.

; TXT Records
@       IN  TXT  "v=spf1 mx -all"
_dmarc  IN  TXT  "v=DMARC1; p=reject; rua=mailto:[email protected]"

; CNAME Record
ftp     IN  CNAME www.example.com.
Zone file key points:
  • $ORIGIN - Sets the domain name for the zone
  • $TTL - Default Time-To-Live for records (in seconds)
  • SOA Serial - Must be incremented with each zone update
  • Serial format - Use YYYYMMDDNN (year, month, day, revision number)

Setting Proper File Permissions

sudo chown nsd:nsd /etc/nsd/zones/example.com.zone
sudo chmod 640 /etc/nsd/zones/example.com.zone

Step 4: Validate Configuration

Before starting NSD, validate your configuration:
1

Check Configuration Syntax

sudo nsd-checkconf /etc/nsd/nsd.conf
If valid, you’ll see no output. Errors will be displayed if found.
2

Check Zone File Syntax

sudo nsd-checkzone example.com /etc/nsd/zones/example.com.zone
This validates the zone file format and records.
3

Review Configuration

Display the effective configuration:
sudo nsd-checkconf -o server /etc/nsd/nsd.conf
This shows how NSD will interpret your config.
Always validate configuration before restarting NSD in production. Invalid configs can cause NSD to fail to start.

Step 5: Start NSD

Now start the NSD server:
# Start NSD
sudo systemctl start nsd

# Check status
sudo systemctl status nsd

# Enable auto-start on boot
sudo systemctl enable nsd

# View logs
sudo journalctl -u nsd -f

Verify NSD is Running

# Check if NSD process is running
ps aux | grep nsd

# Check if NSD is listening on port 53
sudo netstat -tulpn | grep :53
# or with ss
sudo ss -tulpn | grep :53

# Use nsd-control
sudo nsd-control status
Expected output from nsd-control status:
version: 4.14.2
verbosity: 1
ratelimit: off
server1 zone example.com state ok

Step 6: Test DNS Queries

Test that NSD is serving your zone correctly:
1

Query from Localhost

Test basic A record query:
dig @localhost example.com A +short
Expected output:
192.0.2.1
2

Query Different Record Types

Test various DNS record types:
# NS records
dig @localhost example.com NS +short

# SOA record
dig @localhost example.com SOA +short

# MX record
dig @localhost example.com MX +short

# AAAA record (IPv6)
dig @localhost example.com AAAA +short

# Specific hostname
dig @localhost www.example.com A +short
3

Test from Remote Host

If NSD is accessible externally, test from another machine:
# Replace 192.0.2.10 with your server's IP
dig @192.0.2.10 example.com A

Using Different Query Tools

# Full query with details
dig @localhost example.com ANY

# Check DNSSEC (if enabled)
dig @localhost example.com +dnssec

# Trace delegation
dig @localhost example.com +trace

Managing NSD

Common Management Tasks

1

Reload Configuration

After changing zone files:
# Reload all zones
sudo nsd-control reload

# Reload specific zone
sudo nsd-control reload example.com
2

View Statistics

Check server statistics:
sudo nsd-control stats
Shows query counts, zone info, and performance metrics.
3

Add Zone Dynamically

Add a new zone without restarting:
# Add zone to running NSD
sudo nsd-control addzone example.net /etc/nsd/zones/example.net.zone

# Zone is now served immediately
dig @localhost example.net SOA
4

Stop NSD

Gracefully stop the server:
# Using nsd-control
sudo nsd-control stop

# Or systemd
sudo systemctl stop nsd

Monitoring Logs

# View NSD log file
sudo tail -f /var/log/nsd.log

# Or with systemd
sudo journalctl -u nsd -f

# Check for errors only
sudo journalctl -u nsd -p err

Updating Zone Data

When you modify zone files:
1

Increment Serial

Edit /etc/nsd/zones/example.com.zone and increment the SOA serial:
@   IN  SOA  ns1.example.com. admin.example.com. (
              2024030802  ; Serial - incremented from 2024030801
              3600
              1800
              604800
              86400 )
2

Validate Changes

Check the updated zone file:
sudo nsd-checkzone example.com /etc/nsd/zones/example.com.zone
3

Reload Zone

Apply the changes:
sudo nsd-control reload example.com
4

Verify Update

Check the new serial is active:
dig @localhost example.com SOA +short
Should show the new serial number.

Troubleshooting

NSD Won’t Start

sudo nsd-checkconf /etc/nsd/nsd.conf
Fix any reported errors.
Check what’s using port 53:
sudo netstat -tulpn | grep :53
Stop conflicting services (systemd-resolved, dnsmasq, etc.):
# Disable systemd-resolved
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
Ensure NSD runs as root initially (it will drop privileges):
sudo nsd -c /etc/nsd/nsd.conf
Check file permissions:
ls -la /etc/nsd/zones/
sudo journalctl -u nsd -n 50
# or
sudo tail -n 50 /var/log/nsd.log

Queries Not Working

sudo ss -tulpn | grep nsd
Should show NSD listening on 0.0.0.0:53 and/or [::]:53
# Allow DNS in firewall
sudo ufw allow 53/tcp
sudo ufw allow 53/udp

# Or iptables
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
dig @localhost example.com A +trace +dnssec
Look for error messages in the output.
Edit /etc/nsd/nsd.conf:
server:
    verbosity: 3
Then reload:
sudo nsd-control reconfig

Production Checklist

Before deploying NSD in production:
  • Set appropriate server-count for your CPU cores
  • Configure CPU affinity for multi-core systems
  • Enable rate limiting to prevent abuse
  • Set up secondary nameservers with zone transfers
  • Configure TSIG keys for secure zone transfers
  • Enable DNSSEC if required
  • Set up monitoring and alerting
  • Configure automatic log rotation
  • Test failover scenarios
  • Document your configuration

Next Steps

Now that you have NSD running, explore advanced features:

Zone Transfers

Set up primary/secondary DNS with AXFR/IXFR

DNSSEC

Secure your zones with DNSSEC signing

Rate Limiting

Configure response rate limiting

Performance Tuning

Optimize NSD for high query volumes
For comprehensive documentation, see the official NSD documentation and use man nsd.conf for complete configuration reference.

Build docs developers (and LLMs) love