Conversation with Gemini

You said

What is the best replacement for the BIND name server?

Gemini said

Because BIND handles both authoritative (serving your own domain records) and recursive (resolving queries for client devices) DNS, the "best" replacement depends on which role you need to fill.

Modern network architecture heavily favors separating these two roles for better security, performance, and stability.

Comparison of Top Alternatives

ServerPrimary RoleKey StrengthsBest Used For
UnboundRecursiveLightweight, secure, built-in DNSSEC validation, low memory usageInternal enterprise resolvers, local networks, home labs
NSDAuthoritativeUltra-lean, high speed, minimalistic codebase with low attack surfaceHosting static zone files securely without complexity
PowerDNSAuth & Recursive (separate binaries)DB backends (MySQL/PostgreSQL), REST APIs, rich Lua scriptingISPs, large enterprises, environments requiring dynamic DB integration
Knot DNSAuthoritativeMulti-threaded, extremely fast, handles millions of zonesHigh-traffic web hosts, TLD registries, large enterprise zones
CoreDNSFlexible / Service DiscoveryModular plugin system, written in Go, Kubernetes-nativeCloud-native environments, containers, microservices

Which Should You Choose?

1. If you need a local or enterprise Recursive Resolver

  • Choose Unbound: Developed by NLnet Labs specifically to replace BIND's resolver functionality. It is fast, security-focused, extremely stable, and the default resolver in systems like FreeBSD and PfSense.

  • Choose PowerDNS Recursor: If you need advanced traffic filtering, custom query rewriting, or Lua scripting at scale.

2. If you need an Authoritative DNS Server

  • Choose NSD: Also by NLnet Labs, NSD is built purely to serve zone files as fast as possible without the bloat of recursion.

  • Choose PowerDNS Authoritative: If you store zone data in SQL databases (MySQL, PostgreSQL) or want to manage zones dynamically via a REST API.

  • Choose Knot DNS: If you require maximum performance for huge zone counts or high query volumes.

3. If you operate in Containers or Kubernetes

  • Choose CoreDNS: CoreDNS replaced SkyDNS as the default internal DNS server for Kubernetes. It uses plugins to seamlessly integrate with cloud providers, ETCD, and Kubernetes APIs.

Summary Recommendation

  • For simple, secure caching/resolving: Replace BIND with Unbound.

  • For static zone file hosting: Replace BIND with NSD.

  • For complex database-driven or ISP infrastructure: Replace BIND with PowerDNS.

Where would you like to go next?

You said

What do I do if I want both authoritative and recursive?

Gemini said

If you need both roles on the same infrastructure, you have two primary approaches: running a split-architecture setup with dedicated lightweight tools on separate IP addresses/ports, or using a single dual-role server like PowerDNS.

Option 1: The Modern Best Practice (NSD + Unbound)

Running separate dedicated daemons on the same machine is the industry standard for security and isolation. NSD serves your zone data, and Unbound handles external recursion for your clients.

To prevent port conflicts on 53, assign each daemon to a different local IP address or bind interface:

  • Authoritative (NSD): Binds to the external IP (or 127.0.0.1:5353) to answer requests for your domain.

  • Recursive (Unbound): Binds to internal/LAN interfaces (127.0.0.1:53, local subnet) to handle outgoing queries, forwarding local domain requests to NSD.

 Client Query
      │
      ▼
┌──────────────┐   Local Domain   ┌──────────────┐
│   Unbound    │ ────────────────►│     NSD      │
│ (Recursive)  │   (port 5353)    │(Authoritative│
└──────────────┘                  └──────────────┘
      │
      │ External Domain
      ▼
   Internet

Why split them?

  • Security: Prevents cache poisoning, reflection attacks, and accidental open recursion.

  • Privilege Separation: NSD runs completely chrooted with no outward network connections required.

  • Performance: Neither daemon competes for memory or lock cycles between cache storage and zone updates.

Option 2: The Unified Suite (PowerDNS)

If you prefer managing software from a single project ecosystem, PowerDNS provides two purpose-built engines designed to run side-by-side:

  • PowerDNS Authoritative Server: Handles domain hosting with options for flat zone files, SQL backends (MySQL/PostgreSQL), or REST APIs.

  • PowerDNS Recursor: Handles caching and client resolution, with powerful Lua scripting capabilities.

Like the NSD/Unbound setup, both binaries run as separate services bound to distinct IPs or ports, but share similar configuration styles, logging patterns, and management tools.

Option 3: Dual-Role Monolith (Knot DNS / BIND)

If you strictly want one single process answering both types of queries from a single configuration file without running two services:

  • Knot Resolver: Can handle recursion while serving authoritative local zones using the modules = { 'hints' } or zone loading features.

  • BIND 9: Remains the primary single-process server natively supporting simultaneous authoritative and recursive operations.

Important: If using a single process for both roles, restrict recursive access strictly to trusted local IP ranges using ACLs (e.g., allow-recursion { 192.168.1.0/24; localhost; };) to prevent turning your server into an open resolver.

How would you like to proceed?

You said

How do I migrate my zone files from BIND to NSD step-by-step?

Gemini said

Migrating from BIND to NSD is relatively straightforward because NSD uses standard RFC-compliant zone files. Since BIND also uses this format, you can often reuse your existing zone files with minimal changes.

Here is the step-by-step process to migrate on a Unix-like system.

Step 1: Install NSD

Install the NSD package using your system's package manager:

  • FreeBSD: pkg install nsd

  • Debian/Ubuntu: apt install nsd

  • RHEL/Rocky Linux: dnf install nsd

Step 2: Export Clean Zone Files from BIND

If BIND uses dynamic DNS (nsupdate) or DNSSEC inline signing, the files on disk might contain binary state data or missing records. Export clean master zone files directly from BIND first:

Bash
# Export a clean ASCII zone file from BIND
named-compilezone -o /tmp/example.com.zone example.com /var/named/dynamic/example.com.db

If your BIND zone files are standard static text files without dynamic updates, you can copy them directly. Place your zone files in the NSD zone directory (typically /etc/nsd/ or /usr/local/etc/nsd/).

Step 3: Remove BIND-Specific Directives

NSD supports standard zone file directives like $ORIGIN and $TTL. However, it does not support BIND-specific syntax such as:

  • $INCLUDE (if paths are relative or nested outside the NSD working directory)

  • $GENERATE (macro expansion)

If your zone files use $GENERATE, expand them into plain text records before moving them:

Bash
# named-compilezone flattens $INCLUDE and $GENERATE directives automatically
named-compilezone -O raw -o /etc/nsd/zones/example.com.zone example.com /path/to/bind/zonefile

Ensure file permissions allow the nsd user to read the zone files:

Bash
chown -R nsd:nsd /etc/nsd/zones/
chmod 640 /etc/nsd/zones/*

Step 4: Configure nsd.conf

Edit your NSD configuration file (usually /etc/nsd/nsd.conf or /usr/local/etc/nsd/nsd.conf).

Below is a complete, minimal configuration for primary (master) and secondary (slave) zones:

Code snippet
server:
    ip-address: 0.0.0.0
    ip-address: ::1
    verbosity: 1
    username: nsd
    zonesdir: "/etc/nsd/zones"
    logfile: "/var/log/nsd.log"
    pidfile: "/var/run/nsd/nsd.pid"

# Define reuseable transfer ACL patterns
pattern:
    name: "to-secondaries"
    notify: 192.0.2.10 NOKEY
    provide-xfr: 192.0.2.10 NOKEY

# Primary Zone Example
zone:
    name: "example.com"
    zonefile: "example.com.zone"
    include-pattern: "to-secondaries"

# Secondary Zone Example (if NSD is acting as a secondary)
zone:
    name: "example.net"
    zonefile: "example.net.zone"
    allow-notify: 192.0.2.1 NOKEY
    request-xfr: 192.0.2.1 NOKEY

Step 5: Check Configuration and Synthesize Zone Data

NSD provides built-in utilities to verify syntax and compile zones into its internal database format (nsd.db).

  1. Verify configuration syntax:

    Bash
    nsd-checkconf /etc/nsd/nsd.conf
    
  2. Verify zone file syntax:

    Bash
    nsd-checkzone example.com /etc/nsd/zones/example.com.zone
    

Step 6: Swap BIND for NSD

  1. Stop BIND:

    Bash
    systemctl stop named   # or: service named stop / /etc/rc.d/named stop
    systemctl disable named
    
  2. Start NSD:

    Bash
    systemctl start nsd    # or: service nsd start / /etc/rc.d/nsd enable && service nsd start
    systemctl enable nsd
    

Step 7: Verify Operation

Test the new daemon locally using dig to ensure it answers authoritatively (look for the aa flag in the header):

Bash
dig @127.0.0.1 example.com SOA +multiline

Check the log file (/var/log/nsd.log or syslog) to ensure all zones loaded cleanly without errors.

Where would you like to go from here?

profile picture


Gemini is AI and can make mistakes.