You got your domain, what now?
This guide presumes that you got your domain set up in bind and that the configuration is working without DNSSEC configured. My configuration example is for the dnssec.au domain and the zone files are stored in /var/named/primary/ and the DNSSEC keys will be stored in /var/named/keys
Here is my dnssec.au zone file: (ignore the low TTL values)
$ORIGIN .
$TTL 120 ; 2 minutes
dnssec.au IN SOA moss.ih36.net. jalla\.au.contactprivacy.org. (
2022100602 ; serial
1800 ; refresh (30 minutes)
7200 ; retry (2 hours)
345600 ; expire (4 weeks)
60 ; minimum (1 minute)
)
NS moss.ih36.net.
NS brizzy.ih36.net.
NS hamar.ih36.net.
MX 10 helm.hosteng.net.
TXT "v=spf1 include:hosteng.net -all"
CAA 128 issue "letsencrypt.org"
$ORIGIN dnssec.au.
_dmarc TXT "v=DMARC1; p=reject; sp=reject; pct=100; aspf=r; fo=0; rua=mailto:postmaster@dnssec.au"
mail._domainkey CNAME mail._domainkey.hosteng.net.
www CNAME moss.ih36.net.
Here is the relevant part of the named.conf file:
zone "dnssec.au" {
type master;
file "/var/named/master/dnssec.au.DB";
allow-query { any; };
allow-transfer { mysecondaries; };
allow-update { key dhcpd; };
};
Enabling DNSSEC with bind9 is surprisingly easy. You can set up an automated key rotation scheme and bind will do all the hard work for you. All you have to do is to specify the rotation policy and define the key types (Public key type and the hash type and how often you want the keys rotated). Here is my policy:
dnssec-policy my_dnssec_policy {
dnskey-ttl 600;
keys {
ksk lifetime unlimited algorithm ecdsap256sha256;
zsk lifetime 30d algorithm ecdsap256sha256;
};
max-zone-ttl 600;
parent-ds-ttl 600;
parent-propagation-delay 2h;
publish-safety 2h;
retire-safety 2h;
purge-keys 1h;
signatures-refresh 5d;
signatures-validity 15d;
signatures-validity-dnskey 15d;
zone-propagation-delay 2h;
};
This defines a non-expiring key signing key and a zone signing key that is rotated every 30 days. The reason my KSK is set not to expire is that for it to be changed, I have to log into my registrar and update the key hashes in the .au domain. This is easy to do, but it cannot be automated, so I have chosen not to rotate this key automatically. Read the bind documentation for the meaning of the rest of the parameters in the policy or just copy my parameters.
Then all I have to do is to modify the zone definition like this:
zone "dnssec.au" {
type master;
file "/var/named/master/dnssec.au.DB";
allow-query { any; };
allow-transfer { mysecondaries; };
allow-update { key dhcpd; };
# look for dnssec keys here:
key-directory "/var/named/keys/dnssec.au";
# publish and activate dnssec keys:
dnssec-policy my_dnssec_policy;
# use inline signing:
inline-signing yes;
};
That is it. run rndc reconfig to reload the bind configuration and bob’s your uncle. Now you will find the newly generated keys in the directory specified above (/var/named/keys/dnssec.au)
root@moss:/var/named/keys/dnssec.au# ls -l
total 24
-rw-r--r-- 1 bind bind 398 Oct 8 18:54 Kdnssec.au.+013+25892.key
-rw------- 1 bind bind 215 Oct 8 18:54 Kdnssec.au.+013+25892.private
-rw-r--r-- 1 bind bind 569 Oct 8 18:54 Kdnssec.au.+013+25892.state
-rw-r--r-- 1 bind bind 448 Oct 8 18:54 Kdnssec.au.+013+58993.key
-rw------- 1 bind bind 235 Oct 8 18:54 Kdnssec.au.+013+58993.private
-rw-r--r-- 1 bind bind 553 Oct 8 18:54 Kdnssec.au.+013+58993.state
Now to verify that my zone is signed I use https://dnsviz.net/d/dnssec.au to visualize my DNSSEC information. Here is what it shows at this stage in the DNSSEC setup:

This image shows the trust chain for my domain. As you can see my zone is now signed with the KSK id 25892. It has signed the ZSK key id 58993 that has signed the remaining records in the zone. However, there is no trust link from the zone above (.au). So I have to log in to my registrar’s webpage and add two hashes of my KSK key with the ID 25892 to the .au zone. But before that, I have to generate the hashes from my KSK key like this:
root@moss:/var/named/keys/dnssec.au# dnssec-dsfromkey -a sha256 /var/named/keys/dnssec.au/Kdnssec.au.+013+25892
dnssec.au. IN DS 25892 13 2 F27DF44A5CDB057C5F084597244D9C53EAA81989E0463824495B205215B546C6
root@moss:/var/named/keys/dnssec.au# dnssec-dsfromkey -a sha384 /var/named/keys/dnssec.au/Kdnssec.au.+013+25892
dnssec.au. IN DS 25892 13 4 43EF3592F0AD4544733BA892E714F57B4D14F9AF6A96BFA17326AAA359DE80FA41A1D167E40D5A28A609FFDC6E62B94A
Then you have to use the tools your registrar provides for adding DNSSEC records for your zone to its parent zone (.au in my case)

Once I have completed both, it looks like this:

Now I can use https://dnsviz.net/d/dnssec.au to recheck my DNSSEC setup. Remember to use the analyze option to force dnsviz to rebuild its cache for your domain.

As you can see now, there is a trust chain going from the root domain to .au and then to dnssec.au. This means that the DNSSEC configuration is completed. From this point on, you can forget all about DNSSEC and update the zone file as normal. When you reload it bind will sign all the information in it, and the signed zone file will be pushed to your secondary nameservers automatically.
Conclution
This shows all the steps needed to enable DNSSEC for your domain. Doing so will protect you from any unauthorized changes to your zone data in flight to the resolvers that reference your domain.
I hope this information helps you in setting up DNSSEC. I wish I had found this when I started securing my domains.