How to Configure DNSSEC on RHEL 7

DNS Security Extensions (DNSSEC) add a layer of cryptographic verification to the Domain Name System, protecting users from cache poisoning attacks, man-in-the-middle redirects, and forged DNS responses. By digitally signing DNS zone data, DNSSEC allows resolvers to confirm that the records they receive are authentic and unmodified. This tutorial walks through enabling DNSSEC validation in BIND 9 on Red Hat Enterprise Linux 7, generating Zone Signing Keys (ZSK) and Key Signing Keys (KSK), signing a zone, and verifying the configuration end-to-end. This is a hands-on guide aimed at system administrators managing authoritative or recursive DNS servers on RHEL 7.

Prerequisites

  • RHEL 7 server with root or sudo access
  • BIND 9 installed and a working DNS zone already configured
  • The zone file and named.conf accessible (typically under /etc/named/ or /var/named/)
  • Basic familiarity with DNS zone file syntax
  • Open UDP/TCP port 53 in firewalld

Step 1: Install BIND and Required Tools

If BIND is not yet installed, use yum to install it along with the utilities package which provides dnssec-keygen, dnssec-signzone, and named-checkconf:

sudo yum install -y bind bind-utils bind-libs

Confirm the installed version:

named -v
# BIND 9.9.4-RedHat-9.9.4-74.el7_6.1 (Extended Support Version)

Enable and start the named service:

sudo systemctl enable named
sudo systemctl start named
sudo systemctl status named

Step 2: Enable DNSSEC in named.conf

Open the main BIND configuration file and add or verify the DNSSEC directives inside the options block. The two critical settings are dnssec-enable (activates DNSSEC support in responses) and dnssec-validation (controls whether the resolver validates signatures):

sudo vi /etc/named.conf

Locate the options { ... }; block and ensure these lines are present:

options {
    listen-on port 53 { 127.0.0.1; };
    directory       "/var/named";
    dump-file       "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    memstatistics-file "/var/named/data/named_mem_stats.txt";

    dnssec-enable yes;
    dnssec-validation auto;
    dnssec-lookaside auto;

    auth-nxdomain no;
    recursion yes;
    allow-query { any; };
};

Setting dnssec-validation auto instructs BIND to use the built-in root trust anchor managed by the bind-keys file. Save and close the file, then verify the syntax:

sudo named-checkconf /etc/named.conf

No output means the configuration is valid. Reload named:

sudo systemctl reload named

Step 3: Generate DNSSEC Keys for Your Zone

DNSSEC uses two key pairs per zone. The Zone Signing Key (ZSK) signs individual resource records. The Key Signing Key (KSK) signs the ZSK and is used to build the chain of trust up to the parent zone. Navigate to your zone directory:

cd /var/named

Generate the ZSK using RSASHA256 with a 1024-bit key (suitable for ZSK):

sudo dnssec-keygen -a RSASHA256 -b 1024 -n ZONE example.com

This produces two files, for example:

Kexample.com.+008+12345.key
Kexample.com.+008+12345.private

Generate the KSK using a 2048-bit key and the -f KSK flag:

sudo dnssec-keygen -a RSASHA256 -b 2048 -n ZONE -f KSK example.com

This produces another pair:

Kexample.com.+008+67890.key
Kexample.com.+008+67890.private

Set appropriate ownership and permissions:

sudo chown named:named Kexample.com.+008+*.key Kexample.com.+008+*.private
sudo chmod 640 Kexample.com.+008+*.private

Step 4: Include Keys in the Zone File

Edit your zone file (e.g., /var/named/example.com.zone) and include the public key files at the bottom using the $INCLUDE directive. First, increment the zone serial number:

sudo vi /var/named/example.com.zone

Add these lines at the end of the zone file:

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

Verify zone syntax before signing:

sudo named-checkzone example.com /var/named/example.com.zone

Step 5: Sign the Zone with dnssec-signzone

Use dnssec-signzone to cryptographically sign all records in the zone. The -A flag includes all DNSKEY records, -3 generates NSEC3 records (for authenticated denial of existence), and -e sets the signature expiry:

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

This creates a signed zone file named example.com.zone.signed. Update the zone file reference in named.conf:

zone "example.com" IN {
    type master;
    file "example.com.zone.signed";
    allow-transfer { none; };
};

Reload the configuration:

sudo systemctl reload named

Step 6: Verify DNSSEC with dig

Use dig with the +dnssec flag to confirm signatures are being served. Look for the ad (authenticated data) flag in the response header:

dig +dnssec example.com SOA @127.0.0.1

Check for RRSIG records in the answer section:

dig +dnssec example.com A @127.0.0.1

;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 1
;; ANSWER SECTION:
example.com.    86400   IN  A       203.0.113.10
example.com.    86400   IN  RRSIG   A 8 2 86400 20260617000000 (
                                    20260517000000 12345 example.com.
                                    AbCdEfGh... )

To validate DNSSEC from a public resolver:

dig +dnssec +cd example.com @8.8.8.8

Step 7: Check Configuration with named-checkconf

After every change, always validate the full named configuration including referenced zone files:

sudo named-checkconf -z /etc/named.conf

This recursively checks all included zone files and reports any errors. Monitor the named service log for DNSSEC-related messages:

sudo journalctl -u named -f
sudo tail -f /var/log/messages | grep named

Look for lines containing DNSSEC, signed, or validation to confirm normal operation. If you see insecurity proof failed, check that the DS record has been published at the parent registrar.

Step 8: Publish the DS Record at the Parent Zone

For external DNSSEC to work end-to-end, you must submit the Delegation Signer (DS) record to your domain registrar or parent zone. Extract the DS record from your KSK:

sudo dnssec-dsfromkey Kexample.com.+008+67890.key

Output example:

example.com. IN DS 67890 8 1 ABCDEF1234567890ABCDEF1234567890ABCDEF12
example.com. IN DS 67890 8 2 ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD

Submit the SHA-256 (type 2) DS record to your registrar’s DNS management interface. Propagation typically takes up to 48 hours. Validate the chain of trust after propagation:

dig +trace +dnssec example.com

Conclusion

You have successfully configured DNSSEC on RHEL 7 using BIND 9. Your zone is now cryptographically signed, DNSSEC validation is enabled in the resolver, and you have verified the setup with dig. Ongoing maintenance requires re-signing the zone before signatures expire (check the expiry dates with dnssec-signzone -t output), rotating keys periodically, and monitoring named logs. For automated key rollover, consider using BIND’s inline signing feature (auto-dnssec maintain; inline-signing yes; in the zone declaration) which handles re-signing transparently. DNSSEC is a foundational security control that significantly raises the bar for DNS-based attacks against your infrastructure.