BIND9 DNSSEC Signing and Validation Setup - 夜莺博客

BIND9 DNSSEC Signing and Validation Setup

DNSSEC does not encrypt DNS; it makes answers verifiable. A validating resolver checks a cryptographic chain from the root zone down to your zone, so a spoofed answer fails the check instead of being returned to the client. Signing a zone is now much simpler than it used to be — BIND 9.16 and later manage key rollover automatically with dnssec-policy — but the operational parts still matter: the DS record must be published in the parent, and a signed zone that fails validation is worse than an unsigned one because it becomes unreachable to validating resolvers. This guide covers signing a zone, publishing the DS record, configuring validation, and verifying the whole chain.

What DNSSEC Actually Adds

  • RRSIG — a signature over each record set in the zone.
  • DNSKEY — the public keys: a Key Signing Key (KSK) that signs the DNSKEY set, and Zone Signing Keys (ZSKs) that sign the data.
  • DS — a hash of the KSK published in the parent zone, which is what creates the chain of trust.
  • NSEC / NSEC3 — authenticated denial of existence, so a negative answer can also be proven rather than merely asserted.

The chain of trust

The chain works upward: the root's KSK is a trust anchor in the resolver, the root signs the DS for the top-level domain, and so on down to your zone. Break any link and validation fails.

Step 1 - Sign the Zone with dnssec-policy

Modern BIND handles key generation and rollover through a policy. Start with the built-in default policy for a standard zone:

zone "example.com" {
    type primary;
    file "/var/lib/bind/db.example.com";
    dnssec-policy default;
    inline-signing yes;
    key-directory "/var/lib/bind/keys";
    allow-transfer { 10.10.40.12; };
    also-notify { 10.10.40.12; };
};

inline-signing yes lets BIND serve a signed version while keeping a copy of the unsigned zone file, which makes future edits easier. Reload and confirm the keys were created automatically:

sudo named-checkconf /etc/bind/named.conf.local
sudo named-checkzone example.com /var/lib/bind/db.example.com
sudo rndc reconfig
sudo ls -l /var/lib/bind/keys/
sudo rndc dnssec -status example.com

The key directory will contain .key and .private pairs for the KSK and at least one ZSK. rndc dnssec -status reports the current signing state, which key is active for each role, and when the next rollover is due — this is the command to check rather than inspecting files by hand.

Step 2 - Verify the Zone Is Signed Before Publishing DS

Verification before publishing the DS

Never publish a DS record until the signed zone is being served correctly. Query your own server directly:

dig @localhost example.com SOA +dnssec
dig @localhost example.com DNSKEY +dnssec +multi
dig @localhost example.com A +dnssec
dig @localhost example.com thisdoesnotexist.example.com A +dnssec

The DNSKEY answer must include the KSK and ZSK, and the A answer must carry an RRSIG with the ad flag absent (the server is authoritative here, not validating). The non-existent name query should return NSEC or NSEC3 records proving the name does not exist, with an RRSIG covering them.

Get the DS record to publish from the KSK:

dnssec-dsfromkey -2 /var/lib/bind/keys/Kexample.com.+013+12345.key

Step 3 - Publish the DS Record in the Parent

For a delegated domain, the DS goes into the registrar's interface or into the parent zone if you control it. If you host the parent zone yourself, insert the DS record directly and reload the parent:

example.com. IN DS 12345 13 2 A1B2C3... 

The key tag, algorithm, and digest type must match exactly what dnssec-dsfromkey produced. A single wrong digit creates a zone that validates nowhere. Confirm the parent is publishing it:

dig @a.gtld-servers.net example.com DS +dnssec
dig +trace example.com DNSKEY
dig +trace -x 203.0.113.10

Step 4 - Configure a Validating Resolver

A resolver validates with dnssec-validation auto, which uses the built-in trust anchors and maintains the root trust anchor automatically via RFC 5011:

options {
    directory "/var/cache/bind";
    recursion yes;
    allow-recursion { 10.10.0.0/16; };
    dnssec-validation auto;
    // For a manually managed trust anchor: dnssec-validation yes;
    // with an explicit 'trust-anchors' clause.
};

After reloading, confirm the resolver is validating rather than merely serving:

sudo rndc reload
dig @localhost internetsociety.org A +dnssec
dig @localhost dnssec-failed.org A +dnssec
sudo rndc validation status
sudo rndc validation checkds example.com

Proving validation is active

dnssec-failed.org is a deliberately broken test domain: a validating resolver must return SERVFAIL for it. If it returns an answer, validation is not actually active. A correct validating answer for a genuine domain carries the ad (authenticated data) flag.

Troubleshooting

  1. Zone served as unsigned. Check rndc dnssec -status for the policy state and confirm dnssec-policy is actually in the zone block, then reconfig and check the log for signing errors.
  2. Validation fails for your zone but works for others. Query the parent for the DS record and compare the key tag with your KSK. A DS published before the zone was serving signed data, or a key tag mismatch after a rollover, produces exactly this.
  3. SERVFAIL everywhere for your zone. Check the serial and the signature validity period. A zone whose signatures have expired — typically because the signer stopped running — fails validation completely.
  4. Negative answers fail but positive answers work. This is an NSEC/NSEC3 problem, often after a migration from NSEC to NSEC3. Verify that the mechanism in the signed zone matches what you expect with dig +dnssec nonexistent.example.com.

Operational Notes

  • Use dnssec-policy rather than manual key management; automatic rollover is where most manual deployments eventually break.
  • Publish the DS only after the signed zone is verifiably served, and remove it before decommissioning a signer.
  • Monitor signature expiry — an expired RRSIG takes the entire zone offline for validating resolvers.
  • Test with dnssec-failed.org to prove validation is on, and with a real signed domain to confirm the ad flag appears.
  • Keep the key directory backed up; losing the KSK private key during a rollover complicates recovery considerably.

Related reading: our BIND9 authoritative DNS zone configuration guide, the Unbound DNSSEC validation setup and troubleshooting article, and the dig and nslookup troubleshooting commands guide.

原文链接:https://bind9.readthedocs.io/en/latest/dnssec-guide.html