Enabling DNSSEC Validation on BIND Resolvers

Enabling DNSSEC Validation on BIND Resolvers

DNSSEC (Domain Name System Security Extensions) adds cryptographic authentication to DNS responses, protecting against cache poisoning and man-in-the-middle attacks. When your resolver validates DNSSEC, it verifies that DNS responses haven't been tampered with between the authoritative server and your clients.

How DNSSEC Validation Works

DNSSEC creates a chain of trust from the DNS root zone down to individual domains:

  1. Root Zone: Signed by ICANN, trust anchors are built into DNS software
  2. TLD: .com, .org, etc. are signed by their registries
  3. Domain: Individual domains sign their zones
  4. Validation: Resolvers verify signatures up the chain

When a resolver receives a DNSSEC-signed response, it:

  1. Retrieves the DNSKEY records for the zone
  2. Verifies the RRSIG (signature) on the response
  3. Validates the DS record in the parent zone
  4. Continues up to the root trust anchor

If any signature fails validation, the response is rejected as SERVFAIL.

Enabling DNSSEC Validation in BIND

Automatic Configuration

Modern BIND includes built-in root trust anchors. Enable validation with:

options {
    directory "/var/named";
    
    recursion yes;
    allow-recursion { trusted; };
    
    dnssec-validation auto;
};

The auto setting tells BIND to use the built-in managed trust anchors for the root zone. BIND automatically updates these anchors through RFC 5011 automated trust anchor maintenance.

Manual Trust Anchor Configuration

For explicit control, specify trust anchors manually:

trust-anchors {
    . initial-key 257 3 8 "AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3
        +/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kv
        ArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF
        0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+e
        oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfd
        RUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwN
        R1AkUTV74bU=";
};

options {
    dnssec-validation yes;
};

Verify DNSSEC Is Working

Test DNSSEC validation:

# Query a signed domain
dig @localhost dnssec-tools.org +dnssec

# Look for 'ad' (Authenticated Data) flag
dig @localhost example.com +dnssec | grep flags
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

The ad flag indicates the response was DNSSEC validated.

Test with Known Good/Bad Domains

# Should succeed (valid DNSSEC)
dig @localhost www.dnssec-tools.org

# Should fail with SERVFAIL (deliberately broken DNSSEC)
dig @localhost www.dnssec-failed.org

Handling DNSSEC Failures

Why Queries Fail

DNSSEC validation fails when:

  • Zone has expired signatures (RRSIG past validity)
  • Zone was re-signed but parent DS record wasn't updated
  • Zone keys were changed without proper rollover
  • Authoritative server returned truncated response (UDP size issues)
  • Network issues preventing retrieval of DNSKEY records

Diagnosing Failures

Use delv (DNSSEC lookup and validation utility):

# Check validation chain
delv @localhost example.com

# Verbose output
delv @localhost example.com +vtrace

# Show trust chain
delv @localhost example.com +rtrace

Example failure output:

;; resolution failed: RRSIG has expired

Check Signature Validity

# View RRSIG records and expiration
dig @localhost example.com RRSIG +short

# Check DNSKEY records
dig @localhost example.com DNSKEY +short

# Check DS record at parent
dig @localhost example.com DS +short

Negative Trust Anchors (NTAs)

When a domain's DNSSEC is broken but you need to resolve it, use Negative Trust Anchors to temporarily disable validation:

# Add NTA (valid for 1 hour by default)
rndc nta example.com

# Add NTA with specific lifetime
rndc nta -lifetime 3600 example.com

# List active NTAs
rndc nta -dump

# Remove NTA
rndc nta -remove example.com

Persistent NTAs

For permanent exceptions, configure in named.conf:

options {
    dnssec-validation auto;
    
    // Permanent negative trust anchors
    // Use sparingly - security trade-off!
};

// Using managed-keys for NTA (BIND 9.11+)
nta broken-domain.example.com;

Warning: NTAs disable DNSSEC protection for that domain. Use only when necessary and investigate the root cause.

EDNS Buffer Size

DNSSEC responses are larger than regular DNS. Configure appropriate buffer sizes:

options {
    edns-udp-size 1232;
    max-udp-size 1232;
};

The 1232 value avoids fragmentation on most networks (1280 IPv6 minimum MTU - 48 header bytes).

Logging DNSSEC Events

logging {
    channel dnssec_log {
        file "/var/log/named/dnssec.log" versions 5 size 10m;
        severity info;
        print-time yes;
        print-category yes;
        print-severity yes;
    };
    
    category dnssec { dnssec_log; };
};

Log messages show:

  • Successful validations
  • Validation failures with reason
  • Trust anchor updates (RFC 5011)
  • Key rollover events

Trust Anchor Management

Automatic Updates (RFC 5011)

With dnssec-validation auto, BIND manages root trust anchors automatically:

# View managed keys
rndc managed-keys status

# Force refresh
rndc managed-keys refresh

# Check managed keys database
cat /var/named/managed-keys.bind

Key Rollover Events

When the root zone key changes (rare), BIND:

  1. Detects new key in root DNSKEY response
  2. Waits hold-down period (30 days default)
  3. Adds new key to trust store
  4. Removes old key after it's no longer advertised

Monitor for key rollover:

grep "managed-keys" /var/log/named/named.log

Complete Resolver Configuration

// /etc/named.conf

acl "trusted" {
    localhost;
    localnets;
    192.168.0.0/16;
    10.0.0.0/8;
};

options {
    directory "/var/named";
    pid-file "/run/named/named.pid";
    
    // Network settings
    listen-on port 53 { any; };
    listen-on-v6 port 53 { any; };
    
    // Recursion settings
    recursion yes;
    allow-recursion { trusted; };
    allow-query-cache { trusted; };
    
    // DNSSEC validation
    dnssec-validation auto;
    
    // EDNS settings for DNSSEC
    edns-udp-size 1232;
    max-udp-size 1232;
    
    // Security
    version "not disclosed";
    minimal-responses yes;
    
    // Performance
    prefetch 10 60;
};

logging {
    channel default_log {
        file "/var/log/named/named.log" versions 5 size 10m;
        severity info;
        print-time yes;
        print-severity yes;
    };
    
    channel dnssec_log {
        file "/var/log/named/dnssec.log" versions 5 size 10m;
        severity debug;
        print-time yes;
        print-category yes;
    };
    
    category default { default_log; };
    category dnssec { dnssec_log; };
};

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

Testing DNSSEC Validation

Command Line Tests

# Check if validation is enabled
dig @localhost . SOA +dnssec | grep -E "(flags|ad)"

# Test known-good signed domain
dig @localhost cloudflare.com +dnssec +short

# Test validation failure (should return SERVFAIL)
dig @localhost dnssec-failed.org

# Check AD flag on signed domain
dig @localhost sigok.verteiltesysteme.net | grep "ad"

# Check that AD flag is absent for unsigned domain
dig @localhost unsigned-domain.com | grep -v "ad"

Using drill (from ldns)

# Trace DNSSEC chain
drill -DT cloudflare.com

# Show signature details
drill -TD cloudflare.com

Monitoring DNSSEC Health

Statistics

Enable and query BIND statistics:

# View DNSSEC statistics
rndc stats
grep -A20 "DNSSEC" /var/named/data/named_stats.txt

Metrics to monitor:

  • ValOk: Successful validations
  • ValNegOk: Validated negative responses
  • ValFail: Validation failures
  • ValIndeterminate: Non-DNSSEC responses

Alerting on Failures

Script to check validation:

#!/bin/bash
# /usr/local/bin/check-dnssec.sh

RESULT=$(dig @localhost cloudflare.com +dnssec +short 2>&1)
AD_FLAG=$(dig @localhost cloudflare.com | grep -c " ad ")

if [ $AD_FLAG -eq 0 ]; then
    echo "CRITICAL: DNSSEC validation not working"
    exit 2
fi

echo "OK: DNSSEC validation operational"
exit 0

Troubleshooting

"SERVFAIL" for DNSSEC Domains

Check resolver can reach authoritative servers:

# Try direct query to authoritative
dig @ns1.example.com example.com DNSKEY

# Check if DNSKEY is retrievable
dig @localhost example.com DNSKEY +cd

The +cd flag (Checking Disabled) bypasses validation - if this works but normal query fails, the issue is DNSSEC.

Clock Skew

DNSSEC signatures have validity periods. If system clock is wrong:

# Check time
date

# Sync time
ntp -q pool.ntp.org
# or
timedatectl set-ntp true

Trust Anchor Problems

# Check managed keys
rndc managed-keys status

# Verify root key file exists
ls -la /var/named/managed-keys.bind

# Check key validity
cat /var/named/managed-keys.bind | grep -A2 "initial-key"

Conclusion

DNSSEC validation on your resolver protects all clients from DNS spoofing attacks. With modern BIND, enabling validation is straightforward with dnssec-validation auto. Monitor validation statistics, log DNSSEC events, and have a process for handling broken domains via Negative Trust Anchors when necessary.

The next post will cover signing your own zones with DNSSEC on authoritative servers, completing the DNSSEC trust chain for your domains.

Read more

HAProxy Monitoring with Prometheus: Complete Observability Guide

HAProxy Monitoring with Prometheus: Complete Observability Guide

Monitoring HAProxy is essential for maintaining reliable load balancing infrastructure. Prometheus provides powerful metrics collection, alerting capabilities, and seamless Grafana integration for visualizing HAProxy performance and health. Why Prometheus for HAProxy? Prometheus offers: * Pull-based metrics - Prometheus scrapes HAProxy metrics endpoints * Time-series database - Store historical data for trend analysis

By Patrick de Ruiter