Server

Running BIND 9 as an Authoritative Server

By Prabath Thalangama· October 24, 2026· 4 min read
#dns#bind#dnssec

Introduction

An authoritative DNS server answers for zones it hosts (example.com), unlike a recursive resolver which looks things up for clients. Never run one server as both open to the internet. This covers BIND 9 as authoritative, master + slave.

named.conf

options {
    directory "/var/named";
    listen-on port 53 { any; };
    listen-on-v6 port 53 { any; };
    recursion no;                     # AUTHORITATIVE: no recursion
    allow-query { any; };
    version none;
    dnssec-validation no;             # not a resolver
};

key "transfer-key" {
    algorithm hmac-sha256;
    secret "BASE64SECRET==";          # tsig-keygen -a hmac-sha256 transfer-key
};

acl "slaves" { 203.0.113.20; 203.0.113.21; };

zone "example.com" IN {
    type primary;                     # was "master"
    file "zones/example.com.zone";
    allow-transfer { key transfer-key; slaves; };
    also-notify { 203.0.113.20; 203.0.113.21; };
    notify yes;
};

Slave:

key "transfer-key" { algorithm hmac-sha256; secret "SAME-SECRET=="; };

zone "example.com" IN {
    type secondary;                   # was "slave"
    file "slaves/example.com.zone";
    primaries { 203.0.113.10 key transfer-key; };
};

TSIG (the shared key) authenticates zone transfers so random parties can't AXFR your whole zone. Generate with tsig-keygen; distribute the secret securely.

The zone file

$TTL 3600
$ORIGIN example.com.
@   IN  SOA ns1.example.com. hostmaster.example.com. (
        2026082701   ; serial  (YYYYMMDDNN — bump on EVERY change)
        7200         ; refresh
        3600         ; retry
        1209600      ; expire
        3600 )       ; minimum / negative-cache TTL

    IN  NS   ns1.example.com.
    IN  NS   ns2.example.com.
    IN  MX   10 mail.example.com.
    IN  A    203.0.113.5
    IN  TXT  "v=spf1 mx -all"

ns1 IN  A    203.0.113.10
ns2 IN  A    203.0.113.20
www IN  CNAME @
mail IN A    203.0.113.6

Serial discipline: every zone edit must increment the serial, or slaves won't pull the change (they compare serials on refresh). YYYYMMDDNN is the convention; if you edit twice in a day, ...02, ...03.

DNSSEC with inline-signing

Let BIND manage keys and re-signing automatically:

zone "example.com" IN {
    type primary;
    file "zones/example.com.zone";
    inline-signing yes;
    dnssec-policy default;            # modern: policy-driven KSK/ZSK, rollovers
    allow-transfer { key transfer-key; };
};

BIND generates keys under a key directory, signs into a separate .signed/journal file (your source zone stays plain), and handles ZSK rollover. You publish the DS record at the parent (your registrar) from:

dnssec-dsfromkey -2 Kexample.com.+013+12345.key
rndc dnssec -status example.com

ACLs and hardening

allow-query { any; };
allow-transfer { key transfer-key; };     # never { any; }
allow-update { none; };                    # unless you use dynamic DNS + TSIG

Run BIND chrooted / as named, keep it patched (BIND has a steady CVE stream), rate-limit responses (rate-limit { responses-per-second 15; };) to blunt amplification abuse.

Verification and troubleshooting

named-checkconf
named-checkzone example.com /var/named/zones/example.com.zone
rndc reload example.com
rndc zonestatus example.com

dig @ns1.example.com example.com SOA +norec
dig @ns1.example.com example.com AXFR -y hmac-sha256:transfer-key:SECRET==
dig @ns1.example.com example.com DNSKEY +dnssec
  • Slave not updating — serial not incremented, TSIG key mismatch (rndc log: "transfer of ... failed: TSIG verify failure"), allow-transfer doesn't include the slave, or NOTIFY not reaching it. dig AXFR from the slave's IP to test.
  • named-checkzone fails — missing trailing dot (making www.example.com become www.example.com.example.com), missing $ORIGIN, or a CNAME coexisting with other records at the same name (not allowed).
  • NXDOMAIN for records that exist — wrong zone file loaded, rndc reload not run, or the record is in the unsigned source but you're serving the signed copy and forgot to re-sign (rndc sign example.com / it's automatic with dnssec-policy).
  • DNSSEC validation failing at resolvers (SERVFAIL) — DS record at the parent doesn't match your current KSK (rollover mismatch), expired signatures (BIND stopped re-signing — check rndc dnssec -status), or clock skew.
  • AXFR of the whole zone by anyone — allow-transfer { any; }. Lock it to TSIG + slave IPs. Test: dig AXFR example.com @yourserver from an unrelated host should be refused.
  • Recursion open to the internet — recursion yes on an authoritative box facing the world = an open resolver used for amplification attacks. recursion no on authoritative servers, always.
PrabathStuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.