The Problem
DNSSEC keys are purposely short. They need to fit in a DNS query, which is largely limited to 512 bytes for historical reasons. The relative shortness of the keys (per the algorithm) means it takes a manageable amount of time to break on modern hardware. RSA-768 can be broken in 1500 compute-years on a modern PC. If we throw cloud computing into the mix, something around a quarter to half a million cloud virtual machines could break an RSA-768 key in a day. Using AWS it would cost about $32 million currently. As with all security, you should evaluate your situation to determine the appropriate level of protection necessary: would someone spend $32m just to hack your DNS? Probably not. There are alternatives on the horizon. DNSCurve is a promising example of an ECC upgrade to the DNSSEC principles, but no such proposal is standardized or widely deployed.Longer key lengths take much longer to break. But there are two undeniable facts. First, it's possible for someone with the right resources to break RSA keys in a timespan that might be useful to the attacker. As mentioned above it takes significant resources, well out of the reach of your average hacker, so this is not an imminent problem. Second, computing power is expanding, it will take less and less resources in the future. Quantum computers are not as far off as some people think. Already we have 4-qubit processor, still a far cry from the thousand or so we would need to completely break RSA and ECC. D-Wave is making a slightly different quantum processor, in arrangements up to 512-qubits. Eventually technology will make breaking RSA and ECC trivial, though that is likely decades away still.
The Solution
The immediate and relatively easy solution is to rotate your keys. Even with great advances in technology it will always take time to break a key. Configure your systems to automatically rollover keys now and the worst you will have to do in the intermediate future is change the time period of the rollover. RFC 4641 discusses a couple rollover schemes, but only one resonates with me and applies to most situations - the Pre-Publish Key Rollover (PPKR) scheme.PCN Scheme
I could have picked a shorter time frame, since the "expire" time from the SOA record is only a week I could have used that. This only slightly more complicated, but largely unnecessary. With a 768-bit (or more) ZSK and 2048-bit KSK it should be safe to use the ZSK for a month, and the KSK for a year without any reasonable risk of the keys being broken.
When signing a zone for the first time we will need to generate a current KSK and ZSK similar to what we did in the previous article. In addition we'll need to generate a "next" ZSK and specify the various dates for publishing, activation, inactivation, and deletion. I'm also going to keep all the keys in the default
Creating the initial ZSK
The following is a segment from the script I've been developing to manage DNSSEC key rollovers. The script itself really isn't ready to be released, but I will post it someday when it has a bit more polish.KEYDIR="/etc/namedb/keys" INADATE=`date -v1d -v+1m +%Y%m%d` DELDATE=`date -v1d -v+2m +%Y%m%d` newkey=`dnssec-keygen -a RSASHA1 -b 768 -n ZONE \ -I ${INADATE} \ -D ${DELDATE} \ -K ${KEYDIR} \ ${1}` ln -s ${newkey}.key ${KEYDIR}/K${1}.+ZSK+current.key ln -s ${newkey}.private ${KEYDIR}/K${1}.+ZSK+current.privateWhat the above does... Setting the key directory variable is straight forward. The next two lines compute dates, mainly the Inactivation and Deletion dates for the key. The key's creation, publication, and activation dates will all be set to whatever time you run the command. It then runs the
Creating the "next" ZSK
Creating a new "next" key follows a very similar structure as creating the initial key. The main difference is that we will specify the publication and activation dates so that they coincides exactly with "previous" key's deletion and the "current" key's inactivation dates respectively. Before we generate the new key however, we need to update our symlinks:if [ -f ${KEYDIR}/K${1}.+ZSK+retired.key ]; then rm ${KEYDIR}/K${1}.+ZSK+retired.* fi mv ${KEYDIR}/K${1}.+ZSK+current.key ${KEYDIR}/K${1}.+ZSK+retired.key mv ${KEYDIR}/K${1}.+ZSK+current.private ${KEYDIR}/K${1}.+ZSK+retired.private mv ${KEYDIR}/K${1}.+ZSK+next.key ${KEYDIR}/K${1}.+ZSK+current.key mv ${KEYDIR}/K${1}.+ZSK+next.private ${KEYDIR}/K${1}.+ZSK+current.privateOnce the symlinks are updated we can generate the new "next" key.
PUBDATE=`date -v1d +%Y%m%d` ACTDATE=`date -v1d -v+1m +%Y%m%d` INADATE=`date -v1d -v+2m +%Y%m%d` DELDATE=`date -v1d -v+3m +%Y%m%d` newkey=`dnssec-keygen -a RSASHA1 -b 768 -n ZONE \ -K ${KEYDIR} \ -P ${PUBDATE} \ -A ${ACTDATE} \ -I ${INADATE} \ -D ${DELDATE} \ ${1}` ln -s ${newkey}.key ${KEYDIR}/K${1}.+ZSK+next.key ln -s ${newkey}.private ${KEYDIR}/K${1}.+ZSK+next.privateThis was almost the same procedure as generating the initial key. Note that this relies on being run every month or the dates become invalid (an issue I will address in the script before releasing it).
Signing the Zone
With the above setup (re)signing the zone becomes a one-liner, which I follow with a quick command to let BIND know the zone has changed.dnssec-signzone -S -K ${KEYDIR} -o ${1} -N unixtime ${ZONEDIR}/${1} rndc reload ${1}The
Also, when a new KSK is included in a zone you need to run
BIND's Tools
I don't use BIND's built-in tools at this time. The tools use a number of days exclusively for time frames. You can not specify that the dates should always be the "first day of the month" for example. With all the different numbers of days in each month, you are guaranteed that the effective dates would be a different day of each month with no easily foreseeable repetition. You could write a script that checks if a key interval has expired and needs to be rolled, but then you would have to run this check script every day, or use a system which allows you to schedule in arbitrary increments.Essentially the tools do not fit well with simple cron jobs. This is exactly how I, and many others, will be rolling keys for the near future. In the long term I intend on switching to a system backed by database, hopefully all this can be done through that single storage mechanism, and keeping text files will be a thing of the past. Until then, human readable text files and cron jobs are keeping things running smoothly.
I'll update this at some point in the near future with directions for using the built-in tools. Until then there's always the manpage and the hint: use the