One important maintenance requirement for DNSSEC is the key rollover of the zone signing key (ZSK). With this procedure a new public/private key pair is used for signing the resource records, of course without any problems for the end user, i.e., no falsified signatures, etc.
In fact it is really simply to rollover the ZSK with BIND. It is almost one single CLI command to generate a new key with certain time ranges. BIND will use the correct keys at the appropriate time automatically. Here we go:
Some Prenotes
It’s all about timing! A new ZSK must be present in the zone before (!) it signs resource records. Likewise it should remain in the zone even after it is not used anymore for some time.
The DNSSEC keys have four main dates stored within them, which are the following:
- Publish: The time at which the key is public available in the zone
- Activate: From this time on it is used to sign RRs
- Inactive: No longer used to sign
- Delete: Removed from the zone
The later on used CLI commands have the following options to specify these dates: -P, -A, -I, and -D, exactly matching the first letter of the descriptions above.
Let’s have a look at a common key rollover timing, i.e., a pre-publish phase of 1 month, while an active time of 3 months, followed by one more month (inactive) before it is deleted:
Note that a new key is published in the last month of the active phase from the predecessor key. This enables all DNS resolvers to see the new key before it is actively used to sign data.
Time values are specified either discrete or with an offset: “Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a ‘+’ or ‘-‘, it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes ‘y’, ‘mo’, ‘w’, ‘d’, ‘h’, or ‘mi’, then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use ‘none’.” (From the dnssec-settime manual.) Also note that all time values are in UTC!
dnssec-settime
To command line tool
dnssec-settimechanges dates of existing keys. In a common scenario you have never rotated your ZSK before. That is: it has no inactive nor delete time set. But to rollover to a new ZSK (created later), the inactive and delete dates must be set. Use the -I and -D options on the existing ZSK key pair, e.g., to set the inactive date 4 month from now, while the delete date to 5 month from now:
dnssec-settime -I +4mo -D +5mo <key>
For example, I started with these values for my first ZSK from
weberdns.deand “cat”ted the result. Note the activate and inactive dates:
weberjoh@jw-vm16-ns0:/etc/bind/keys$ sudo dnssec-settime -I +4mo -D +5mo Kweberdns.de.+008+57909 dnssec-settime: warning: Permissions on the file ./Kweberdns.de.+008+57909.private have changed from 0640 to 0600 as a result of this operation. ./Kweberdns.de.+008+57909.key ./Kweberdns.de.+008+57909.private weberjoh@jw-vm16-ns0:/etc/bind/keys$ cat Kweberdns.de.+008+57909.key ; This is a zone-signing key, keyid 57909, for weberdns.de. ; Created: 20160205194924 (Fri Feb 5 20:49:24 2016) ; Publish: 20160205194924 (Fri Feb 5 20:49:24 2016) ; Activate: 20160205194924 (Fri Feb 5 20:49:24 2016) ; Inactive: 20161001134524 (Sat Oct 1 15:45:24 2016) ; Delete: 20161031134524 (Mon Oct 31 14:45:24 2016) weberdns.de. IN DNSKEY 256 3 8 AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0tOErEc1+To0BG p3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7fWO6Qs+05U6dnf2BGPy91m/4 LHqM+6jzFMMf566GHxuZYB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQb DRlbtNgP
That was the first step. Now let’s continue with the creation of new ZSKs:
dnssec-keygen -S
As in the first post about DNSSEC signing,
dnssec-keygenis used to create the keys. It has the great “-S <key>” option, described as: “Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.” That is: referring to the last key, only the inactive and delete dates must be set to generate a new key, the publish and activate dates are set automatically. If using the “ZSK rollover every 3 month” approach while starting in 4 month from now on with the activation (due to inactivation of the first key with dnssec-settime), the -I and -D values must be incremented by 3, starting with 7 and 8:
weberjoh@jw-vm16-ns0:/etc/bind/keys$ sudo dnssec-keygen -S Kweberdns.de.+008+57909 -I +7mo -D +8mo -r /dev/urandom Generating key pair.....++++++ ....................++++++ Kweberdns.de.+008+26703
That is: this new key
- will be published in 3 months (that is: 1 month before the first key is “inactive”),
- used in 4 month (because the first key is inactive in 4 month),
- inactive in 7 month (set with -I, –> after the usage of 3 months), and
- deleted in 8 month (set with -D, –> 1 month after inactive).
Refer to the timeline figure shown above. It helps!
And then keep on going creating new keys, each one using for 3 month, i.e., increment the I and D times by 3 such as:
sudo dnssec-keygen -S Kweberdns.de.+008+26703 -I +10mo -D +11mo sudo dnssec-keygen -S Kweberdns.de.+008+41295 -I +13mo -D +14mo sudo dnssec-keygen -S Kweberdns.de.+008+61119 -I +16mo -D +17mo
Create as much keys as you want, e.g., for 2-3 years. But NOTE: For the last key you are creating, don’t use the -I and -D options to have a lifetime of forever. This avoids the situation in which no key can be active anymore which would result in falsified (or even no) DNS signatures.
sudo dnssec-keygen -S Kweberdns.de.+008+07401
You should add a big reminder to your calendar to generate more keys when the old ones are inactive!
In my installation of BIND with DNSSEC signing, the *.private files must be readable by the group, so I adjusted the permissions with:
sudo chmod g+r *.private
The final step is to reload the keys for the zone:
sudo rndc loadkeys weberdns.de
Watch out the syslog entries whether BIND accepts and uses them, such as:
Sep 1 16:11:20 jw-vm16-ns0 named[1720]: received control channel command 'loadkeys weberdns.de' Sep 1 16:11:20 jw-vm16-ns0 named[1720]: zone weberdns.de/IN (signed): reconfiguring zone keys Sep 1 16:11:20 jw-vm16-ns0 named[1720]: zone weberdns.de/IN (signed): next key event: 01-Sep-2016 17:11:20.248
That’s it.
Examples
The following DNSViz graphs and dig listings show the process during my key rollover for weberdns.de. Refer to the descriptions below the graphs for more details:
The same is true if querying the dnskeys with dig. For example, the following listing only shows the first ZSK with id = 57909:
weberjoh@jw-nb12-lx:~$ dig weberdns.de dnskey +multi ; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de dnskey +multi ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54400 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;weberdns.de. IN DNSKEY ;; ANSWER SECTION: weberdns.de. 3591 IN DNSKEY 257 3 8 ( AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpG EDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4Id EmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KC EV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGw O7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGS NwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc 9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWV gemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s= ) ; KSK; alg = RSASHA256; key id = 63202 weberdns.de. 3591 IN DNSKEY 256 3 8 ( AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0t OErEc1+To0BGp3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7 fWO6Qs+05U6dnf2BGPy91m/4LHqM+6jzFMMf566GHxuZ YB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQbDRlbtNgP ) ; ZSK; alg = RSASHA256; key id = 57909 ;; Query time: 1 msec ;; SERVER: 192.168.120.22#53(192.168.120.22) ;; WHEN: Thu Sep 01 16:35:25 CEST 2016 ;; MSG SIZE rcvd: 464
While a few days later the next ZSK with id = 26703 was published:
weberjoh@jw-nb12-lx:~$ dig weberdns.de dnskey +multi ; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de dnskey +multi ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54177 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;weberdns.de. IN DNSKEY ;; ANSWER SECTION: weberdns.de. 3600 IN DNSKEY 257 3 8 ( AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpG EDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4Id EmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KC EV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGw O7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGS NwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc 9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWV gemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s= ) ; KSK; alg = RSASHA256; key id = 63202 weberdns.de. 3600 IN DNSKEY 256 3 8 ( AwEAAdAeTdXab14Qp3A8YjQUhu2DSkJwWC6X6Y8V4O34 UiRAxfXb3Z3zYIeMntyQIgSXrIiY60WW532O21borUfS SReundoZiyq/GBLsPtXL1iQeLXT4QWWg9w2fg3y7Xde5 gzTswXazRIgMX8lqttmfIuZuU9qnWi2OoUCR5Pm2/rdj ) ; ZSK; alg = RSASHA256; key id = 26703 weberdns.de. 3600 IN DNSKEY 256 3 8 ( AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0t OErEc1+To0BGp3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7 fWO6Qs+05U6dnf2BGPy91m/4LHqM+6jzFMMf566GHxuZ YB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQbDRlbtNgP ) ; ZSK; alg = RSASHA256; key id = 57909 ;; Query time: 21 msec ;; SERVER: 192.168.120.22#53(192.168.120.22) ;; WHEN: Sun Sep 04 23:22:17 CEST 2016 ;; MSG SIZE rcvd: 612
How Often?
How often should you rollover your ZSK? Well, it depends. The “use your ZSK for 3 month” opinion is quite conservative from my point of view. We are talking about 2048 bit crypto! This is used within TLS certificates that stay on the Internet for a couple of years.
You should rollover your ZSK on a regular basis to be prepared if your private key got lost. That is: to never rollover your keys is not a good advise. To my mind a good compromise is to rollover the ZSK every 6 month or 12 month. With this regularity you will practise key rollovers at least once a year while you have not that much burden.
Featured image: “Keys” by Rosa Say is licensed under CC BY-NC-ND 2.0.