DNSSEC (DNS Security Extensions) adds cryptographic signatures to DNS records, protecting against cache poisoning and DNS spoofing attacks where an attacker forges DNS responses to redirect users to malicious sites. On RHEL 9, BIND9 is the standard DNS server and includes full DNSSEC support out of the box. This tutorial walks through enabling DNSSEC validation, generating zone signing keys, signing a zone, and verifying the configuration. Implementing DNSSEC is a critical step in hardening your DNS infrastructure for production environments.

Prerequisites

  • RHEL 9 server with root or sudo access
  • A working BIND9 installation or ability to install it
  • A DNS zone you control (e.g., example.com)
  • Basic familiarity with DNS zone files

Step 1 — Install BIND and Utilities

Install the BIND DNS server along with its companion utilities package, which provides tools like dig and delv used for testing later.

dnf install -y bind bind-utils

Enable and start the named service so it runs at boot:

systemctl enable --now named

Step 2 — Enable DNSSEC Validation in named.conf

Open /etc/named.conf and locate the options block. Add or update the DNSSEC-related directives to enable validation. The dnssec-validation yes directive instructs BIND to validate DNSSEC signatures on all incoming DNS responses, while dnssec-enable yes ensures the server can serve signed zone data.

options {
    listen-on port 53 { 127.0.0.1; };
    directory       "/var/named";
    dnssec-enable   yes;
    dnssec-validation yes;
    managed-keys-directory "/var/named/dynamic";
};

Reload named after saving the file:

named-checkconf
systemctl reload named

Step 3 — Generate Zone Signing Keys

DNSSEC uses two key types: a Zone Signing Key (ZSK) for signing the zone records, and a Key Signing Key (KSK) for signing the ZSK. Generate both inside the zone key directory. Replace example.com with your actual zone name.

cd /var/named/keys
# Generate the Zone Signing Key (ZSK) — 1024-bit RSASHA256
dnssec-keygen -a RSASHA256 -b 1024 -n ZONE example.com

# Generate the Key Signing Key (KSK) — 2048-bit with -f KSK flag
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK example.com

This produces pairs of .key and .private files. The .key files contain the public key records that go into the zone file. Include both public keys in your zone file by adding $INCLUDE directives:

$INCLUDE /var/named/keys/Kexample.com.+008+12345.key
$INCLUDE /var/named/keys/Kexample.com.+008+67890.key

Step 4 — Sign the DNS Zone

Use dnssec-signzone to sign the zone file, producing a signed version with .signed appended to the filename. The -o flag specifies the zone origin and -k specifies the KSK file.

cd /var/named
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) 
    -N INCREMENT -o example.com -t example.com.zone

Update named.conf to point to the signed zone file:

zone "example.com" IN {
    type master;
    file "example.com.zone.signed";
    allow-query { any; };
};

Reload named to load the signed zone:

named-checkconf && systemctl reload named

Step 5 — Configure Trust Anchors and Submit DS Records

For DNSSEC to be verifiable by resolvers on the internet, you must submit your zone’s DS (Delegation Signer) record to your parent zone (your domain registrar). The DS record is derived from the KSK and links your zone into the chain of trust. Generate the DS record from the KSK public key file:

dnssec-dsfromkey /var/named/keys/Kexample.com.+008+67890.key

Copy the output DS record and submit it to your DNS registrar through their control panel. This creates the trust chain from the root zone down to your zone. For internal/private zones, you can configure a local trust anchor in named.conf using a trusted-keys or managed-keys block.

Step 6 — Test DNSSEC Validation

Use dig with the +dnssec flag to query your zone and confirm DNSSEC records are present. The AD (Authenticated Data) flag in the response header confirms the response has been validated.

# Query for DNSSEC records on your domain
dig +dnssec example.com A

# Verify DS record propagation
dig +dnssec example.com DS

# Use delv for detailed DNSSEC validation output
delv @localhost example.com A +rtrace

A fully validated response will show ; fully validated in the delv output. If you see ; unsupported algorithm or missing signatures, double-check that your zone was re-signed and named reloaded. You can also test external DNSSEC validation using the Verisign DNSSEC Debugger at dnssec-debugger.verisignlabs.com.

Conclusion

You have successfully configured DNSSEC on RHEL 9 with BIND9, generating signing keys, signing a zone, and verifying validation with dig and delv. Your DNS infrastructure is now protected against cache poisoning and man-in-the-middle DNS attacks through cryptographic record verification. Remember to re-sign your zone before the signature expiry period (default 30 days) using a cron job or systemd timer invoking dnssec-signzone.

Next steps: How to Configure BIND9 Views for Split-Horizon DNS on RHEL 9, How to Set Up a Recursive DNS Resolver with Unbound on RHEL 9, and How to Monitor DNS Query Logs and Detect Anomalies on RHEL 9.