DNSSEC Configuration
NSD provides comprehensive support for DNSSEC (DNS Security Extensions), including NSEC and NSEC3 authenticated denial of existence. This guide covers the technical implementation details and configuration.Overview
DNSSEC adds cryptographic signatures to DNS data, enabling resolvers to verify the authenticity and integrity of DNS responses. NSD handles DNSSEC as an authoritative nameserver, serving signed zones with RRSIG, DNSKEY, DS, and NSEC/NSEC3 records.NSD does not sign zones itself. You must use external signing tools like
ldns-signzone or BIND’s dnssec-signzone to create signed zone files. NSD serves the pre-signed data.NSEC vs NSEC3
DNSSEC provides authenticated denial of existence through two mechanisms:NSEC (Next Secure)
NSEC records form a chain linking all names in a zone, proving that a queried name does not exist. Advantages:- Simpler implementation
- Lower computational overhead
- No hashing required
- Zone enumeration possible (zone walking)
- All zone names are visible
NSEC3 (Next Secure 3)
NSEC3 uses cryptographic hashing (SHA-1) to obscure zone contents while still providing authenticated denial of existence. Advantages:- Prevents zone enumeration
- Opt-out support for unsigned delegations
- Zone contents remain private
- Higher computational cost
- More complex implementation
- Hash collisions possible (though rare)
NSEC3 Implementation in NSD
Hash Calculation
NSD implements NSEC3 hashing using the SHA-1 algorithm with salt and iterations. From the source (nsec3.c:116):
NSEC3 Parameters
NSEC3 parameters are defined in the NSEC3PARAM record at the zone apex:- Hash Algorithm: Currently only SHA-1 (algorithm 1) is supported
- Flags: Typically 0 (opt-out flag in NSEC3 records, not NSEC3PARAM)
- Iterations: Number of additional hash iterations (0-65535)
- Salt: Hex-encoded salt value (up to 255 octets)
Precompilation and Trees
NSD precompiles NSEC3 data structures for performance. It maintains four red-black trees:- nsec3tree: NSEC3 records indexed by base32-encoded hash
- hashtree: Domain hashes for regular names
- wchashtree: Wildcard hashes (*.domain)
- dshashtree: Delegation signer hashes
void nsec3_zone_trees_create(struct region* region, zone_type* zone)
{
if(!zone->nsec3tree)
zone->nsec3tree = rbtree_create(region, cmp_nsec3_tree);
if(!zone->hashtree)
zone->hashtree = rbtree_create(region, cmp_hash_tree);
if(!zone->wchashtree)
zone->wchashtree = rbtree_create(region, cmp_wchash_tree);
if(!zone->dshashtree)
zone->dshashtree = rbtree_create(region, cmp_dshash_tree);
}
void nsec3_precompile_domain(struct namedb* db, struct domain* domain,
struct zone* zone, region_type* tmpregion)
{
// Hash the domain and wildcard
nsec3_lookup_hash_and_wc(db->region, zone,
domain_dname(domain), domain, tmpregion);
// Add to hash trees
zone_add_domain_in_hash_tree(db->region, &zone->hashtree,
cmp_hash_tree, domain, &domain->nsec3->hash_wc->hash.node);
// Find covering NSEC3 record
nsec3_find_cover(zone, domain->nsec3->hash_wc->hash.hash,
sizeof(domain->nsec3->hash_wc->hash.hash), &result);
domain->nsec3->nsec3_cover = result;
}
Configuration
Basic DNSSEC Zone
For a zone signed with NSEC:NSEC3 Zone Configuration
- SHA-1 Default
- With Salt
- Opt-Out
NSEC3 Chain Validation
NSD validates NSEC3 chains on startup to ensure consistency:Signing Your Zone
Using ldns-signzone
# Generate Zone Signing Key (ZSK)
ldns-keygen -a ECDSAP256SHA256 -b 256 example.com
# Generate Key Signing Key (KSK)
ldns-keygen -a ECDSAP256SHA256 -b 256 -k example.com
# Sign zone with NSEC3
ldns-signzone -n -s $(openssl rand -hex 16) \
-a ECDSAP256SHA256 \
-e $(date -d "1 year" +%Y%m%d%H%M%S) \
example.com.zone \
Kexample.com.+013+12345
# Parameters:
# -n: Use NSEC3
# -s <salt>: Hex salt for NSEC3
# -a: Algorithm
# -e: Expiration date
ldns-signzone -n -p \
-s $(openssl rand -hex 16) \
-a ECDSAP256SHA256 \
example.com.zone \
Kexample.com.+013+12345
# -p: Enable opt-out for unsigned delegations
Performance Considerations
Memory Usage
NSEC3 precompilation requires additional memory:- Per domain: ~100-200 bytes for hash storage and tree nodes
- Large zones: A 1M domain zone uses ~100-200MB additional memory for NSEC3
CPU Impact
NSEC3 hashing occurs at:- Zone load time: All domains are hashed and precompiled
- Query time: Only for NXDOMAIN responses when precompilation failed
Hash Collision Handling
Hash Collision Handling
NSD detects hash collisions at query time:Hash collisions result in SERVFAIL responses with EDE (Extended DNS Errors) code 0.
Monitoring and Debugging
Check NSEC3 Status
Verify NSEC3 Chain
Enable Verbose Logging
- NSEC3 chain validation failures
- Hash collisions
- Zone reload status
Algorithm Support
Supported Signing Algorithms
NSD supports all standard DNSSEC algorithms when serving signed zones:- RSA: RSASHA1 (5), RSASHA1-NSEC3-SHA1 (7), RSASHA256 (8), RSASHA512 (10)
- ECDSA: ECDSAP256SHA256 (13), ECDSAP384SHA384 (14)
- EdDSA: ED25519 (15), ED448 (16)
Recommended Algorithms
Modern deployments should use ECDSA or EdDSA algorithms for smaller key sizes and better performance:
- ECDSAP256SHA256 (13): Best balance of security and performance
- ED25519 (15): Fastest signing/verification, smallest signatures
Troubleshooting
NSEC3 Chain Errors
Symptom: Zone fails to load with “NSEC3PARAM entry has no hash(apex)” Solution: Ensure the zone file contains a properly signed NSEC3 record covering the apex domain name hash.Hash Collision Servfail
Symptom: Queries return SERVFAIL with “NSEC3 hash collision” EDE Solution: This is extremely rare. Resign the zone with a different salt value to generate different hashes.Broken Chain After Update
Symptom: Zone status shows “catalog: consumer (serial: X, # members: 0)” Solution: The NSEC3 chain was broken during zone update. Regenerate and resign the zone completely.Security Considerations
Related Topics
- TSIG Configuration - Secure zone transfers
- Access Control - Zone transfer security
- Rate Limiting - Prevent DNSSEC amplification attacks