DNS & BIND 9

1 Building the authoritative DNS server

  • Repeat the steps for the next chapter on the nsNNa.dnslab.org and nsNNb.dnslab.org virtual machines (primary and secondary authoritative server)
  • User: user
  • Password: DNSandBIND

1.1 Enable the ISC BIND 9 repository for Enterprise Linux 9

  • Add the ISC BIND 9 repository to the packet-manager repository list
% dnf copr enable isc/bind
  • Install the EPEL (Extra Packages for Enterprise Linux) repository (required for additional dependencies needed for BIND 9.20)
% dnf install epel-release

1.2 Installing BIND 9.20

  • Install BIND 9.20 from the ISC repositories
% dnf install isc-bind
  • ISC and EPEL signing keys
Importing GPG key 0xC35B531D:
 Userid     : "isc_bind (None) <isc#bind@copr.fedorahosted.org>"
 Fingerprint: 490C 4AE6 3D8A 6B24 A641 2C8D ED4A 0B1B C35B 531D
 From       : https://download.copr.fedorainfracloud.org/results/isc/bind/pubkey.gpg

Importing GPG key 0x3228467C:
 Userid     : "Fedora (epel9) <epel@fedoraproject.org>"
 Fingerprint: FF8A D134 4597 106E CE81 3B91 8A38 72BF 3228 467C
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
  • Quick reference for the named daemon:
    • The configuration file can be found at: /etc/opt/isc/scls/isc-bind/named.conf
    • Command line options for the daemon can be specified in: /etc/opt/isc/scls/isc-bind/sysconfig/named
  • Note that due to the nature of Software Collections, no BIND 9 daemon or utility installed by these packages is available in $PATH by default. To be able to use them, do the following:
    • To enable the Software Collection for the current shell, run scl enable isc-bind bash
    • To enable the Software Collection inside a shell script, add the following line to it: source scl_source enable isc-bind
% source scl_source enable isc-bind
% which named
/opt/isc/isc-bind/root/usr/sbin/named
  • Add BIND 9 SCL path to bash shell startup
% echo "source scl_source enable isc-bind" >> .bashrc
  • Link the ISC BIND configuration file directory into the /etc directory (for easy access)
% ln -s /etc/opt/isc/scls/isc-bind /etc
  • Enable and start BIND 9
% systemctl enable --now isc-bind-named
  • Check that BIND 9 is running without errors
% rndc status
% systemctl status isc-bind-named

1.2.1 A configuration file for an authoritative BIND 9 server

  • Let's tweak the configuration file /etc/isc-bind/named.conf for an authoritative-only DNS server
options {
        directory "/var/named";
        listen-on { any; };
        listen-on-v6 { any; };
        dnssec-validation no;
        recursion no;
        minimal-responses yes;
        minimal-any yes;
        querylog no;
        max-udp-size 1232;
        edns-udp-size 1232;
        zone-statistics yes;
};
  • Logging for the authoritative server
logging {
        channel default_syslog {
          // Send most of the named messages to syslog.
          syslog local2;
          severity debug;
        };
        channel xfer {
          file "transfer.log" versions 10 size 10M;
          print-time yes;
        };
        channel update {
          file "update.log" versions 10 size 10M;
          print-time yes;
        };
        channel named {
          file "named.log" versions 10 size 20M;
          print-time yes;
          print-category yes;
        };
        channel security {
          file "security.log" versions 10 size 20M;
          print-time yes;
        };
        channel dnssec {
          file "dnssec.log" versions 10 size 20M;
          print-time yes;
        };
        channel ratelimit {
          file "ratelimit.log" versions 10 size 20M;
          print-time yes;
	      };
        channel query_log {
          file "query.log" versions 10 size 20M;
          severity debug;
          print-time yes;
        };
        channel query-error {
          file "query-errors.log" versions 10 size 20M;
          severity info;
          print-time yes;
        };

        category default        { default_syslog;  named; };
        category general        { default_syslog;  named; };
        category security       { security; };
        category queries        { query_log; };
        category dnssec         { dnssec; };
        category edns-disabled  { default_syslog; };
        category config         { default_syslog; named; };
        category xfer-in        { default_syslog; xfer; };
        category xfer-out       { default_syslog; xfer; };
        category notify         { default_syslog; xfer; };
        category client         { default_syslog; named; };
        category network        { default_syslog; named; };
        category rate-limit     { ratelimit; };
	category update         { update; };
};
  • Test the configuration
% named-checkconf
  • Reload the BIND 9 configuration
% rndc reconfig
  • The last two commands might fail. Why? What can you do to fix the issue?
  • Open port 53 (DNS) in the firewall
% firewall-cmd --permanent --zone=public --add-service=dns
% firewall-cmd --reload
  • Test if you can reach your new authoritative server from the DNS resolver
    • from the resolver machine (NNN = your number)
$ dig @nsNNNa.dnslab.org ch TXT version.bind

1.3 Solution "Building an authoritative DNS Server":

  • Issue: The /var/named directory is missing and needs to be owned by the named user.
  • Create the /var/named directory
% mkdir /var/named
  • Adjust the permissions on the BIND 9 home directory
% chown named: /var/named
  • The BIND 9 process should now successfully load the new configuration
% rndc reconfig

1.4 Create a primary zone

  • Work on the primary DNS server nsNNa
  • Goal: a working primary zone for this training lab environment
  • The trainer will publish the solution after some time into the exercise, but first try to create the configuration without outside help

1.4.1 A zone file

  • Create a new zone file for the zone zoneNN.dnslab.org in the BIND 9 home directory /var/named
  • The zone records should have a TTL of 60 seconds (not recommended for production, but required for the course labs)
  • The zone should contain: 1 x SOA, 2 x NS records (for nsNNa and nsNNb)
  • One A record for the name primary.zoneNN.dnslab.org (IPv4 of nsNNa)
  • One AAAA record for the name primary.zoneNN.dnslab.org (IPv6 of nsNNa)
  • One A record for the name secondary.zoneNN.dnslab.org (IPv4 of nsNNb)
  • One AAAA record for the name secondary.zoneNN.dnslab.org (IPv6 of nsNNb)
  • A TXT record with the owner-name of text and a text of your choice
  • Two MX records for primary and secondary with different preference values
  • Check the syntax of your zone-file with named-checkzone

1.4.2 Register the zone in the BIND 9 configuration

  • Create a zone block in named.conf for a primary zone for the zone created in the last chapter
  • Test the configuration with named-checkconf -z
  • Reload the BIND 9 configuration
  • Verify that nsNNa.dnslab.org answers authoritatively for this zone (AA-Flag!)

1.4.3 Solution for primary zone

  • The Zonefile (your zone will have different IPv4 and IPv6 addresses)
$TTL 60
@          IN SOA       nsNNa.dnslab.org. hostmaster.zoneNN.dnslab.org. 1001 1h 30m 41d 30
           IN NS        nsNNa.dnslab.org.
           IN NS        nsNNb.dnslab.org.
           IN MX        10 primary
           IN MX        20 secondary
primary    IN A         192.0.2.53
           IN AAAA      2001:db8:100::53
secondary  IN A         192.0.2.153
           IN AAAA      2001:db8:200::53
text       IN TXT       "DNS Leap Ahead!"
  • The primary zone configuration on nsNNa
zone "zoneNN.dnslab.org" {
    type primary;
    file "zoneNN.dnslab.org";
};

1.5 Test

  • Verify the delegation of your DNS servers with
    dig text.zoneNN.dnslab.org txt
    

2 A quick look at DNSSEC

2.1 DNS Security (or lack of)

  • the classic DNS from 1983 has not been designed with security in mind
  • Attack vector: DNS cache poisoning 0205-dns-dangers.png
  • Attack vector: Men-in-the-Middle data spoofing 0206-dns-dangers.png
  • Attack vector: changes to the client DNS resolver configuration 0207-dns-dangers.png
  • Attacks of authoritative DNS servers 0208-dns-dangers.png
  • DNSSEC can help 0210-roadsign.png

2.2 DNSSEC

  • The DNS security extension DNSSEC secures DNS data by augmenting the data with cryptographic signatures
    • The owner (administrator) creates a pair of private and public keys for each DNS zone (asymmetric crypto)
    • The owner/administrator signs all DNS data with the private/secret key
    • The recipient of the data (DNS resolver or client operating system or application) will verify (validate) the data
      • That the data has not been changed on the server nor during transit
      • That the data comes from the owner (the owner of the private key)

2.3 The chain of trust in DNS

  • DNSSEC creates a chain of trust between the parent zone and the child zone

0209-DNSSEC-chain-of-trust.png

  • Applications and DNS resolvers can follow the chain of trust to a configured trust anchor to validate the DNS data
  • We will look into DNSSEC in more details later in this course

3 DNSSEC signing and validation

4 DNSSEC in a nutshell

  • In DNSSEC, each zone has one or more key pairs.
    • The private key of each pair
      • Is stored securely (probably on a hidden primary)
      • Is used to sign zone data
      • Should never be stored in a RR
    • The public key of each pair
      • Is stored in the zone data, as a DNSKEY record
      • Is used to verify zone data
  • A private key signs the hashes of each RRSet in a zone.
  • The public key is accessible through a standard RR.
    • Recursive servers or clients query for the public key RR in order to decrypt a hash.
    • The RR is known as the DNSKEY and covered below.

4.1 DNSSEC records

4.1.1 RRSIG

  • The RRSIG records holds the cryptographic signature over the DNS data. The first field of the RRSIG holds the type this RRSIG is for. Together with the domain name of the RRSIG this data is important to match the signature to the data record.
  • A zone's private key signs the RRSets in the zone.
    • The signatures are added to the zone as RRSIG RRs.
    • If two key pairs are in use, each RRSet is signed twice, and there is double the number of signatures.
  • Signatures have start and expiration times (typically a month or less apart).
    • They must be replaced before expiring. BIND 9 can automate the signature updates.
    • Keys don't have expiration timers.

  • Work on the virtual machine
  • Ask for the DNSSEC signature of lwl.org NS:
    $ dig lwl.org NS +dnssec +multi
    
  • Answer these questions

4.1.2 DNSKEY

  • The public key of a DNSSEC key pair is stored in an DNSKEY RR.
    • The private key is not publicly available or accessible through DNS.
  • DNSKEY RRs are stored in the zone they can verify.
    • This conveniently means the zone administrator can sign all the RRSets and create the DNSKEY RRSet.

  • Work on the virtual machine
  • Ask for the DNSSEC keys of dnsworkshop.cz:
    $ dig dnsworkshop.cz DNSKEY +dnssec +multi
    
  • Answer these questions
    • Which algorithm is this zone using?

5 DNSSEC Keys

5.1 Algorithms for DNSSEC

DNSSEC keys can be generated with different crypto algorithms. Some of these algorithms are obsolete and deprecated, others are not (yet) widely supported by deployed DNS software to be useful

Algorithm No. Note
RSAMD5 1 deprecated, not implemented
RSASHA1 5 not recommend, deprecated for DNSSEC signing, not supported in Red Hat Enterprise Linux 9 (and up)
RSASHA256 8 recommended
RSASHA512 10 large keys, large signatures, risk of UDP fragmentation or TCP fallback
DSA 3 deprecated, slow validation, no extra security
ECC-GOST 12 deprecated
ECDSA 13/14 small signatures, read RSA vs ECDSA for DNSSEC
ED448/ED25519 16/15 not supported by legacy resolver RFC 8080 / RFC 8032 Edwards-Curve Digital Signature Algorithm (EdDSA) / Assessing DNSSEC with EdDSA
SM2SM3 17 SM2 and SM3 are cryptographic algorithms that are national standards for China, as well as ISO/IEC standards RFC 9563
GOST-2012 23 GOST R 34.10-2012 and GOST R 34.11-2012 are Russian national standards. Their cryptographic properties haven't been independently verified. RFC 9558
     

5.2 DNSSEC key sizes for RSA algorithm

  • Every additional bit increases the strength of a DNSSEC against brute-force attacks to break the key
  • Double the RSA key size results in
    • Generating signatures is up to eight times more work
    • Validation of DNSSEC signatures inside an DNS resolver up to 4 times more work
    • Size of key and signature records increases and can create operational issues

5.2.1 Problems with large DNS response messages

  • Fragmentation of IPv4 and IPv6 UDP messages
    • Hurts performance
    • Fragmented IPv6 packets (containing a fragment header) could be blocked on the Internet backbone
    • Enables UDP fragmentation attacks against non-validating DNS resolver
    • DNS amplification attacks

The goal should be that the DNSKEY RRSet during an KSK rollover (including perhaps an emergency KSK) stays below 1232 byte

5.3 KSK and ZSK

  • For organizational reasons, DNSSEC splits the chain of trust inside a DNS zone onto two different keys: the Key-Signing-Key (KSK) and the Zone-Signing-Key (ZSK)

5.3.1 KSK:

  • The KSK generates only one signature: the signature over the DNSKEY record (RRset)
  • The hash of the KSK is stored in the parent zone as the DS record. This hash is used to close the chain of trust from the parent zone to the DNSSEC signed zone. Each time the KSK in the DNSSEC signed zone is changed, the DS record in the parent zone must be replaced. The KSK has therefore a dependency on the parent zone.
  • Because of this dependency with the parent zone, the KSK is usually a stable and strong key and not rolled often

5.3.2 ZSK:

  • The Zone-Signing-Key does not have dependencies to external resources and can be rolled at any time
  • Usually the ZSK is rolled often (and automatically), so the key does not need to be particularly strong

5.4 BIND 9: KSK/ZSK signature over the DNSKEY record set

  • For historical reasons, BIND 9 generates two signatures over the DNSKEY record set:
    • one signature generated with the KSK (required)
    • one signature generated with every active ZSK (optional)
  • This can generate larger than good DNSKEY record answer messages
  • BIND 9 can be configured to only generate a signature using the KSK
    options {
      [...]
      dnssec-dnskey-kskonly yes;
    };
    

5.5 Lifetimes of DNSSEC keys

  • DNSSEC keys have an organisational lifetime (there is no technical limit on the lifetime, unlike with X.509 TLS certificates)
    • the administrator responsible for a DNSSEC-signed zone can decide when to change the DNSSEC keys
  • Renewing the DNSSEC key material of a zone is called a key rollover
  • Keys with weak algorithms or short key lengths should be changed (rolled) in shorter intervals
    • 1024bit RSASHA256 -> 30 days (ZSK)
    • 1536bit RSASHA256 -> 120 days (ZSK)
    • 2048bit RSASHA256 -> 360 days (KSK)
    • 2560bit RSASHA256 -> 720 days+ / 2 years+ (KSK)

5.6 DNSSEC Signer "Best-Practices"

  • Zones with high security requirements should keep the DNSSEC keys "offline"
    • this requires manual DNSSEC signing
  • Keys can be stored securely in Hardware Security Modules (HSM)
  • HSM selection criteria for DNSSEC signing
    • Number of key storage slots
    • Timely support for new operating system releases (Linux distribution)
    • Timely support for new OpenSSL releases
    • Stability of the HSM-Driver
  • Zones with medium to low security requirements should use a hidden-primary DNSSEC signer configuration
    • The DNSSEC signing authoritative server is not exposed to the Internet, it will not receive DNS queries
    • DNS secondary authoritative servers in the Internet will receive the DNSSEC signed zone from the hidden DNSSEC signer through DNS zone transfer
    • The DNSSEC key material is secured with operating system level permissions
    • With full automation of DNSSEC key-rollovers, the DNS server administrators don't need access to the DNSSEC keys
    • Login and access to the DNSSEC key files should be audited (Logging online and towards a remote log server)
  • Zone content can be split across multiple zones or DNS server with DNS delegation
    • Every zone can have a different DNSSEC security level
    • Example: main zone example.com signed via a hidden-signer (keys not exposed to the Internet) has a sub-zone with e-mail address hashes (OPENPGPKEY and SMIMEA) in the zone securemail.example.com) which is secured with NSEC3-NARROW scheme and keys that are online on every authoritative server

6 DNSSEC signing with BIND 9

6.1 Manual zone signing

  • Since BIND 9.6 zones can be signed manually (BIND 9.6 was the first version to support the new DNSSEC version)
  • Benefits:
    • The signing can be done offline on a machine not connected to any network, BIND 9 does not need to be running on the signing machine
    • The DNSSEC private keys can be stored on security devices such as Hardware Security Modules (HSM) and can be encrypted
    • The generated DNSSEC signed zone files are universal and can be used in any DNS server that supports DNSSEC signed zones
    • The parameters of the signing process can be tuned
  • Drawbacks:
    • Manually signed zones need to be refreshed (re-signed) periodically so that the signatures do not expire
    • Any automation must be done through custom scripts

6.2 Manual signing with BIND 9

  • These are the steps to manually sign a zone for BIND 9
  • For older BIND 9 versions, enable DNSSEC in the named.conf configuration file
    options {
       directory "/var/named";
    };
    
  • Create a Zone-Signing-Key (ZSK)
    • This requires good real entropy (randomness) in the operating system. If the key creation process takes too long (more than a minute for a key), there might not be enough entropy in the system. In such case a hardware random number generator or a software entropy gathering daemon (such as haveged) can help
    % dnssec-keygen -a RSASHA256 -b 1536 zoneNN.dnslab.org
    Generating key pair.........++++ ............................
    KzoneNN.dnslab.org.+008+16239
    
    % more KzoneNN.dnslab.org.+008+16239.key
    ; This is a zone-signing key, keyid 16239, for zoneNN.dnslab.org.
    ; Created: 20160202121320 (Tue Feb  2 13:13:20 2016)
    ; Publish: 20160202121320 (Tue Feb  2 13:13:20 2016)
    ; Activate: 20160202121320 (Tue Feb  2 13:13:20 2016)
    zoneNN.dnslab.org. IN DNSKEY 256 3 8 AwEAAc1xFtt40wPEx4TVB7h8Ac7HvMZuF1LIqESU/0HUUzDT2rkujMdL
    z0fgJJQVStYIbb1fXN0/PmKayEpj5ScbT7WU9Bef6b49uG1PwhsaftRr
    /udr3DEA6MTEdRqkl8K+E3P9hFj4XKxus45MYVSPaXZg3TcIQK3xpXC8
    sKISny43cQaJpm12oBtKsANlA25KRJC8soP1s/GqLSnArWDMN/YGqvs0
    QECulpm2Nh1uULZfzwga8515xizyx5yAl/sgWQ==
    
  • Generate a Key-Signing-Key with the same DNSSEC algorithm used for the ZSK
    % dnssec-keygen -a RSASHA256 -b 2048 -f KSK zoneNN.dnslab.org
    Generating key pair...................................................
    KzoneNN.dnslab.org.+008+04351
    
    % more KzoneNN.dnslab.org.+008+04351.key
    ; This is a key-signing key, keyid 4351, for zoneNN.dnslab.org.
    ; Created: 20160202121714 (Tue Feb  2 13:17:14 2016)
    ; Publish: 20160202121714 (Tue Feb  2 13:17:14 2016)
    ; Activate: 20160202121714 (Tue Feb  2 13:17:14 2016)
    zoneNN.dnslab.org. IN DNSKEY 257 3 8 AwEAAcmn/QkiCne922gBBBuJJOnq9jnG2yYbB10zBS2SgUCUxlZfM2ja
    PAyubB2V+QhFsKf0VKUsVGl28JWAMcG1NGitj+nna4sGwvmeumj70DbG
    ZzynwcFknEZG1Swn2bM/OFmlMS2WV3luzDYKnLeZgvN5geB6ZetONlpP
    H9am3MRmExNIxoFb5NEcUlCzxSUI5GzjPZtGmCtDoNKrGE5nsssCgrjw
    ec6hbeXLOjP9JiQ3egF3+PJHLUOjuqXKwSofHw4jV4Rqc3eP+uAHk5Wp
    iH/BNW7c7lJ9IP+jZYZ3dp3SkO2qU8BOVV4fcm1L+IVcA9jwuuPaOV53
    j9L8fCTL/Uk=
    
  • This is the content of the unsigned DNS zone
    $TTL 3600
    $ORIGIN zoneNN.dnslab.org.
    @             IN SOA serverNN.dnslab.org.  hostmaster.zoneNN.dnslab.org. (
                         1001 ; serial
                         1d   ; refreh
                         2h   ; retry
                         4w   ; expire
                         30m  ; negTTL
                      )
                  IN NS serverNN.dnslab.org.
                  IN MX 10 mail.zoneNN.dnslab.org.
    www           IN A  192.168.53.199
    mail          IN A  192.168.53.199
    
  • Add the public part of the ZSK and KSK to the zone (be careful with the shell redirection!) or use master file $INCLUDE syntax.
    % cat KzoneNN.dnslab.org.+008+*.key >> zoneNN.dnslab.org
    
  • Sign the zone file
    % dnssec-signzone -o zoneNN.dnslab.org \
            -k KzoneNN.dnslab.org.+008+04351.private \
            zoneNN.dnslab.org \
    	 KzoneNN.dnslab.org.+008+16239.private
    Verifying the zone using the following algorithms: RSASHA256.
    Zone fully signed:
    Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                          ZSKs: 1 active, 0 stand-by, 0 revoked
    zoneNN.dnslab.org.signed
    
  • Zone signing tool syntax:
    dnssec-signzone -o <origin> -k <KSK-private> <zone-file> <ZSK-private>
    
    • If the error message dnssec-signzone: fatal: SOA is not signed (keys offline or inactive?) is displayed, then the KSK and ZSK have been given in the wrong order
    • Additional options for dnssec-signzone
      • -j sec Jitter, variation in seconds of the signature validity
      • -M maxttl - specifies the maximum allowed TTL in the signed zone. Higher TTL values will be capped to this number.
      • -s starttime - start of validity of the signatures
      • -e endtime - expire time of the signatures
      • -N SOA-format - format of the SOA serial number
        • keep do not modify the current SOA serial number
        • increment increment the current SOA by one
        • date set the SOA serial number to today's date in YYYYMMDDnn format
        • unixtime use the Unixtime (seconds since 1.1.1970) as the SOA serial
      • -x only create one signature for the DNSKEY record set (using the KSK)
      • -n numcpus use this amount of CPU cores for signing
      • -t print performance statistics after signing
  • The signed zone is stored in a new file with the name of the original zone file and the extension .signed
    zoneNN.dnslab.org.      3600    IN SOA  serverNN.dnslab.org. hostmaster.zoneNN.dnslab.org. (
                                             1001       ; serial
                                             86400      ; refresh (1 day)
                                             7200       ; retry (2 hours)
                                             2419200    ; expire (4 weeks)
                                             1800       ; minimum (30 minutes)
                                             )
                             3600    RRSIG   SOA 8 3 3600 (
                                             20160303114542 20160202114542 16239 zoneNN.dnslab.org.
                                             jT+M9IhjViHkoLnC5/y+MaHYoxpcoyHvif7H
                                             sFESQfk7JBx654zb7OZ2LVxsmMnGtiqxkLlD
                                             l5nJtBJuWXMufPLks+qQb42YjdGgU6vf5WOI
                                             GkTyTMf0ZcNc3ULZZCMG/Vkf3Pak4O6He+cB
                                             xvdbDzOOaLcQqlKH8xY/ylmHawJTm8Mmcbb/
                                             1tL3B/Iv0SI9Lv+F/g+ajaA7fd3bcr0Vueol
                                             gOTJ3OZkIEoQFROrn5UMQ/fvbY7Go2TjDT7I
                                             GYMu )
                             3600    NS      serverNN.dnslab.org.
                             3600    RRSIG   NS 8 3 3600 (
                                             20160303114542 20160202114542 16239 zoneNN.dnslab.org.
                                             ColPExa9EdSA1Nt1DsEtX5qjYzNWA8vUl8ef
                                             oJG409V6BX4JJsK7RJGCGlmqDIA7HO1IQKug
                                             64N+fD/IuVjqHsPxc/YtP1sdnnLjYK0rHgG7
                                             kMMkoqU7Ta/l/laKKd3jcI/kh66dOsTwYrEC
                                             aykvfzYCnVj/rxwEomu2aTbPh/Nt7V2OEXDT
                                             EqlmpS34yQ3LvYfnSTTipLYZNS/2kL7NRuEo
                                             1gId5PD/IMAKSpTqfilW1bQUf+CYJF/CGgF5
                                             KRIx )
    
  • Compare the file sizes. The signed zone is much larger
    % wc zoneNN.dnslab.org*
         23     133    1554 zoneNN.dnslab.org
        130     314    5178 zoneNN.dnslab.org.signed
        153     447    6732 total
    
  • Adjust the zone definition in named.conf to load the new signed zone
    zone "zoneNN.dnslab.org" IN {
        type primary;
        file "zoneNN.dnslab.org.signed";
    };
    
  • Check the new BIND 9 configuration. The output should indicate that the zone is now DNSSEC signed
    % named-checkconf -z
    zone zoneNN.dnslab.org/IN: loaded serial 1001 (DNSSEC signed)
    
  • Load the DNSSEC signed zone into the BIND 9 DNS server
    % rndc reload zoneNN.dnslab.org
    
  • Send the DS record for the KSK to the operator of the parent zone
    % cat dsset-zoneNN.dnslab.org.
    zoneNN.dnslab.org.  IN DS 16239 8 1 C0213 ... 0373A
    zoneNN.dnslab.org.  IN DS 16239 8 2 EAC59 ... E694690565680E3F6D201 E2650EAE
    

6.3 Exercise: Signing BIND 9.6 style (manual signing)

  • Create a Zone Signing Key (ZSK), RSASHA256 Algorithm and 1024 bit length
    % mkdir -p /etc/isc-bind/keys
    % cd /etc/isc-bind/keys
    % dnssec-keygen -a RSASHA256 -b 1024 zoneNN.dnslab.org
    
  • Create a Key Signing Key (KSK), RSASHA256 Algorithm and 2048 bit length
    % dnssec-keygen -a RSASHA256 -b 2048 -f KSK zoneNN.dnslab.org
    
  • Add the public part of the ZSK and KSK to the zone file and manually increment the SOA serial number (in a text editor)
    % cat KzoneNN.dnslab.org.+008+*.key >> /var/named/zoneNN.dnslab.org
    % $EDITOR /var/named/zoneNN.dnslab.org
    
  • DNSSEC sign the zone
    % dnssec-signzone -o zoneNN.dnslab.org \
           -k KzoneNN.dnslab.org.+008+(KSK).private \
          /var/named/zoneNN.dnslab.org \
          KzoneNN.dnslab.org.+008+(ZSK).private
    
  • Adjust the zone definition in the Bind 9 configuration file to now load the signed version of the zone file
    zone "zoneNN.dnslab.org" {
          type primary;
          file "zoneNN.dnslab.org.signed";
    };
    
  • Test the BIND 9 configuration, and if no errors are shown, reload the signed zone into BIND 9
    % named-checkconf -z
    % rndc reconfig
    
  • Check locally if DNSSEC records are returned from our DNS server
    $ dig @localhost zoneNN.dnslab.org SOA +dnssec +multi
    
  • The DS record for the zone can be found in the file dsset-zoneNN.dnslab.org in the directory where the zone has been signed. Copy the DS record onto the machine of the trainer (using scp, username user and password DNSandBIND. The trainer is operating the parent zone of your zone and will add the DS record there to close the chain of trust.
    % cat dsset-zoneNN.dnslab.org.
    % scp dsset-zoneNN.dnslab.org. user@ns10a.dnslab.org:.
    
  • Wait for the DS record to be published in the parent zone
  • Now test DNSSEC validation against your DNS resolver machine
    $ dig @<IP-of-resolver> zoneNN.dnslab.org SOA +dnssec +multi
    
  • Query the DS record from the parent
    $ dig @<IP-of-resolver> zoneNN.dnslab.org DS +dnssec
    
  • Make a small change to your zonefile (add or change a TXT record), increment the SOA serial (or use the command dnssec-signzone with the parameter -N unixtime)
  • Test the zone file
    % named-checkzone zoneNN.dnslab.org /var/named/zoneNN.dnslab.org
    
  • Re-Sign the zone
    % dnssec-signzone -o <zonenname> -k <KSK-private-file> <zonefile> \
           <ZSK-private-file>
    
  • Load the newly signed zone in BIND 9
    % rndc reload zoneNN.dnslab.org
    
  • Check for the changes you made, are they visible? (Do you still see the AD-Flag?). Adjust the query below to match your changes to the zone file:
    $ dig TXT text.zoneNN.dnslab.org +dnssec +multi
    

7 DNSSEC Key and Signing Policy

  • BIND 9.16 has introduced a new dnssec-policy feature as a further step in automation
  • Configuring a zone to use KASP (Key And Signing Policy) can be as easy as
    zone "example.net" {
        type primary;
        dnssec-policy default;
    	...
    };
    
  • Requirements
    • One of the following
      inline-signing yes;    // manual edited zone files
      update-policy local;   // dynamic update zone files
      
  • Benefits
    • More intuitive and a higher level of automation
    • Several vendors use KASP (Knot, OpenDNSSEC)
    • Robust
      • No need to rely on metadata added by humans
      • Use key timing state machine

7.1 Default policy

  • Single CSK ("common signing key", also called a SSK - "single signing key")
    • ECDSAP256SHA256 (algo 13) with unlimited lifetime
    • RRSIG validity 14 days, refreshed 5 days before expiration
  • NSEC
  • Key timings:
    • DNSKEY TTL: 3600, max zone TTL: 86400 (1 day)
    • Key publish and retire safety times: 3600 (1 hour)
    • Propagation delay: 300 (5 minutes)
  • Parent timings
    • DS TTL: 86400 (1 day)
    • Propagation delay: 3600 (1 hour)
  • Prevent policy changes on upgrade by using an explicitly defined dnssec-policy, rather than default

7.2 Creating custom DNSSEC policies in BIND 9

  • Below is an example of an custom DNSSEC policy in BIND 9.16+ named "one"
    dnssec-policy "one" {
        keys {
            ksk lifetime 365d algorithm rsasha256 4096;
            zsk lifetime 60d  algorithm rsasha256 1024;
        };
    };
    
    zone "example.net" {
        file "example.net.zone";
        dnssec-policy "one";
    };
    
    • keys specify roles instead of specific keys
    • lifetime specifies duration or unlimited
    • algorithm uses mnemonic or number

7.3 Additional configuration of custom policy

dnssec-policy "one" {
    keys {
        ksk lifetime 365d algorithm rsasha256 4096;
        zsk lifetime 60d  algorithm rsasha256 1024;
    };
    dnskey-ttl 600;
    publish-safety PT2H;
    signatures-refresh 7d;

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

7.4 Key-and-Signing-Policy (KASP) syntax

dnssec-policy <string> {
    dnskey-ttl <duration>;
    keys { ( csk | ksk | zsk ) [ ( key-directory ) ]
        lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ...
    };
    max-zone-ttl <duration>;
    nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
    parent-ds-ttl <duration>;
    parent-propagation-delay <duration>;
    publish-safety <duration>;
    purge-keys <duration>;
    retire-safety <duration>;
    signatures-refresh <duration>;
    signatures-validity <duration>;
    signatures-validity-dnskey <duration>;
    zone-propagation-delay <duration>;
};

7.5 A real world custom DNSSEC policy

  • A KSK with ECDSAP256SHA256 and no automatic key rollover
  • A ZSK with ECDSAP256SHA256 and a rollover interval of 30 days
  • Signatures are valid for 10 days
  • Signatures will be refreshed after 8 days (2 day buffer)
  • TTL of DNSKEY records is 2 hours
  • Max TTL of other records in the zone is 1 day
  • DNSSEC keys will be published one hour after they have become valid (publish-savety)
  • DNSSEC keys will be kept in the zone one our after deactivation (retire-safety)
  • Expired DNSSEC keys will be removed after 90 days
  • Zone transfer between primary and secondary servers is 5 minutes (zone-propagation-delay)
dnssec-policy "example.eu" {
       dnskey-ttl 2h;
       keys { ksk lifetime unlimited algorithm ECDSAP256SHA256;
              zsk lifetime P30D      algorithm ECDSAP256SHA256;
            };
       max-zone-ttl 1d;
       publish-safety 1h;
       purge-keys P90D;
       retire-safety 1h;
       signatures-refresh 8d;
       signatures-validity 10d;
       signatures-validity-dnskey 10d;
       zone-propagation-delay 300;
 };

8 DNSSEC with dynamic zones

  • Since BIND 9.7.4 dynamic DNS-Zones (zones that are managed through dynamic DNS updates) can be DNSSEC signed
  • Benefits of DNSSEC with dynamic zones:
    • BIND 9 takes care of updating the signatures (RRSIG records) whenever they expire
    • The DNSSEC keys can be automatically imported into the zone and also they can be automatically removed once they are no longer in use
    • The lifetime of a DNSSEC key can be specified in the meta-data in the key files
    • Using the meta-data the key rollover can be automated
    • Changes to the zone are automatically DNSSEC signed
    • The SOA serial number will be automatically incremented for each change
    • The parser of the nsupdate tool used to send dynamic updates prevents syntax errors
    • The zone journal collects all changes to the zone
  • Drawbacks:
    • The primary authoritative DNS server with the dynamic zone must have access to the private DNSSEC key material in order to create the signatures. The primary server should not be exposed to the Internet but should be a "Hidden Primary"
    • The zone file may not be modified manually. The use of text editors and DNS management scripts on the zone file is not possible anymore

8.1 DNSSEC with a dynamic zone

8.2 Exercise: DNSSEC signing a dynamic DNS zone with BIND 9

  • Create a new directory for the zone and change its ownership
    % mkdir /var/named/myzones
    % chown named:named /var/named/myzones
    
  • Create a new zonefile as a child to the existing zone zoneNN.dnslab.org with the name dynamic.zoneNN.dnslab.org. It should contain one NS record and one SOA record (a bare minimum zone file). Save the zone file into /var/named/myzones/dynamic.zoneNN.dnslab.org.
    $TTL 30
    @    SOA  nsNNa.dnslab.org.  hostmaster 1001 1h 30m 41d 30s
    @    NS   nsNNa.dnslab.org.
    
  • Ensure named can write to the zone file
    % chown named:named /var/named/myzones/dynamic.zoneNN.dnslab.org
    
  • Add a new zone definition to the BIND 9 configuration file /etc/isc-bind/named.conf. The Key-Directory is relative to the BIND 9 home directory /var/named
    zone "dynamic.zoneNN.dnslab.org" {
      type primary;
      key-directory "myzones/keys";
      update-policy local;
      dnssec-policy default;
      file "myzones/dynamic.zoneNN.dnslab.org";
    };
    
  • Test the configuration and reload the BIND 9 server
    % named-checkconf -z
    % rndc reconfig
    
  • Test: you should see the DNSSEC RRSIG record(s)
    $ dig @127.0.0.1 dynamic.zoneNN.dnslab.org SOA +dnssec +multi
    
  • Add a NS record for the delegation to the parent zone
    % echo "dynamic.zoneNN.dnslab.org. IN NS nsNNa.dnslab.org." >> \
            /var/named/zoneNN.dnslab.org
    
  • Create the DS record and add it to the parent zone to close the chain of trust
    % dnssec-dsfromkey -K /var/named/myzones/keys/ \
              Kdynamic.zoneNN.dnslab.org.+013+(KSK) \
          >> /var/named/zoneNN.dnslab.org
    
  • Increment the SOA serial of the parent zone zoneNN.dnslab.org and re-sign that parent zone (remember, this zone is manually signed)
    % dnssec-signzone -o <zone-name> -k <KSK-private-file> \
              <zone-file> \
              <ZSK-private-file>
    
  • Re-Load the parent zone
    % rndc reload zoneNN.dnslab.org
    
  • You should now see a AD-Flag when querying data of the new dynamic zone from a DNSSEC validating resolver
    $ dig @9.9.9.9 dynamic.zoneNN.dnslab.org SOA +dnssec +multi
    
  • Add a new IPv4 A record to the zone (for testing purposes)
    % nsupdate -l
    > ttl 30
    > add www.dynamic.zoneNN.dnslab.org. IN A 192.0.2.80
    > send
    > quit
    
  • Query the new entry. Check for the AD-Flag.
    $ dig www.dynamic.zoneNN.dnslab.org +dnssec
    
  • Change the IPv4 address of the A record (replace xxx.xxx.xxx.xxx with the public IPv4 address of your primary authoritative server)
    % nsupdate -l
    > ttl 30
    > del www.dynamic.zoneNN.dnslab.org IN A
    > add www.dynamic.zoneNN.dnslab.org IN A xxx.xxx.xxx.xxx
    > send
    > quit
    
  • Test if the new entry can be queried and shows the AD-Flag.
  • Delete the www-Entry from the zone
    % nsupdate -l
    > del www.dynamic.zoneNN.dnslab.org IN A
    > send
    > quit
    
  • Force the zone file to be written from memory into a file and display the content
    % rndc sync dynamic.zoneNN.dnslab.org
    % less /var/named/myzones/dynamic.zoneNN.dnslab.org
    
  • All changes to the dynamic zone are written to the BIND 9 journal file for this zone. The journal file has the same name as the zone file, but with the extension .jnl
  • The journal file is a binary file, this file can be converted to readable format with the command named-journalprint:
    % named-journalprint /var/named/myzones/dynamic.zoneNN.dnslab.org.jnl
    

8.3 Exercise: Secure dynamic updates with TSIG keys

  • Dynamic updates should always be authorized by a cryptographic key. Authorization by IP address is insecure and not recommended
  • In this exercise, we will add TSIG security to our dynamic zone
  • Generate a new TSIG key, use the name dynamic-zoneNN-update-key as the key name:
    % tsig-keygen dynamic-zoneNN-update-key > /etc/isc-bind/<filename-for-TSIG>.key
    
  • Import the new TSIG key into the BIND 9 configuration file (you can also use include "<filename>"; if that is more convenient)
    key "dynamic-zoneNN-update-key" {
        algorithm hmac-sha256;
        secret "C7o1qNKcdkLef/1uDw1RQLSs9AqqbK1cliVecoGg0Ww=";
    };
    
  • Adjust the zone configuration to authenticate dynamic updates against the TSIG key
    zone "dynamic.zoneNN.dnslab.org" {
      type primary;
      key-directory "myzones/keys";
      // update-policy local;
      allow-update { key dynamic-zoneNN-update-key; };
      dnssec-policy default;
      file "myzones/dynamic.zoneNN.dnslab.org";
    };
    
  • Check and reload the BIND 9 configuration
  • Use nsupdate together with the TSIG-key to make changes to your zone
    $ nsupdate -k /etc/isc-bind/dynamic-zoneNN-update-key.key
    > ttl 60
    > add www.dynamic.zoneNN.dnslab.org IN A 1.2.3.4
    > send
    > quit
    

8.3.1 Recovering from BIND 9 journal mismatch

  • If the zone file of a dynamic zone is changed outside DNS dynamic update, the zone content becomes out-of-sync with the journal and BIND 9 will refuse to work with the zone (it will not load anymore). To solve this issue, stop BIND 9, remove the journal file, fix the zone-file on disk (if needed), and restart BIND 9
    % systemctl stop isc-bind-named
    % rm /var/named/dynamic/dynamic.zoneNN.dnslab.org.jnl
    % systemctl start isc-bind-named
    

8.3.2 Tools

9 NSEC vs. NSEC3

9.1 Authenticated Denial of existence - NSEC vs. NSEC3

  • The RRSIG records in DNSSEC secure the positive answers from DNS (answers to queries where DNS records exist)
  • But also negative answers need to be protected
    • without protection for negative answers, attackers could spoof negative answers to launch denial-of-service attacks. The attacker can make DNS clients believe that a DNS resource does not exist
  • DNS knows two kinds of negative answers: NXDOMAIN and NODATA/NXRRSET
    • NXDOMAIN = the requested domain name does not exist
    • NODATA/NXRRSET = the requested domain name does exist, but the requested record type does not exist for this name
  • DNS error messages such as SERVFAIL, FORMERR or REFUSED cannot be secured with DNSSEC (these errors indicate errors in the protocol or in the DNS server infrastructure). If the protocol is broken, DNSSEC can't work either.
  • The solution: the NSEC records in the DNSSEC signed zone create a list of all existing data in the zone (domain names and records types for the domain names)
    • When returning a negative answer, the DNS server returns the negative answer containing the NSEC record (plus a signature for the NSEC record) which proves that the requested data does not exist in DNS

nsec-chain.png

9.2 Issues with NSEC

  • The NSEC record is an elegant solution to the problem, but it has drawbacks:
    • It is now possible for outsiders to list the complete zone contents by following the NSEC record chain. This is called zone walking.
    • For most zones this is not a big problem, as the DNS zone content is public anyway (SOA, NS records, WWW-A, MX records)
    • But it can be an issue for zones with sensitive content (email addresses, hostnames of critical infrastructure, new product names that should no go public yet)
    • Operators of TLDs zones stay away from DNSSEC with NSEC, as it allows outsiders to record all changes to the TLD zone (new delegations and delegation removals)
    • The new compact authenticated denial of existance standard (RFC 9824) solves this issue.
  • Example of zone walking:
$ ldns-walk paypal.com

9.3 The NSEC3 record

  • RFC 5155 (2008) defines the NSEC3 record as an alternative to NSEC
    • All modern DNS servers support NSEC3
    • The NSEC3 record works similarly to NSEC, with the difference that the link between the owner names is done using SHA1 hashes of the domain names instead of the clear text names
    • NSEC3 makes it harder, but not impossible, to list the zone content

9.4 NSEC3 Chain

nsec-chain1.png

9.5 NSEC3-Parameter

  • The NSEC3 record contains a number of parameters used for the NSEC3 operation
    • The hashing algorithm used (currently only SHA1 is defined)
    • Flags: allows for DNSSEC opt-out in delegations.
    • Number of hash iterations
    • A salt value

9.6 NSEC3-Parameter Record

  • Every zone with NSEC3 records contains an NSEC3PARAM record. This record holds information needed by authoritative DNS servers to generate NSEC3 records for negative answers
  • Example: (SHA1, no flags, 20 iterations, salt value "ABBACAFE")
nsec3.dnslab.org.    0   IN  NSEC3PARAM 1 0 20 ABBACAFE

9.7 NSEC3 iterations and salt

  • The idea of the hash iterations in the NSEC3PARAM record was to allow the operator of the zone to fine tune the work required for calculating the hash
    • A higher number of iterations should make it harder for attackers to brute force break an NSEC3 domain name
    • A higher number also creates more CPU load for DNS resolvers that validate the NSEC3 records, making DNS name resolution slower
    • The iteration parameter of an NSEC3 signed zone should be re-evaluated from time to time (yearly) to adjust the value for the technical progress
  • The salt should make it impossible for an attacker to pre-calculate rainbow tables for the zone
  • The salt is a hexadecimal number, every hex digit contains 4 bit of information

9.8 Problems with NSEC3

  • The iterations had more an negative impact on the CPU load of the authoritative DNS servers than preventing attacks
  • The salt is not really needed, as each zone naturally has unique hashes so that a rainbow table for multiple zones is not possible

9.9 RFC 9276 - Guidance for NSEC3 Parameter Settings

  • RFC 9276 - Guidance for NSEC3 Parameter Settings (Best current practice) gives updates guidelines for NSEC and NSEC3 deployments
  • The iterations value should be set to 0 (meaning 1 iteration of SHA1 hashing)
    • DNSSEC responses containing NSEC3 records with iteration counts greater than 150 are now treated as insecure by major DNS resolvers!
  • As NSEC3 zones are inherently salted, the salt parameter should be set to -
  • The current recommendation for NSEC3PARAM is 1 0 0 - (SHA1 Hash, no flags, 1 iteration, no salt)

9.10 NSEC3 needed?

  • Most DNS zone can work with NSEC instead of NSEC3
    • Don't store names in DNS that should be secret (internal names, product names etc)
    • DNS is a service to publish data, not for hiding data

9.11 NSEC3 Narrow-Mode

  • RFC 7129 (also RFC 4470 and RFC 4471) describe a special variant of NSEC3 usage, called the narrow mode
    • With narrow mode, the NSEC3 records are not pre-calculated when the zone is signed, but they are created on the fly whenever a negative response is needed
      • To be able to calculate the signatures for such answers, every authoritative DNS server for the zone must have access to the private DNSSEC keys (at least the ZSK)!
  • With NSEC3 narrow mode, the DNS server does not return an NSEC3 chain of existing records, but a synthetic NSEC3 record that proves that the requested name does not exist
    • This prevents zone walking, as the number of possible NSEC3 records returned is near infinite. It will exhaust the memory of the attacker that will try to store this NSEC3 chain
  • Known implementations:

10 DNSSEC Key-Rollover

10.1 Why Keyrollover

  • The DNSSEC key material is public
    • Including the signatures and the matching clear text (DNS record sets)
  • The private key can get in un-authorized hands
    • By accident
    • By attacks on the signing server/HSM
    • When using online-signing, the private keys must be live on the signing DNS server
  • The key length or the algorithm used is not considered secure for a longer amount of time (for example 1024bit RSA keys)

10.2 The Challenges

  • The DNS is not consistent
    • DNS zone data can differ for some time between authoritative server of the same zone (delay in zone transfer)
    • DNS data is cached in DNS resolvers, operating systems, and applications
  • During a DNSSEC key-rollover, the chain of trust must be un-broken at all times from all vantage points of the Internet

10.3 DNSSEC Keyrollover Documentation

10.4 Key rollovers, when and how often?

  • DNSSEC keys do not have a technical lifetime, they don't expire
  • The operational life time of DNSSEC keys is decided by the responsible administrator(s) and can be changed at any time
  • The DNSSEC community has different views on KSK key rollovers
    • Often and regularly
    • Often but irregular (to not give attackers information when the system might be more vulnerable due to the key rollover)
    • Only if there is evidence that the key has been compromised or stolen

10.5 ZSK Rollover

  • The Zone-Signing-Key has no dependencies to external resources (such as the parent zone)
  • A ZSK Rollover can be started at any time
  • The 'pre-publication' rollover scheme is used for ZSK rollover

10.5.1 ZSK - pre-publication - Step 1

  • Create a new ZSK key pair
  • Publish the public part of the new key (DNSKEY) of the ZSK in the zone
  • The current/old ZSK is kept in the zone
  • The zone is signed with the current/old (not the new) ZSK and KSK

10.5.2 ZSK - pre-publication - Step 2

  • Wait for the zone with the new ZSK be visible on all authoritative DNS servers of the zone (zone transfer)
  • Wait for the TTL of the DNSKEY RRset (+ some buffer for security)
  • Now we can be sure the new ZSK DNSKEY record is in all caches (DNS resolvers, operating systems, applications)

10.5.3 ZSK - pre-publication - Step 3

  • Sign the zone with the new ZSK
  • The new ZSK is now active, the old ZSK is now retired
  • The old ZSK will be kept in the zone for now (it is needed to validate old signatures that still exist in the caches in the network)

10.5.4 ZSK - pre-publication - Step 4

  • Wait for the new zone version with the signatures from the new ZSK to be visible on all authoritative DNS servers of the zone (zone transfer)
  • Wait for the largest TTL in the zone (plus some buffer)
  • Now the signatures created by the old ZSK are expired from the caches, and the new signatures are available

10.5.5 ZSK - pre-publication - Step 5

  • Remove the old ZSK from the DNSKEY record set of the zone
  • Continue signing the zone with the new ZSK

10.5.6 ZSK - pre-publication in pictures

10.6 Exercise: ZSK Rollover

  • In this exercise we will perform a ZSK-Rollover on the manually-signed zone zoneNN.dnslab.org. This will be a pre-publish roll-over.
  • Step 1: create a new ZSK key-pair and note down it's Key-ID
    % cd /etc/bind/keys
    % dnssec-keygen -a RSASHA256 -b 1024 zoneNN.dnslab.org
    
  • Publish the public part of the new key in the zone. Make sure to use >> when using shell redirection.
    % cat KzoneNN.dnslab.org.+008+<ID-of-the-new-ZSK>.key >> /var/named/zoneNN.dnslab.org
    
  • Increment the SOA serial of the zone (or use the Unixtime as the SOA-serial when signing the zone)
  • Sign the zone with the old/current ZSK (to publish the new ZSK)
    % dnssec-signzone -N unixtime -o zoneNN.dnslab.org \
       -k <KSK-private-file> \
       /var/named/zoneNN.dnslab.org  \
       <ZSK-private-file>
    
  • Load the signed zone in the BIND DNS server and check that all secondaries have loaded the new zone (check the SOA serial number)
    % rndc reload
    $ dig zoneNN.dnslab.org +nssearch
    
  • Wait for the TTL of the DNSKEY record-set (60 seconds in this case)
  • Increment the SOA serial of the zone (or use the Unixtime), then sign the zone (without any other change) with the new ZSK
    % dnssec-signzone -N unixtime -o zoneNN.dnslab.org \
        -k <KSK-private-file> \
        /var/named/zoneNN.dnslab.org  \
    	  <NEW-ZSK-private-file>
    
  • Load the signed zone into the BIND 9 DNS server and check that all secondaries have the new zone loaded (check SOA serial)
    % rndc reload
    $ dig zoneNN.dnslab.org +nssearch
    
  • Wait for the largest TTL used in the zone (should be 60 seconds in our case)
  • Remove the old ZSK from the zone file /var/named/zoneNN.dnslab.org, increment the SOA serial and sign the zone with the new ZSK:
    % dnssec-signzone -N unixtime -o zoneNN.dnslab.org \
          -k <KSK-private-file> \
          /var/named/zoneNN.dnslab.org  \
    	    <NEW-ZSK-private-file>
    
  • Load the signed zone into the BIND 9 DNS server and check that all secondaries have the new zone loaded (check SOA serial)
    % rndc reload
    $ dig zoneNN.dnslab.org +nssearch
    
  • Check that the zone still is being DNSSEC validated (AD-Flag!)
    $ dig zoneNN.dnslab.org SOA +dnssec +multi
    
  • This is the end of the ZSK rollover

10.7 KSK Rollover

  • The KSK has a dependency on its DS record in the parent zone
  • For the KSK rollover we will use the 'double-signing' rollover scheme (the DNSKEY record set will get two signatures, from both, old and new, KSK)

10.7.1 KSK - double-signing - Step 1

  • Create a new KSK key pair
  • Publish the DNSKEY record of the new key in the zone
  • Sign the DNSKEY RRset in the zone with both KSKs (old and new)

10.7.2 KSK - double-signing - Step 2

  • Wait until the new zone content with the new KSK is visible on all authoritative DNS server of the zone
  • Wait for the TTL of the DNSKEY RRSet (+ some buffer)
  • The new KSK is now visible to all DNS clients (through DNS resolver caches)

10.7.3 KSK - double-signing - Step 3

  • Send the new DS record to the operator of the parent DNS zone (usually through an API or through an Web-Interface)
  • Wait for the DS record to be updated in the parent zone
  • Wait for the TTL of the DS record in the parent zone (+ some buffer)
  • The new DS record is now visible for all DNS clients

10.7.4 KSK - double-signing - Step 4

  • Remove the old KSK from the DNSKEY record set of the zone
  • Sign the zone with only the new KSK
  • Wait and remove the old DS from the parent zone

10.7.5 KSK - double-signing in pictures

10.8 Exercise: KSK Rollover

  • Use your virtual lab machine, nsNNa.dnslab.org (primary authoritative)
  • Create a new KSK key pair
    % cd /etc/bind/keys
    % dnssec-keygen -a RSASHA256 -b 2048 -f KSK zoneNN.dnslab.org
    
  • Publish the new DNSKEY record in the zone, increment SOA-serial (or use Unixtime), sign the zone with both KSK keys (old and new)
    % cat KzoneNN.dnslab.org.+008+<ID-of-new-KSK>.key >> /var/named/zoneNN.dnslab.org
    % dnssec-signzone -N unixtime -o zoneNN.dnslab.org \
            -k <OLD-KSK-private-file> \
            -k <NEW-KSK-private-file> \
            /var/named/zoneNN.dnslab.org \
            <Current-ZSK-private-file>
    
  • Load zone into the BIND 9 server and verify that the zone still validates (AD-Flag!)
    % rndc reload
    $ dig zoneNN.dnslab.org SOA +dnssec +multi
    
  • Submit the new DS to the parent zone
    % scp dsset-zoneNN.dnslab.org. user@ns01a.dnslab.org:.
    
  • Wait for the new DS record to be in the parent zone
    $ dig zoneNN.dnslab.org DS
    
  • Wait for the TTL of the DS record in the parent zone and the TTL of the DNSKEY record in the zone (whichever is larger)
  • Remove the old KSK DNSKEY record from the zone file, increment the SOA serial (or use the unixtime feature) and sign the zone with only the new KSK and the current ZSK
    % dnssec-signzone -N unixtime -o zoneNN.dnslab.org \
                -k <NEW-KSK-private-file> \
                /var/named/zoneNN.dnslab.org \
                <Current-ZSK-private-file>
    
  • Load the signed zone into the BIND 9 server
    % rndc reload
    
  • Check that the zone still validates (AD-Flag!)
    $ dig zoneNN.dnslab.org SOA +dnssec +multi
    

10.9 Algorithm Rollover

  • An algorithm rollover is used when the DNSSEC key algorithm of the zone needs to be changed
    • e.g. when switching from RSASHA256 to ECDSASHA256
  • During an algorithm rollover, the KSK and ZSK will be changed at the same time using a double-signing rollover scheme
    • During such a roll over, the zone should be monitored for failures and over sized DNS answer messages

10.10 Emergency Rollover Key

  • In an emergency, time is at an essence
  • To save time on an KSK rollover, step one (publication) can be done ahead of time
    • This published extra key is called the standby key
    • It saves time, but makes the DNSKEY RRSet larger
  • The standby key is not used during normal DNSSEC signing operation
  • If there is a need to change the KSK in an emergency, the zone can almost immediately switch over to the standby key
  • The standby key should be replaced (rolled) whenever the production KSK is rolled

11 KSK-2024 Root Zone KSK-Rollover

  • The Key-Signing-Key of the Internet Root Zone will be rolled in October 2026 (for the 2nd time in since the root has been DNSSEC signed).
    • Because this key is the trust-anchor for all of DNSSEC, and the public part or hash of that key has to be present in all DNS-resolver before the roll, special care must be taken by DNS resolver operators.
    • The new KSK2024 key (Key-ID 38696) has been created in April 2024 and has been published in January 2025 inside the root DNS zone:
      $ dig dnskey . +multi
      
      ; <<>> DiG 9.18.41 <<>> dnskey . +multi
      ;; global options: +cmd
      ;; Got answer:
      ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33764
      ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
      
      ;; OPT PSEUDOSECTION:
      ; EDNS: version: 0, flags:; udp: 1232
      ;; QUESTION SECTION:
      ;.			IN DNSKEY
      
      ;; ANSWER SECTION:
      .			77796 IN DNSKEY	257 3 8 (
      				AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTO
      				iW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN
      				7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5
      				LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8
      				efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7
      				pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLY
      				A4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws
      				9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=
      				) ; KSK; alg = RSASHA256 ; key id = 20326
      .			77796 IN DNSKEY	257 3 8 (
      				AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC
      				6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeH
      				spaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vr
      				hbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAx
      				m9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7
      				CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+
      				u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxP
      				vYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc=
      				) ; KSK; alg = RSASHA256 ; key id = 38696
      .			77796 IN DNSKEY	256 3 8 (
      				AwEAAeuS7hMRZ7muj1c/ew2DoavxkBw3jUG5R79pKVDI
      				39fxvlD1HfJYGJERnXuV4SrQfUPzWw/lt5Axb0EqXL/s
      				Q2ZyntVmwQwoSXi2l9smlIKh2UrkTmmozRCPe7GS4fZT
      				E4Ew7AV4YprTLgVmxiGP4unRuXkYOgQJXCIBpVCmEdUl
      				i6X2sm0i5ZilU/Q+rX3RDw+eYPP7K0cJnJ+ZnvQDy14+
      				BFtreWl9enNQljgGpBp26lEp1z7AbvUfzkQNVCVGaM8j
      				EaCSALXiROlwCQMOdj+tpLXFf99kdJnTQw2cpEr1uGs/
      				yENAJpoGhbjZAoIkXzDUBSlfFeYz7FWzH6gIe7M=
      				) ; ZSK; alg = RSASHA256 ; key id = 61809
      
      ;; Query time: 1 msec
      ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
      ;; WHEN: Mon Nov 03 13:57:31 CET 2025
      ;; MSG SIZE  rcvd: 853
      
  • Blog-Post: The 2024-2026 Root Zone KSK Rollover: Initial Observations and Early Trends
  • ICANN KSK Rollover Files https://www.iana.org/dnssec/files
  • RFC 9718 - DNSSEC Trust Anchor Publication for the Root Zone
Event Date Description
Publication 11 January 2025 The successor key was introduced in the DNS root zone.
- 10 February 2025 The successor key should begin to be trusted by resolvers that follow the mechanisms described in RFC5011.
Rollover 11 October 2026 The successor key is scheduled to sign the zone; the current key will not sign the zone. Validating resolvers must have updated trust anchors to continue validating the root zone.

12 DNS and DNSSEC Monitoring

12.1 Why DNSSEC monitoring

  • a DNS infrastructure with DNSSEC signed zones is more fragile
    • more complex configuration
    • most errors are fatal, the zone cannot be resolved anymore (this is a security feature of DNSSEC!)
  • DNSSEC monitoring helps to detect issues before the DNS service is affected

12.2 Monitoring scripts

  • We have compiled 15 essential monitoring test scripts
    • These scripts are simple (Bourne-) shell scripts that should work on any Unix/Linux system (and on Windows 10 with Linux-Sub-System or Windows with Cygwin)
    • The scripts are available in our Github repo at https://github.com/cstrotm/dns-monitoring-scripts
    • Please send pull-requests for fixes and additions
  • The scripts are deliberately simple
  • Each script takes one input parameter
    • The domain-name of a delegated zone
  • The scripts can be used from a cron-job
    • or embedded into an monitoring system.

12.3 DNS-Server tests

  • Test 1 - UDPv4 reachability - test for each authoritative server of the DNS infrastructure
    $ dig -4 test-domain +nssearch
    
  • Test 2 - UDPv6 reachability - test for each authoritative server of the DNS infrastructure that it is reachable over UDP IPv6
    $ dig -6 test-domain +nssearch
    
  • Test 3 - TCPv4 reachability - test for each authoritative server of the DNS infrastructure that it is reachable over TCP IPv4
    $ dig -4 test-domain +tcp +nssearch
    
  • Test 4 - TCPv6 reachability - test for each authoritative server of the DNS infrastructure that it is reachable over TCP IPv6
    $ dig -6 test-domain +tcp +nssearch
    
  • Test 5 - EDNS0 response size: tests that the server signals the correct EDNS0 response size. Size needs to be checked against the local policy. Usually 1220-1232 bytes.
    echo " == #5 - EDNS0 response size == "
    
    err=0
    ednspolicy=1232
    
    dig NS ${1} +short | while read server; do
      echo "Server: ${server} "
      ednsbuf=$(dig @${server} ${1} | grep "; EDNS:" | cut -d " " -f 7)
    
      if [ "${ednsbuf}" -eq "${ednspolicy}" ]; then
        echo " EDNS0-Bufsize is ${ednsbuf}, good "
      else
        err=1
        echo " EDNS0-Bufsize is ${ednsbuf}, out of policy range "
      fi
    done
    
    exit ${err}
    

12.4 DNS-Zone tests

  • Test 6 - test that all authoritative server for a zone respond. Count is tested against the number of delegation authoritative servers for the zone.
    echo " == #6 - IPv4 zone response tests == "
    
    err=0
    # get TLD for the zone
    tld=$(echo ${1} | rev | cut -d'.' -f 1 | rev)
    # pick one TLD auth server
    tldns=$(dig NS ${1}. +short | tail -1)
    # query and count the delegation NS records for the zone
    parentnsnum=$(dig @${tldns} NS ${1} +short | wc -l)
    # query the authoritative DNS servers for the zone
    childnsnum=$(dig -4 ${1} +nssearch | wc -l)
    
    if [ "${parentnsnum}" -eq "${childnsnum}" ]; then
      echo "all authoritative DNS-Server answer"
    else
      err=1
      echo "Error: Mismatch"
      echo "Auth DNS-Servers in Delegation: ${parentnsnum}"
      echo "Auth DNS-Servers in answering: ${childnsnum}"
    fi
    
    exit ${err}
    
  • Test 7 - test that all authoritative server for a zone respond via TCP. Count should be tested against the known good number of authoritative servers for the zone. The return code of the dig command should be checked for errors.
    echo " == #7 - IPv4 (TCP) zone response tests == "
    
    err=0
    # get TLD for the zone
    tld=$(echo ${1} | rev | cut -d'.' -f 1 | rev)
    # pick one TLD auth server
    tldns=$(dig NS ${1}. +short | tail -1)
    # query and count the delegation NS records for the zone
    parentnsnum=$(dig @${tldns} NS ${1} +short | wc -l)
    # query the authoritative DNS servers for the zone
    childnsnum=$(dig -4 ${1} +nssearch +tcp | wc -l)
    
    if [ "${parentnsnum}" -eq "${childnsnum}" ]; then
      echo "all authoritative DNS-Server answer"
    else
      err=1
      echo "Error: Mismatch"
      echo "Auth DNS-Servers in Delegation: ${parentnsnum}"
      echo "Auth DNS-Servers in answering: ${childnsnum}"
    fi
    
    exit ${err}
    
  • Test 8 - test that all authoritative server for a zone have the same SOA serial. The return code of the dig command should be checked for errors.
    dig zone +nssearch
    
    • the SOA serial can be different for short amount of times after an update on the primary (propagation delay during zone transfer)
    • on a test interval of 5 minutes the test should issue a warning if the same SOA difference is seen in two successive tests
    • is the same SOA difference seen after three or more tests, an event of severity ERROR should be generated
  • Test 8 - test that all authoritative server for a zone have the same SOA serial. The return code of the dig command should be checked for errors.
    echo " == #8 - SOA serial == "
    
    err=0
    oldsoaserial="0"
    
    dig ${1} +nssearch | while read serverres; do
      soaserial=$(echo ${serverres} | cut -d ' ' -f 4)
    
      if [ "${oldsoaserial}" -eq "0" ]; then
        oldsoaserial=${soaserial}
      else
        if [ "${oldsoaserial}" -eq "${soaserial}" ]; then
         echo "Match for ${soaserial}"
        else
         err=1
         echo "Mismatch for ${soaserial} != ${oldsoaserial}"
        fi
      fi
    done
    
    exit ${err}
    
  • Test 9 - test for AA-Flag. Repeat this test for each authoritative server for the zone. Each server must respond with an AA-Flag.
    echo " == #9 - AA-Flag == "
    
    err=0
    
    dig NS ${1} +short | while read server; do
      echo "Server: ${server} "
      aaflag=$(dig @${server} ${1} SOA +norec | grep ";; flags" | cut -d " " -f 4 | cut -b 1-2)
    
      if [ "${aaflag}" = "aa" ]; then
        echo " AA-Flag found, good "
      else
        err=1
        echo " no AA-Flag, Server not authoritative "
      fi
    done
    
    exit ${err}
    
  • Test 10 - test for Parent-Child NS-RRset. Tests that the NS-RRset in the parent zone (delegation) matches the NS-RRset in the zone data.
    echo " == #10 - test for Parent-Child NS-RRset == "
    
    if [ "$1" = "" ]; then
      echo "This test fails without param. Exiting..."
      exit 1
    fi
    
    err=0
    # get one authoritative server for the zone
    child_dns=$(dig NS ${1} +short | tail -1)
    # get TLD of Domain
    tld=$(echo ${1} | rev | cut -d'.' -f 1 | rev)
    # get one authoritative server for the TLD
    tldns=$(dig NS ${tld}. +short | tail -1)
    # query the delegation records
    parns=$(dig @${tldns} NS ${1} +norec +noall +authority | grep "IN.*NS" | sort)
    
    while read nsrec; do
      ns=$(echo ${nsrec} | cut -d ' ' -f 5)
      parentns="${parentns} ${ns}"
    done <<EOF
    ${parns}
    EOF
    
    # query the zone records
    childns=$(dig @${child_dns} NS ${1} +short +norec | sort)
    parentns=$(echo ${parentns} | tr ' ' '\n' | sort)
    
    echo "Parent delegation:"
    echo ${parentns}
    echo "Child zonedata:"
    echo ${childns}
    
    if [ "${childns}" = "${parentns}" ]; then
      echo "Parent/Child NS-RRSet matches"
    else
      err=1
      echo "Parent/Child NS-RRSet mismatch"
    fi
    
    exit ${err}
    

12.5 DNSSEC tests

  • Test 11 - test for DNSKEY RRset answer size. The full answer packet of the DNSKEY rrset should be below the IPv6 fragmentation payload limit (1232 byte)
    echo " == #11 - test for DNSKEY RRset answer size == "
    
    err=0
    maxsize=1232
    replysize=$(dig ${1} DNSKEY +dnssec +cd | grep ";; MSG SIZE" | cut -d " " -f 6)
    
    if [ "${replysize}" -le "${maxsize}" ]; then
      echo "Good, DNSKEY RRSet size is ${replysize} which is below or equal to ${maxsize}"
    else
      err=1
      echo "Bad, DNSKEY RRSet size is ${replysize} which is above ${maxsize}"
    fi
    
    exit ${err}
    
  • Test 12 - RRSIG validity: check for the lifetime timestamps of RRSIGs in the zone. This test should be done for every important RRset in the zone (SOA, DNSKEY, MX, A/AAAA)
    dig zone soa +dnssec | egrep "RRSIG.*SOA" | cut -d " " -f 6
    dig zone soa +dnssec | egrep "RRSIG.*SOA" | cut -d " " -f 5
    
  • compare the output with the current system time date "+%Y%m%d%H%M%S"
    1. issue an ERROR event, if the inception time is in the future
    2. issue an ERROR event, if the expiry time is in the past
    3. issue an WARNING event, if the expiry time will be reached in less than 5 days
    4. issue an ERROR event, if the expiry time will be reached in less than 2 days
    echo " == #12 - RRSIG validity == "
    
    if [ "$1" = "" ]; then
      echo "This test fails without param. Exiting..."
      exit 1
    fi
    
    err=0
    today=$(date "+%Y%m%d%H%M%S")
    inception=$(dig ${1} SOA +cd +dnssec | egrep "RRSIG.*SOA" | cut -d " " -f 6)
    expiry=$(dig ${1} SOA +cd +dnssec | egrep "RRSIG.*SOA" | cut -d " " -f 5)
    
    echo "Today    : ${today}"
    echo "Inception: ${inception}"
    echo "Expiry   : ${expiry}"
    
    if [ "${inception}" -gt "${today}" ]; then
      err=1
      echo "ERROR: RRSIG validity (${inception}) is in the future"
    fi
    
    if [ "${expiry}" -lt "${today}" ]; then
      err=1
      echo "ERROR: RRSIG validity (${expiry}) is in the past, DNSSEC signature has expired"
    fi
    
    twodaysahead=$(date +%s)
    twodaysahead=$((${twodaysahead}+172800))
    twodaysahead=$(date -u --date="@${twodaysahead}" "+%Y%m%d%H%M%S")
    
    if [ "${expiry}" -lt "${twodaysahead}" ]; then
      err=1
      echo "ERROR: RRSIG validity (${expiry}) will end in less than two days"
    fi
    
    fivedaysahead=$(date +%s)
    fivedaysahead=$((${fivedaysahead}+432000))
    fivedaysahead=$(date -u --date="@${fivedaysahead}" "+%Y%m%d%H%M%S")
    
    if [ "${expiry}" -lt "${fivedaysahead}" ]; then
      err=1
      echo "WARNING: RRSIG validity (${expiry}) will end in less than five days"
    fi
    
    exit ${err}
    
  • Test 13 - DS Records - test the number and the content of the DS records in the parent zone. Issue a warning when the count or the content changes
    echo " == #13 - DS Records == "
    
    err=0
    
    if [ -f "$0.$1.saved.dscontent" ]; then
      oldds=$(cat $0.$1.saved.dscontent)
      olddscount=$(cat $0.$1.saved.dscount)
    else
      echo "First run. This result won't be meaningful until the next run.";
    fi
    
    ds=$(dig ${1} DS +short)
    echo "${ds}" > $0.$1.saved.dscontent
    
    dscount=$(dig ${1} DS +short | wc -l)
    echo "${dscount}" > $0.$1.saved.dscount
    
    if [ "${ds}" != "${oldds}" ]; then
      err=1
      echo "Warning: DS-Record has changed!"
    else
      echo "OK: DS-Record is the same as last time tested!"
    fi
    
    if [ "${dscount}" != "${olddscount}" ]; then
      err=1
      echo "Warning: number of DS-Record has changed!"
    else
      echo "OK: number of DS-Record is the same as last time tested!"
    fi
    
    exit ${err}
    
  • Test 14 - DS Records and KSK - test that the DS-Record matches the KSK in the zone. The two values (Key-ID) must match.
    echo " == #14 - DS Records and KSK == "
    
    if [ "$1" = "" ]; then
      echo "This test fails without param. Exiting..."
      exit 1
    fi
    
    err=0
    
    dskeyid=$(dig ${1} DS +short +cd | cut -d " " -f 1 | tail -1)
    rrsigkeyid=$(dig ${1} DNSKEY +dnssec +short +cd | egrep "^DNSKEY" | grep "${dskeyid}" | cut -d ' ' -f 7)
    
    if [ "${dskeyid}" != "${rrsigkeyid}" ]; then
      err=1
      echo "Error: Key-Tag of DS-Records does not match the Key-Tag of RRSIG on DNSKEY"
    else
      echo "OK: Key-Tag of DS-Records does match the Key-Tag of RRSIG on DNSKEY"
    fi
    
    exit ${err}
    
  • Test 15 - Count of DNSKEY records in the zone. The number can change during a key-rollover. Any change should create an WARNING event
    echo " == #15 - DNSKEY record count == "
    
    if [ -f "$0.$1.saved.dnskeycount" ]; then
      olddnskeycount=$(cat $0.$1.saved.dnskeycount)
    else
      echo "First run. This result won't be meaningful until the next run.";
    fi
    
    err=0
    dnskeycount=$(dig ${1} DNSKEY +cd +dnssec | egrep "DNSKEY.*2" | grep -v "RRSIG" | wc -l)
    
    echo "${dnskeycount}" > $0.$1.saved.dnskeycount
    
    if [ "${dnskeycount}" != "${olddnskeycount}" ]; then
      err=1
      echo "Warning: Number of DNSKEY-Record has changed!"
    else
      echo "OK: Number of DNSKEY-Record is the same as with last test!"
    fi
    
    exit ${err}
    

12.6 DNSSEC Monitoring tips

  • the DNSSEC monitoring system should write an audit trail of DNSSEC zone changes:
    • changes to the DNSKEY records (KEY-ID and SOA Serial of the change)
    • changes to the DS-Record (KEY-ID and SOA serial of the parent zone)

12.7 DNSSEC Monitoring - tools

12.8 DNS monitoring with Prometheus

Prometheus is a very popular application for event monitoring and alerting. It records metrics in real-time in a time-series database using an HTTP pull model. It's written in Go and is Open Source.

For monitoring BIND, Prometheus requires a so-called exporter which provides metrics which Prometheus consumes, and we'll use bind_exporter for doing so. bind_exporter has to access BIND's metrics which named will make available via its statistics-channels{} feature.

  • Login to your DNS resolver machine (dnsrNNN) and become root
    $ sudo -i
    
  • Ensure BIND is installed and running
    % rndc status
    
  • Run our Prometheus installer script
    % /usr/local/bin/prom-setup
    * Downloading bind_exporter software ..
    * Downloading prometheus software ..
    * Reconfiguring named ..
    * Setting up bind exporter ..
    * Setting up prometheus ..
    * Starting services ..
    Prometheus is running at https://dnsrNNN.dnslab.org:8443/
    
  • Use a Web browser to connect to the displayed URL. Note that this configuration is not ideal as we've purposely done away with any sort of authentication. In a productional environment you will want to add that by default.
  • In the input field which says Expression (press Shift+Enter...) enter the term bind_response_rcodes_total or select that from the dropdown list which appears when you click on the globe on the right of that field.
  • Press Execute and look at the values displayed
  • Query your DNS resolver for existing and non-existing names (purposely cause NXDOMAIN)
dig @localhost dnslab.org a       # NOERROR
dig @localhost xyz.dnslab.org a   # NXDOMAIN
dig @localhost fail02.dnssec.works a  # SERVFAIL
  • Click on Execute and view the new metrics.

13 DNS reverse resolution

  • A-Records and AAAA-Records map domain names to IPv4 and IPv6 addresses
  • Aometimes we want to map IP addresses back to their domain names
  • DNS offers this function, it is called reverse lookup
  • Reverse lookup is optional except where required by protocol (X11 authentication) or custom (Anti-Spam checks for SMTP mail)

13.1 Reverse records

  • For reverse DNS lookup, the IP address must be converted into a domain name (because in DNS the query index is always a domain name)
    • In IP addresses, the hierarchy is from left to right (network part on the left of an IP address, host part on the right)
    • In domain names, the hierarchy is from right to left (Root-Zone and Top-Level domain on the right, host part on the left)
    • To map an IP address to a domain name, we reverse the order of all digits of the address, and add the second level domains in-addr.arpa. (IPv4) or ip6.arpa. (IPv6)
      • For IPv4 = 192.0.2.100 -> 100.2.0.192.in-addr.arpa.
      • For IPv6 = 2001:db8:ff::1 -> 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.F.F.0.0.8.B.D.0.1.0.0.2.IP6.ARPA
    • The domain name for an IP address is stored as a PTR (Pointer) record with the domain name in the record data
132.0.2.192.IN-ADDR.ARPA.    3600 IN PTR www.example.com.

  • arpaname is a BIND tool for generating a PTR RR from an IP address.
    $ arpaname 10.4.13.132
    132.13.4.10.IN-ADDR.ARPA
    $ arpaname 2001:db8:a1:CAFE::fab
    B.A.F.0.0.0.0.0.0.0.0.0.0.0.0.0.E.F.A.C.1.A.0.0.8.B.D.0.1.0.0.2.IP6.ARPA
    
  • dig supports a shortcut notation for reverse lookup queries with the -x switch:
    $ dig -x 192.168.1.36
    
  • is the same as
    $ dig 36.1.168.192.in-addr.arpa PTR
    
  • Reverse domains are delegated from the Regional Internet Registries (RIRs) and Local Internet Registries (LIRs)
RIR Website
APNIC https://apnic.net/
ARIN https://arin.net
RIPE https://ripe.net/
AFRINIC https://afrinic.net/
LACNIC https://www.lacnic.net/
  • You need to request your reverse space be delegated to your authoritative servers by the entity that gave you IP address space (ISP, RIR, LIR etc)

13.2 Exercise

  • Work on the primary authoritative server (nsNNa.dnslab.org)
  • Create a new zone file for the fictional IPv4 network in the picture below 0803-reverse-delegation-lab.png
  • The picture only shows the hostname label of the domain name. You need to add the forward domains name zoneNN.dnslab.org. to the names. Example: Host beta is beta.zoneNN.dnslab.org.. Ignore the "alias" names shown in the picture.
  • The "Home" directory for BIND 9 is /var/named
  • Add a zone block for this network to your BIND 9 configuration file named.conf on nsNNa.
  • bonus: create a zone file and add a zone block for the second network in the picture 10.0.10.in-addr.arpa
  • Check the zonefile and the configuration for errors
  • Reload the BIND 9 DNS server
  • Test if the zone can be resolved
    $ dig @nsNNa.dnslab.org 1.168.192.in-addr.arpa.
    $ dig @nsNNa.dnslab.org 20.1.168.192.in-addr.arpa. PTR
    
  • Can it be reached via delegation?
    $ dig -x 192.168.1.1
    

13.3 Solution (Template)

  • Zonefile for reverse zone for network block 192.168.1.0/24:
    $TTL 60
    $ORIGIN 1.168.192.in-addr.arpa.
    
    ;; the domain names of the authoritative name servers are always in
    ;; a "normal/forward" zone, not in the namespace of a reverse zone!
    
    @               SOA   nsNNa.dnslab.org.    .    1001 1h 30m 40d 60
                    NS    nsNNa.dnslab.org.
    
    ;; the Pointer Records point to the names of the machines
    1               PTR   beta.zoneNN.dnslab.org.
    20              PTR   alpha.zoneNN.dnslab.org.
    25              PTR   delta.zoneNN.dnslab.org.
    100             PTR   gateway.zoneNN.dnslab.org.
    
  • Zone-Block in named.conf
    zone "1.168.192.in-addr.arpa" {
         type primary;
         file "1.168.192.in-addr.arpa";
    };
    

14 Master Zone File Shortcuts

14.1 $ORIGIN

  • $ORIGIN is a variable that is appended to non full qualified domain names (FQDN).
    • It applies to owner names and RDATA name fields.
    • The default $ORIGIN is the name of the zone.
    • @ allows the explicit use of the $ORIGIN value.

1101-shortcuts.png

14.1.1 Example

$ORIGIN zoneNN.dnslab.org.
@          30 IN SOA dns-main hostmaster 5 7200 3600 2592000 600
@          30 IN NS  dns-main
@          30 IN NS  dns2.someotherzone.com.
@          30 IN A   192.0.2.200
dns-main   30 IN A   192.0.2.100
www        30 IN CNAME @

14.1.2 Result in memory

zoneNN.dnslab.org.		   30 IN SOA	 (
                                        dns-main.zoneNN.dnslab.org.
                                        hostmaster.zoneNN.dnslab.org.
                                        5 7200 3600 2592000 600 )
zoneNN.dnslab.org.		   30 IN NS      dns2.someotherzone.com.
zoneNN.dnslab.org.		   30 IN NS      dns-main.zoneNN.dnslab.org.
zoneNN.dnslab.org.                30 IN A       192.0.2.200
dns-main.zoneNN.dnslab.org.       30 IN A       192.0.2.100
www.zoneNN.dnslab.org.            30 IN CNAME   zoneNN.dnslab.org.

14.2 Owner Name

  • A RR that begins with a white space inherits the most recently specified owner name.
    • This means that order matters in a zone file.
    • Be careful not to add a new RR with a new name before a RR inheriting its name.
    • A new owner name is always left justified.
    zoneNN.dnslab.org.      30 IN NS   dns2.someotherzone.com.
                             30 IN NS   ns1
                             30 IN A    192.0.2.67
    

14.3 $TTL

  • A RR without a TTL is assigned the zone's default TTL.
    • The default is defined with the $TTL control statement.
    • $TTL can be used multiple times in a zone file.
    • The most recent $TTL is the default.
    $TTL 30
    zoneNN.dnslab.org.      IN NS   dns2.someotherzone.com.
                             IN NS   ns1
                             IN A    192.0.2.67
    

14.4 Owner Name vs. Time to Live

  • Note the different inheritance rules for the Owner Name and the TTL.
    • A RR without an owner name inherits the previous RR's name.
    • A RR without a TTL inherits the zone's default TTL.

14.5 Network Class

  • Without being explicitly assigned, a RR inherits its class from the zone’s definition.
    • For BIND, the definition is in named.conf.
    • IN is the default class. You are unlikely to create zones with any other class.
    @         30 SOA ns1 hostmaster 5 7200 3600 2592000 600
              30 NS  ns1
    ns1       30 A   192.0.2.100
    

14.6 $INCLUDE

  • $INCLUDE reads another file into the zone file.
  • If you have zones with identical data, $INCLUDE lets you avoid recreating and maintaining the same information.
     @         30 SOA ns1 hostmaster 5 7200 3600 2592000 600
               30 NS  ns1
               30 NS  dns2.someotherzone.com.
    ns1       30 A   192.0.2.100
    $INCLUDE "common.rr.txt"
    

14.7 Quiz

  • What is the TTL of each RR?
    $TTL 30
    zoneNN.dnslab.org.      IN NS   dns2.xy.com.
                          45 IN A    192.0.2.44
    zoneNN.dnslab.org.      IN A    192.0.2.67
    
    $TTL 300
    abc                   90 IN AAAA 2001:db8::cafe
                         300 IN AAAA 2001:db8::dead
    def                      IN AAAA 2001:db8::dab
    

14.8 Solution

$TTL 30
zoneNN.dnslab.org. 30 IN NS   dns2.xy.com.
zoneNN.dnslab.org. 45 IN A    192.0.2.44
zoneNN.dnslab.org. 45 IN A    192.0.2.67

$TTL 300
abc                90 IN AAAA 2001:db8::cafe
abc                90 IN AAAA 2001:db8::dead
def               300 IN AAAA 2001:db8::dab

15 Stub zone

  • A stub zone short circuits normal recursion by going directly to an authoritative server for the zone.
  • The authoritative servers (primaries) are specified in the configuration, and should match the zones' NS RRs.
  • A primaries is used only to retrieve the actual NS RRs, and glue RRs, if necessary.
  • The actual NSs are then used for resolution.
  • When the NS RRSet's TTL expires, the NS RRSet is pulled again.
    • This keeps the resolver's information for the zone up to date.
  • Stub zones keep normal name resolution intact, and are less likely to fail when NS names or their addresses change.
  • A stub zone is similar to a hint zone, but a hint zone is limited to reaching the root zone's authoritative servers.
  • A stub zone is similar to a secondary zone, except it replicates only the NS RRs, not the entire zone.

15.1 An example stub zone configuration

  • stub zones are configured in the named.conf of a DNS resolver
  • the backup file is optional and will be created
    zone "private.dns.zone.example" {
      type stub;
      primaries { <ip-addresses-of-primaries>; };
      file "private.dns.zone.example.stubzone";
    };
    

15.2 Exercise

  • Switch to work on the 2nd DNS Server nsNNb.dnslab.org
  • Install BIND 9 and configure the BIND server as a DNS resolver (default config should work) dnf install bind
  • Our zone reverse zone on nsNNa.dnslab.org is currently not reachable from the DNS resolver
    • because it is not delegated from the root DNS zone down
  • Add a stub zone for the reverse zone we've created on the authoritative servers (file /etc/named.conf):
    zone "1.168.192.in-addr.arpa" {
      type stub;
      primaries { <ip-addresses-of-primaries>; }; // address of nsNNa
      file "reverse.stubzone";
    };
    
  • Check and reload the configuration
  • Check that the backup file of the stub-zone is created
    % cat /var/named/reverse.stubzone
    $ORIGIN .
    $TTL 60	; 1 minute
    [..]
    
  • You should now be able to directly resolve records inside this zone via the resolver nsNNb.dnslab.org
    $ dig @localhost -x 192.168.1.20
    

16 Forwarding

  • The standard recursive process sends iterative queries (RD=0) to authoritative servers and follows referrals.
  • Most DNS resolver servers support an alternate form of resolution, forwarding.
    • When configured to use forwarders, a resolver first checks its cache for the answer.
    • If the answer is not cached, the DNS resolver server recursively queries (RD=0) a forwarder (another resolver).

16.1 Forwarding Advantages

  • If multiple resolvers use a forwarder, they benefit from the forwarder's cache.
  • If the forwarder has better Internet connectivity than a resolver using it, the resolver benefits again.
    • This is particularly applicable for resolvers blocked by firewalls from reaching authoritative servers.

16.2 Forwarding Disadvantages

  • Forwarding architectures that depend on a small number of forwards are brittle.
  • Forwarding intercepts the standard resolution process and is harder to troubleshoot.
  • Forwarding configuration is not replicated by zone transfer, where normal delegation is (named.conf vs. zone data information).
    • Forwarding must be configured on each resolver using it.

16.3 Configuring Global Forwarding

  • If all forwarders fail, a DNS resolver server resolves normally (forward first mode).
  • forward only; completely disables normal resolution. The default is forward first;
  • If no forwarder returns an answer, the resolver returns: SERVFAIL
options {
  forwarders { <IP address>; <...> };
  forward only;   # The server can no longer be accurately called recursive!
};

16.4 Forward Zones / conditional forwarding

  • A forward zone configures the resolver to forward for one domain.
    • The domain "." is the equivalent of global forwarding.
    • Remaining queries are through the normal recursive process.
    • They are used primarily in intranets, were introduced in BIND 9.1, and are known as conditional forward in Microsoft DNS (introduced in Windows Server 2003).

16.5 Forward Zone Misuse

  • A forward zone should be directed to a recursive server that can resolve for the specified domain.
  • However, a forward zone is often directly to the authoritative server of the zone.
    • Before stub zones were introduced, this was reasonable.
    • Today, stub zones are the best way to redirect to an authoritative server.

16.6 Forward Zones example

zone "example.com." {
     type forward;
     forwarders { 192.0.2.110; 192.0.2.120; };
};
  • Forward zones apply to queries ending in the specified domain name.
  • Queries for sub.example.com and ab.de.fg.example.com would be forwarded.

16.7 Forwarding in action

Note: In this example the DNS resolver points the forward configuration towards authoritative server. While this is bad use of forwarding, it is common in practice

16.7.1 Exercise

  • Work on the DNS resolver machine nsNNb.dnslab.org
  • Configure a forwarding (forward only) to 2 (!) upstream DNS resolver from Quad9 (https://www.quad9.net) for the domain name dnslab.org (and everything below)
  • Check and reload the BIND 9 configuration
  • Run tcpdump in a separate terminal window (or use tmux) to observe the DNS queries going out from the server machine. Send test queries for dnslab.org and other domains. Validate that the requests for dnslab.org are being send to Quad9.

16.7.2 Solution

  • BIND 9 configuration
zone "dnslab.org" {
  type forward;
  forwarders { 9.9.9.9; 149.112.112.112; };
  forward only;
};
  • tcpdump
% tcpdump port 53 and host 9.9.9.9 or host 149.112.112.112
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:34:03.721440 IP dnsrNN.dnslab.org.31778 > dns9.quad9.net.domain: 30694+% [1au] DS? www.dnslab.org. (45)
15:34:03.733552 IP dns9.quad9.net.domain > dnsrNN.dnslab.org.31778: 30694$ 0/4/1 (500)
15:34:03.733852 IP dnsrNN.dnslab.org.18160 > dns9.quad9.net.domain: 23994+% [1au] DNSKEY? dnslab.org. (41)
15:34:03.742156 IP dns9.quad9.net.domain > dnsrNN.dnslab.org.18160: 23994$ 3/0/1 DNSKEY, DNSKEY, RRSIG (765)
15:34:03.742854 IP dnsrNN.dnslab.org.22697 > dns9.quad9.net.domain: 57733+% [1au] A? www.dnslab.org. (45)
15:34:03.929210 IP dns9.quad9.net.domain > dnsrNN.dnslab.org.22697: 57733$ 2/0/1 A 188.166.104.92, RRSIG (233)
  • DNS Query to test the forward name resolution:
dig @localhost www.dnslab.org A