You need a single small package to perform the following steps: ldns-utils. I guess some system tools can be used to generate most of the things, but as I feel a bit lazy, I used the quick and dirty way to do mine (DS records, ZSK KSK pair, RSASHA1-NSEC3-SHA1 as NSEC3PARAM).
Every information related to DNSSEC principles, fundamentals, and algorithms used can especially be found here (thanks *-pedia and IETF):
This Cloudflare (ARGH!!!) blog entry explains most of these in a general and easy manner:
I created a simple shell script to perform DNSSEC initialization for “w00t.eu.org":
#!/bin/sh # feel free to use $1 to play with multiple domains DOMAIN="w00t.eu.org" ZONEDIR="/var/nsd/zones/master" cd $ZONEDIR export ZSK=`ldns-keygen -a RSASHA1-NSEC3-SHA1 -b 1024 $DOMAIN` export KSK=`ldns-keygen -k -a RSASHA1-NSEC3-SHA1 -b 2048 $DOMAIN` # we don't need static .ds files, we'll generate them using ldns-key2ds rm $ZSK.ds $KSK.ds # now it's time to create the .signed zone file ldns-signzone -n -p -s $(head -n 1000 /dev/random | sha1 | cut -b 1-16) -f $ZONEDIR/$DOMAIN.signed $DOMAIN $ZSK $KSK # and here are our DS records to give to our registrar ldns-key2ds -n -1 $DOMAIN.signed && ldns-key2ds -n -2 $DOMAIN.signed
nb. You only have to run that script once: during the initialization of your zone. Do not forget to make a backup of your KSK/ZSK pair (especially the .private ones, stored somewhere else).
Now that your $DOMAIN.signed file is generated you'll just have to tell to nsd to use it. I did a scp to copy the generated *.key files on the master to the slave one, this step is not needed as the zone file is locally signed on my master server, but I prefer keep my keys backed up, in a “trusted” place. Yes, I have to move the *.private ones in a decent location (eg. not in a location an unprivileged or socket listening program has the right to read to ;-)) - stay tuned for some better security practices of these keys (storing them, manipulating them in my scripts, backing them up…).
And then, let's just set nsd zone settings to use the .signed file on both master and slave name server:
Copy, or (A)XFR to your slaves and nsd-control write:
$ scp -rp /var/nsd/zones/master/* email@example.com:/var/nsd/zones/slave/
/var/nsd/etc/nsd.conf on master:
# on the master zone: name: "w00t.eu.org" zonefile: "master/w00t.eu.org.signed" ...
/var/nsd/etc/nsd.conf on slaves:
# on the slave zone: name: "w00t.eu.org" zonefile: "slave/w00t.eu.org.signed" ...
Now that both of the name servers uses the signed zone file, you will have to set (or ask your registrar to set) the correct DS records, obtained in the last step of the script. But in case you need to get them back, you can do it that way:
cd /var/nsd/zones/master/ ldns-key2ds -n -1 $DOMAIN.signed ldns-key2ds -n -2 $DOMAIN.signed
Depending of the modifications to be propagated, you can play localy on both of your name servers to perform some verifications.
First, take a look at the SOA and ensure the loaded zone is the latest you set:
$ dig w00t.eu.org SOA +short +multiline $ dig w00t.eu.org SOA +short +multiline @an.other.resolver
You should now be able to perform DS, RRSIG, and DNSKEY lookups on both your servers (on even external ones once propagation is done):
$ dig w00t.eu.org DS +short +multiline [@an.other.resolver] ;; Warning, extra type option 65166 7 1 9C741[...] 65166 7 2 CB2FA[...] 4121F8BD $ dig w00t.eu.org DNSKEY +short +multiline [@an.other.resolver] ;; Warning, extra type option 256 3 7 AwEAAd1v0FOamYCTowE[...] 257 3 7 AwEAAaqLcxi48hQGquO[...]
You'd probably also need to ensure that all the DNSSEC chain is valid. I used Verisign Labs one:
Another usefull tool I used, performing kind of a “chain walk”:
For common zone administration (editing / adding / modifying records…) it is always needed to re-sign the updated zone “source file”, so I just follow these steps:
Here are some parts of my “re-signing-after-modification” script:
# feel free to use $1 to play with multiple domains DOMAIN="w00t.eu.org" ZONEDIR="/var/nsd/zones/master" cd $ZONEDIR # let's look at the ZSK and KSK for $DOMAIN KSK=$(basename $(grep -r "`grep '(ksk)' $DOMAIN.signed | cut -f3-10`" K$DOMAIN.*.key | cut -d':' -f1) .key) ZSK=$(basename $(grep -r "`grep '(zsk)' $DOMAIN.signed | cut -f3-10`" K$DOMAIN.*.key | cut -d':' -f1) .key) # now we got the key files to sign with, let's sign the zone file ldns-signzone -n -p -s $(head -n 1000 /dev/random | sha1 | cut -b 1-16) -f $ZONEDIR/$DOMAIN.signed $DOMAIN $ZSK $KSK # almost done! nsd-control reload $DOMAIN nsd-control notify $DOMAIN