Skip to content

Last updated: 2026-06-25

BIND DNSSEC & DNS over TLS Configuration Guide

This guide provides recommended DNSSEC and DNS over TLS (DoT) settings for BIND (Berkeley Internet Name Domain). DNSSEC adds cryptographic signatures to DNS records, allowing resolvers to verify that responses have not been tampered with. DNS over TLS encrypts DNS queries in transit. This guide covers authoritative zone signing, resolver-side validation, and DoT configuration.

Prerequisites

  • BIND 9.20 or later recommended. 9.20 is the current stable / Extended Support Version (ESV); 9.16 reached end of life in April 2024 and 9.18 reached end of life in June 2026.
  • dnssec-policy inline signing was introduced in 9.16; DNS over TLS support was introduced in 9.18. Both are present in 9.20.
  • bind-dnssec-utils or equivalent package for dnssec-keygen, dnssec-dsfromkey
  • A valid TLS certificate and private key (for DoT server mode)
  • Access to the parent zone registrar to publish DS records

Important: dnssec-enable was removed in BIND 9.18+. Do not use it on 9.18 or later; it will cause a startup failure.

Path note: This guide uses RHEL paths (/etc/named.conf, /var/named/). On Debian/Ubuntu, use /etc/bind/named.conf, /var/cache/bind/ for zone files, and /etc/bind/bind.keys instead of /etc/named.root.key. On SLES, config is at /etc/named.conf but zone files are under /var/lib/named/.

DNSSEC Overview

DNSSEC uses a chain of trust from the DNS root to your zone:

  1. ZSK (Zone Signing Key) - Signs individual DNS records in the zone
  2. KSK (Key Signing Key) - Signs the DNSKEY RRset and is referenced by the parent zone's DS record
  3. DS Record - Published in the parent zone, linking the parent's chain of trust to your KSK
  4. RRSIG - Cryptographic signatures over each RRset
  5. NSEC/NSEC3 - Authenticated denial of existence

Authoritative Server Configuration

BIND 9.16+ supports dnssec-policy for fully automated key generation, signing, and rollover:

dnssec-policy "standard" {
    keys {
        ksk key-directory lifetime unlimited algorithm ecdsap256sha256;
        zsk key-directory lifetime P90D algorithm ecdsap256sha256;
    };

    dnskey-ttl 3600;
    publish-safety PT1H;
    retire-safety PT1H;
    purge-keys P90D;

    signatures-refresh P5D;
    signatures-validity P14D;
    signatures-validity-dnskey P14D;

    max-zone-ttl 86400;
    zone-propagation-delay PT5M;
    parent-ds-ttl 3600;
    parent-propagation-delay PT1H;

    nsec3param iterations 0 optout no salt-length 0;
};

Apply the policy to a zone:

zone "example.com" {
    type primary;
    file "/var/named/example.com.zone";
    dnssec-policy "standard";
    inline-signing yes;
    key-directory "/var/named/keys";
};

Algorithm Selection

Use ECDSAP256SHA256 (algorithm 13) for new deployments. It provides strong security with small key and signature sizes:

Algorithm ID Recommendation
RSASHA256 8 Acceptable (use 2048-bit minimum)
RSASHA512 10 Acceptable
ECDSAP256SHA256 13 Recommended
ECDSAP384SHA384 14 Acceptable
ED25519 15 Good (limited resolver support)

Automatic Key Rollover

The dnssec-policy handles key rollover automatically based on the configured lifetimes. The ZSK lifetime of P90D (90 days) triggers automatic ZSK rollovers. The KSK lifetime of unlimited means KSK rollovers must be initiated manually.

Monitor key states:

rndc dnssec -status example.com     # for dnssec-policy (KASP) zones; use `rndc signing -list` only for legacy auto-dnssec zones

Manual Key Generation

If not using dnssec-policy, generate keys manually:

# Generate KSK
dnssec-keygen -a ECDSAP256SHA256 -f KSK example.com

# Generate ZSK
dnssec-keygen -a ECDSAP256SHA256 example.com

Include the keys in your zone file:

$INCLUDE Kexample.com.+013+12345.key
$INCLUDE Kexample.com.+013+67890.key

Sign the zone:

dnssec-signzone -A -3 $(head -c 16 /dev/urandom | od -A n -t x1 | tr -d ' \n') \
  -N INCREMENT -o example.com example.com.zone

DS Record Publication

After signing your zone, extract the DS record and publish it at your registrar or parent zone:

dnssec-dsfromkey /var/named/keys/Kexample.com.+013+12345.key

This outputs DS records in multiple digest formats:

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

Publish the SHA-256 (digest type 2) DS record with your domain registrar.

Resolver Configuration (DNSSEC Validation)

Configure BIND as a validating resolver:

options {
    directory "/var/named";

    // Enable DNSSEC validation
    dnssec-validation auto;

    // Use the built-in root trust anchors
    // (managed-keys-directory for RFC 5011 auto-updates)
    managed-keys-directory "/var/named/dynamic";
    bindkeys-file "/etc/named.root.key";

    recursion yes;
    allow-recursion { localnets; localhost; };
};

The dnssec-validation auto; setting uses the built-in root zone trust anchor and automatically validates DNSSEC-signed zones.

Trust Anchors

BIND ships with the root zone trust anchor. For custom trust anchors:

trust-anchors {
    example.com. initial-key 257 3 13 "base64-encoded-key-data";
};

Complete Configuration

Authoritative Server

// /etc/named.conf

options {
    directory "/var/named";
    listen-on { any; };
    listen-on-v6 { any; };

    allow-transfer { none; };
    allow-query { any; };

    recursion no;

    // Key directory for DNSSEC keys
    key-directory "/var/named/keys";
};

// DNSSEC signing policy
dnssec-policy "standard" {
    keys {
        ksk key-directory lifetime unlimited algorithm ecdsap256sha256;
        zsk key-directory lifetime P90D algorithm ecdsap256sha256;
    };

    dnskey-ttl 3600;
    publish-safety PT1H;
    retire-safety PT1H;
    purge-keys P90D;

    signatures-refresh P5D;
    signatures-validity P14D;
    signatures-validity-dnskey P14D;

    max-zone-ttl 86400;
    zone-propagation-delay PT5M;
    parent-ds-ttl 3600;
    parent-propagation-delay PT1H;

    nsec3param iterations 0 optout no salt-length 0;
};

// Signed zone
zone "example.com" {
    type primary;
    file "/var/named/example.com.zone";
    dnssec-policy "standard";
    inline-signing yes;
    key-directory "/var/named/keys";
};

Validating Resolver

// /etc/named.conf (resolver)

options {
    directory "/var/named";
    listen-on { 127.0.0.1; 10.0.0.1; };

    recursion yes;
    allow-recursion { localnets; localhost; };

    dnssec-validation auto;
    managed-keys-directory "/var/named/dynamic";
    bindkeys-file "/etc/named.root.key";

    // Rate limiting
    rate-limit {
        responses-per-second 10;
    };

    // Minimal responses
    minimal-responses yes;
};

zone "." {
    type hint;
    file "named.ca";
};

DNS over TLS (DoT)

BIND 9.18 and later supports DNS over TLS for both serving encrypted queries and forwarding to upstream resolvers over TLS.

Version note: DoT support requires BIND 9.18+. The tls configuration block used below is not available in earlier versions. RHEL 9 ships BIND 9.16, which does not support DoT natively; SLES 15 SP6 ships BIND 9.18. On those systems, consider using a TLS-terminating proxy such as stunnel or dnsdist for encrypted DNS transport.

TLS Profile

Define a TLS profile with your certificate and key:

tls local-tls {
    cert-file "/etc/named/ssl/fullchain.pem";
    key-file "/etc/named/ssl/privkey.pem";
    protocols { TLSv1.2; TLSv1.3; };
    ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";
    prefer-server-ciphers yes;
};

Listening for DoT

Accept DNS over TLS queries on port 853:

options {
    listen-on port 853 tls local-tls { any; };
    listen-on-v6 port 853 tls local-tls { any; };
};

Forwarding over TLS

Configure a TLS profile for upstream resolvers and forward queries over TLS:

tls upstream-tls {
    ca-file "/etc/pki/tls/certs/ca-bundle.crt";   // Debian/Ubuntu: /etc/ssl/certs/ca-certificates.crt
    remote-hostname "dns.quad9.net";
};

options {
    forwarders port 853 tls upstream-tls {
        9.9.9.9;
        149.112.112.112;
    };
    forward only;
};

The remote-hostname option verifies the upstream server's TLS certificate hostname.

Complete DoT Server Configuration

// /etc/named.conf (DoT-enabled authoritative server)

tls local-tls {
    cert-file "/etc/named/ssl/fullchain.pem";
    key-file "/etc/named/ssl/privkey.pem";
    protocols { TLSv1.2; TLSv1.3; };
    ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";
    prefer-server-ciphers yes;
};

options {
    directory "/var/named";

    // Plain DNS
    listen-on { any; };
    listen-on-v6 { any; };

    // DNS over TLS
    listen-on port 853 tls local-tls { any; };
    listen-on-v6 port 853 tls local-tls { any; };

    allow-transfer { none; };
    allow-query { any; };
    recursion no;

    key-directory "/var/named/keys";
};

dnssec-policy "standard" {
    keys {
        ksk key-directory lifetime unlimited algorithm ecdsap256sha256;
        zsk key-directory lifetime P90D algorithm ecdsap256sha256;
    };
    dnskey-ttl 3600;
    signatures-refresh P5D;
    signatures-validity P14D;
    signatures-validity-dnskey P14D;
    max-zone-ttl 86400;
    nsec3param iterations 0 optout no salt-length 0;
};

zone "example.com" {
    type primary;
    file "/var/named/example.com.zone";
    dnssec-policy "standard";
    inline-signing yes;
    key-directory "/var/named/keys";
};

DoT Verification

Test DNS over TLS with kdig:

kdig @ns.example.com +tls example.com A

Or with OpenSSL:

echo | openssl s_client -connect ns.example.com:853 2>/dev/null | grep -E 'Protocol|Cipher'

Firewall

Open port 853 for DNS over TLS:

firewall-cmd --permanent --add-port=853/tcp
firewall-cmd --reload

Security Notes

The cipher suite and protocol configuration in this guide addresses the following known TLS vulnerabilities:

  • POODLE (CVE-2014-3566, 2014): SSL 3.0 is disabled. TLS_FALLBACK_SCSV was added in OpenSSL 1.0.1j / 1.0.2 (October 2014); SSL 3.0 disabled by default in OpenSSL 1.1.0 (August 2016).
  • BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
  • CRIME (CVE-2012-4929, 2012): TLS compression is off by default in OpenSSL 1.1.0+; do not enable it.
  • Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
  • FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers are excluded. Removed from OpenSSL 1.1.0 (August 2016).
  • LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
  • Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the cipher string.
  • ROBOT (2017): Static RSA key exchange is excluded; only ECDHE is recommended.
  • Downgrade attacks: TLS_FALLBACK_SCSV prevents protocol version rollback.

The following are not addressable through TLS configuration alone:

  • Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching OpenSSL, not by TLS configuration.
  • BREACH (CVE-2013-3587, 2013): Not applicable. BREACH targets HTTP-level response compression; DNS-over-TLS does not involve HTTP. DNS-over-HTTPS uses HTTP but typically without compressible secret data.
  • DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled on all services that use the same certificate and key pair.

Verification

Check that a zone is signed:

dig @localhost example.com DNSKEY +dnssec +multiline

Verify RRSIG records exist:

dig @localhost example.com A +dnssec

Look for the ad (Authenticated Data) flag in responses:

dig @resolver example.com A +dnssec

Use delv for detailed DNSSEC validation:

delv @localhost example.com A +rtrace

Verify the DS record matches:

dig example.com DS +short

Check DNSSEC chain of trust:

drill -S example.com

Check the DNSSEC signing status in BIND:

rndc dnssec -status example.com     # for dnssec-policy (KASP) zones; use `rndc signing -list` only for legacy auto-dnssec zones
rndc zonestatus example.com

Verify the full DNSSEC chain of trust externally with the Mr.DNS DNSSEC Validation Check.


Related Guides

View all DNS guides →

Configured TLS? Now Monitor It.

Generator Labs alerts you before certificates expire, get revoked, or fail chain validation, across HTTPS, SMTPS, IMAPS, LDAPS, and more.

Certificate Monitoring →