DNSSEC in the .nl zone mini HOWTO. The .nl.nl-experiment.
published in 2003
DNSSEC mini HOWTO⌗
By Paul Wouters (paul@xtdnet.nl)
Introduction⌗
This article is a translation of the article “Secure DNS, Het beveiligingen van DNS in de praktijk that appeared in C’T magazine on March 14 2003.
DNSSEC in the .nl zone⌗
The Dutch NIC (SIDN [http://www.domain-registry.nl/]>), The European Regional Internet Registry (RIPE), and NLnetLabs have created the first toplevel secure DNS. The experiment is running its own set of nameservers to guarantee that the experiment will not interfere with the production nameservers. The project started in November of 2002 with the goal of gaining experience in running DNSSEC for a TLD Registry.
For years, the IETF has been (re)designing the successor of the current DNS system. The new protocols have been changed so often, people began to wonder if it would ever happen at all. One would think that the DNS would have been one of the first protocols to be thoroughly secured. After all, practically all communication on the internet relies on the DNS. A malicious user only needs to manipulate the DNS to get control of the communication.
The standard DNS zonefile of the domain “ct.nl”, with the standard “start of authority” (SOA), nameserver (NS), mail (MX), address (A) and alias (CNAME) resource records (RR’s).
Digital Signature⌗
Standard DNS queries and answers are easily faked. If third parties can observe the DNS traffic of any machine between the enduser and the DNS server that person is using, data can be easily manipulated. DNSSEC solves this problem by using digital signatures for all records. A key-pair is generated, of which the public key is put in the DNS itself, in the form of a KEY record. The private key is then used to digitally sign all records, including the public key record. These signatures are placed in the SIG records. A malicious user can still modify the DNS data, but without the private key, the the corresponding SIG records cannot be recreated to validate the changed records. The tampering will be noticed, and the spoofed DNS answers not believed. The beauty of this setup is that the entire zone can be signed on a very secure machine and then copied onto the nameserver. Even if one has full control of the nameserver, one cannot change any DNS record without breaking the SIG record. An attacker can ofcourse still destroy the nameserver, but at least no one will be tricked to connect to an attacker’s malicious network, even after a nameserver compromise.
The ct.nl zonefile, secured with DNSSEC records. (KEY material shortened for readability).
DNSSEC has another new record type, the NXT record. This record gives us the opportunity to deny the existence of a certain RR. It is not enough to just not have a certain record to make it clear the requested RR doesn’t exist. We have to proof this somehow.
The NXT record for ct.nl shows the existence of the NS, SOA, MX, SIG, KEY and NXT record types. It also tells us that the next RR, in alphabetical order, is going to be www.ct.nl. The NXT record of www.ct.nl shows that there is only a CNAME, SIG and NXT record. And since its NXT record points back to ct.nl, we know it is the last name in the chain. There is no zzz.ct.nl. And all this information was digitally signed. This is the essence of DNSSEC.
But we have a few wrinkles to iron out. The DNS is a hierarchical system. The zone above our zone, the parent zone, has some information about our zone. The nameserver of the parent zone contains nameserver (NS) records to point to the responsible nameservers of its child zones. And if the nameservers of the child zone themselves have names within their own zone (for example when ns.ct.nl is an NS record for ct.nl), then it also needs to pass that information to pass along as well ; the so-called glue records. If someone manages to manipulate those records in our parent zone, then it doesn’t matter how secure our own server is. They will never reach our super-secure nameserver. So this information needs to be signed as well. But our parent doesn’t have our private key, so it cannot sign those records on our behalf. Somehow, we will need to give our parent some information about our key, without turning it over.
The Hint⌗
Of course this problem isn’t new to DNS. The .nl nameserver (ns.nic.nl) already has NS records for our ct.nl zone. In our case these point to ns.xtdnet.nl. However, this answer is given without setting the so-called “authoritative answer” flag. The information is provided “as is”. If we would ask the same question to ns.xtdnet.nl, it would yield the same answer, but this time the “authoritative answer” flag will be set. If ns.xtdnet.nl would give different answer, we would call this a “lame server”. But for DNSSEC, this hint is not enough. After all, anyone can just claim to be an authoritative server. That is why DNSSEC gives a cryptographic hint, the Delegation Signer(DS) record.
The DS record contains the id and the hash of the KEY record of the child-zone. The DS record itself is signed by the parent-zone with a SIG record. To find the ct.nl zone we ask the .nl nameserver for both the NS and DS records. We receive a hint (NS) to use ns.xtdnet.nl as nameserver and a hash of the key (DS) that as far as .nl knows, should have signed the entire ct.nl zone. Then we go to ns.xtdnet.nl and ask for the KEY record of ct.nl. We receive the KEY record, and the signature that belongs to it. We hash the KEY and compare it with the hash in the DS record we received from the .nl nameserver. If they match, we have securely landed at the authoritative nameserver for ct.nl. and we can proceed to ask it about the ct.nl domain. All the answers of ns.xtdnet.nl will be digitally signed, and cannot be tampered with.
Securely resolving www.ct.nl, using the resolv tool made by Miek Gieben.
KEY roll-overs⌗
However, with enough time and cpu-power, all crypto can be broken eventually. That is why it is very important to change your KEY’s regularly. But we cannot just change the key, because then our parent’s DS record will be wrong. So how do we renew our KEY’s without constantly bugging the parent to update the DS record?
The trick is to use two KEY records in our zone, a zone-signing key (ZSK) and a key-signing key (KSK). We sign all KEY records with the KSK, then sign the entire zone with the ZSK. The KSK is the key for which our parent publishes the DS record. The zone-signing key (ZSK) can be relatively small (for instance 768 bits) if we recycle it every month. We can keep the KSK for a year if we make it a bit stronger, for example 2048 bit.
So we get the following path of trust: We trust the KEY of .nl, and thus we trust the NS and DS that ns.nic.nl serves us which, when used, ends us at ns.xtdnet.nl. We verify its KSK with the DS we got, so we trust the KSK which has signed the ZSK, which has signed all the data (RR’s) of which we wanted to know the signed A record www.ct.nl. And we can now recycle the ZSK without notifying the parent. Though of course we just postponed our problem. We still need to recycle the KSK after a year, and we need to securely inform our parent about the new KSK.
To start a roll-over of the KSK we first create another KSK (let’s call it KSK2) and add this third KEY to the zone. Then we can inform the parent (even insecurely!) that there is a new KSK. The parent checks whether its existing KSK (for which it has a DS to verify) has signed the new KSK2. If so, it will update its DS record to point to KSK2. Once we are sure that no cached copies of KSK are scattered around the world, we can remove KSK from our zone. For .nl, NLnetlabs has created such a procedure, SECREG (Secure registration).
From DNS to DNSSEC⌗
Our last problem is that the world will not switch in a single moment from DNS to DNSSEC. So while some subtrees, such as .nl, might have switched, others, most notable the root zone (”.") itself, might still be insecure. The resolve this issue, it is possible to define “secure islands” within a insecure tree. You can define a ’trusted key’ for a particular tree. This is exactly what SIDN has done for .nl
We will now describe how to secure a .nl domain using DNSSEC and SECREG. Obviously, the SECREG part only applies to .nl domains, but you can still read the procedures involved in making any zone secure.
DNSSEC is still a fast moving target. The only software that can be used to create signed zones at this time is the latest snapshot of bind9.
In that snapshot, threading is broken, so you will need to disable that with –disable-threads. Zones signed with the snapshot can however be served by any recent nameserver software package, such as the stable versions of bind8 and bind9 or nsd. The only caveat is when using bind8. If you setup a secure zone, with signatures that are valid for a month, and you forget about your expeirment and let those signatures expire, bind8 will remove the record from the zone. Bind9 will keep serving the expired record, and leave it up to the resolvers querying it to determine whether or not to pass the expired record on to the application.
To not jeopardize the regular operations of the .nl zone, two separate DNSSEC aware CC:TLD nameservers, “bakbeest.sidnl.nl” and “alpha.nlnetlabs.nl” are used. If you want to test secure resolving, be sure to use those two servers instead of the official .nl nameservers. Of course you can also use tools such as dig or resolv.pl manually. If you wish to create your own secure recursing nameserver, you need to run the latest bind9 snapshot and add a trusted-key statement for the .nl key in named.conf:
trusted-keys {
"nl." 256 3 1
"AQOtBQXOH5L/wmOt01PuxXAfSk1bw/dneWPoCyl4yi8tLCjz+DkAs0mzAAvd9XUNpYDaf5KT
ciSs9254oeiE0s0FuYbxS4nm7veZSPCgWoHULFNJtKPNeb4EEblNkAsEGagwQJoIrjlAYKx4C
En3hPwElUlVko23I5tSSPPssxrVnQ==";
};
(The above should be on a single line)
Be aware that using bind9 snapshots will often kill some of the functionality of your nameserver. Do not run this on production servers, unless you know what you’re doing and have extensive monitoring enabled. Even though the development is focused on dnssec, some snapshots also broke normal resolving, so be careful. The next step is to install Net::DNS::SEC from CPAN. Some of the perl scripts we use later on depend on it. Olaf Kolkman of RIPE NCC has written a management-tool that uses it extensively. Such a tool is vital once you start securing many zones. So after we have installed all our software, we’re ready to secure our domain, fnl.nl. Ideally, this would be the time to remove the signing machine from the network, and only connect it to upload the signed zones to the primary nameserver. Other methods would be even better, such as transferring the zones with a USB pen-drive. The security setup of the signer machine is left as exercise for the reader.
We will start by creating the KSK and ZSK:
$ dnssec-keygen -a RSASHA1 -b 2048 -n ZONE fnl.nl
Kfnl.nl.+005+16217
$ nssec-keygen -a RSASHA1 -b 768 -n ZONE fnl.nl
Kfnl.nl.+005+25541
The private keys are in the files with extension .private. The public keys are in the files with extension .key. If you are creating a large amount of keys, you might need to use “-r /dev/urandom”. This random source is slightly less secure, but will not block while you’re waiting for new randomness to appear. It seems that, with Linux at least, the quickest way of getting more random is to move the mouse. Once we’re done with the key-pair creation, we add the KEY records to the zonefile:
$ cat *key >> /var/named/fnl.nl
And after we’ve increased the zone’s serial number, we’re ready to sign the zone:
$ dnssec-signzone -o fnl.nl -k Kfnl.nl.+005+16217.key /var/named/fnl.nl Kfnl.nl.+005+25541.key
We can then copy the zonefile to our primary nameserver and reload the zone:
# rndc reload fnl.nl
(If you use RedHat, you can also use ‘service named restart’)
After a few minutes, your secondary nameservers should also have loaded the new zone. We will use the dig command to verify this. We recommend that people who are used to using the nslookup or the host command really break that habit by now. If you preferred the output of host or nslookup over the output of dig, you can now use the +multiline option to dig (which you can even put in a .digrc file) to get output that is very similar to nslookup or host. To verify if our secondary server received the new zone, we query a key record:
$ dig +dnssec +multiline -t key fnl.nl @ns.xtdnet.nl
We should receive an answer that contains both a KEY and a SIG record. Also take a close look at the “flags” section of the dig output. The Authoritative Answer (aa) flag will say whether or not the nameserver itself was responsible for the zone (authoritative). The Authenticated Data (ad) flag tells us whether our answer was verifiably secure using the dnssec extensions. The above query, contrary to what you might except, did not set the “ad” flag. The reason for this is that the verification of data is done by a resolver, and not by the authoritative server itself. It wouldn’t make much sense to verify the zone on your own disk.
Creating the DS record⌗
When we have our secure zones loaded on our nameservers, we can ask SECREG to vouch for our domainname and request it adds a signed DS record to the .nl zone. We can request this through email (for bulk registrations) or use the web-interface:
Selecting the correct KEY for SECREG.
At this point there is no way that SECREG can determine which key is your ZSK and which is your KSK, though a draft to make a distinction is on its way. If you used a different key-size when generating the keys, you can tell the keys apart by their size. If you used an equal size, you’ll have to check your key id, which is apparent from the filename it uses. Once you’ve told SECREG which key is the KSK, the zone will appear as “processing”.
Registrant and Registrar have two days to cancel the SECREG request.
SECREG decided to add a two day waiting period so that any involved party (Registrant or Registrar) has a chance to decline the request. This is an experimental policy, that might develope into a Best Current Practice (“BCP”). If no one declines the request, your zone will be added to SECREG. The .nl zone is refreshed every weekday between 7am and 11am. This 40 MByte file is then signed by the signing machine, currently a Pentium-III 1Ghz. This process takes about two hours, and when it is done, the file size has grown to 300 Mbyte. SECREG will send emails to the parties involved if it has successfully added a zone, which means adding and signing the DS record for your zone.
The “ad” flag is set. Dig has successfully found the address of our website using DNSSEC.
KSK roll-over⌗
The KSK and ZSK do not have an expire date - only SIG records expire. The ZSK roll-over can be done whenever you want, since the KSK will just sign whatever ZSK you have. So this rollover just consists of deleting the old key, generating a new one, and updating the KEY record in the zone.
The KSK rollover needs to happen in a co-ordinated fashion with the parent, so that the DS record can be updated. First, one needs to create a new KSK:
$ dnssec-keygen -a RSASHA1 -b 2048 -n ZONE fnl.nl
Kfnl.nl.+005+16310
The public KEY record needs to be added to the zone. Assuming the zonefile lives in /var/named/fnl.nl, issue:
$ cat Kfnl.nl.+005+16310.key >> /var/named/fnl.nl
And after we increased the serial, both KSK’s need to sign the KEY records and the ZSK needs to sign the entire zone:
$ dnssec-signzone -o fnl.nl -k Kfnl.nl.+005+16217 -k Kfnl.nl.+005+16310
/var/named/fnl.nl Kfnl.nl.+005+25541
Then we need to propagate the new zone to the primary and secondary nameservers. Then we go back to the SECREG website and choose “rollover”. It will present us with a TXT record containing a random challenge string. This needs to be signed using the sign.pl tool linked on that page, using the OLD KSK.
$ sign.pl
What is the full path to your private key? []
Kfnl.nl.+005+16217.private
What is your domain? []
fnl.nl
Record to sign: []
3600 IN TXT "random txt m80fN0LtmpXz2aQ"
Key path : Kfnl.nl.+005+35861.private
Domain name : fnl.nl
Record to sign : 3600 IN TXT "random txt m80fN0LtmpXz2aQ"
Is this correct (y/n)? y
fnl.nl. 3600 IN SIG TXT 5 2 3600 20030315125047 (
20030213125047 35861 fnl.nl
KHR718ehTtidLkTUbnf+NPPJymSo2jwrWTkPOvjKySFTe
v6tRoCPkvQ2pZxnn7aR3hOCrMAWmwa7WCUJ4GzdPJD2fx
M0zYkH722ewhVmayyZTTgGQ81cpVmbag/95/OR )
Using the sign.pl tool and our old KSK, we have signed the random TXT record as proof that are allowed to do a KSK roll-over.
If the signature is correct, SECREG knows we are the holder of the old KSK key, and that we are authorized to perform a key roll-over. SECREG will update the DS record, which will be published when the .nl zone gets reloaded. Our roll-over is complete.
The old KSK might still be in various caches on the net, so you should at least keep it for as long as its TTL was. Only when that time has past, can the old KSK be removed from the zone. Olaf Kolkman’s maintenance tool does an excellent job of managing these roll-overs.
Conclusion⌗
The Netherlands is the first TLD with a functional DNSSEC registry. One cannot expect to find many programs that already use the extra functionality that DNSSEC offers. Because of the many changes, even very recently, of the DNSSEC protocol, this hasn’t really been possible so far. DNSSEC extensions are also missing from the POSIX libraries, such as the C-library, which means that every program which wants to support DNSSEC needs to write their own dns functions. The first applications to adopt DNSSEC will likely be FreeS/WAN, the most widely deployed Linux IPsec implementation, and OpenSSH. Both tools use public key cryptography, and need to fetch and verify their own application keys. These keys can be put into the DNS, but one can only rely on it if the DNS itself is secure. And the entire situation can become quite complex, as soon as DNSSEC finds it way into DHCP client updates, dynamic dns updates or IPsec opportunistic encryption. And hopefully browsers will also soon understand DNSSEC, so that online banking can implement real DNS security, instead of advising the user “to only continue when the name of our bank appears in the address bar”. We have been waiting for DNSSEC for years. Let’s hope the Dutch SECREG experiment gives everyone a push in the right direction.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.