About the worst that can happen when you set up an authoritative DNS server to serve DNSSEC-signed data is that the data your systems serve is bogus; this effectively renders your DNS zones unusable, and your customers can't reach your services. The probability of that happening decreases as time goes by, because the signing engines have improved considerably in the last few years, and the quality of the authoritative signing servers is progressively improving. Even so, I'll admit that putting a DNSSEC-signed zone up for the world to see is, at the very least, and exciting procedure.
The guys at NLnetLabs, in particular, I believe, Willem Toorop, have come up with a solution in the form of a proxy server that sits between your signing system and the rest of the world. It's called credns (the artist formerly known as dnssexy) ; there's no Web site for it yet, but Willem gave a presentation of its features recently. (Not to be confused with our dnssexy.net Web site...)
credns, is a bit of a CYA kind of tool, and very useful at that:
credns sits between a (hidden) master signing server and your official Internet-facing slave servers. The master signer is configured to NOTIFY credns when a zone changes. credns transfers the zone and forks a verifier command which checks the validity of the signed zone. If the verifier succeeds, credns "opens a tap" and provides the zone it just transferred to its slaves for publication. In the event the verifier says "no no", the tap remains closed -- the slaves do not get to see the current version of the zone.
This "tap" is controlled by SOA serial numbers seen by credns. The following log snippets obtained from a running credns detail this: in the first run, I ensured the verifier fails. The server sees the NOTIFY, transfers the zone, forks off the verifier which fails, and discards the zone with SOA serial 20, reverting to the previous version (i.e. 19).
info: Zone example.net has changed. error: Zone verifier for zone example.net exited with status: 1 info: Following commit trail for zone example.net to set it to 0 in file /tmp/nsd/var/db/nsd/ixfr.db info: Written 0 on pos 11323 of file /tmp/nsd/var/db/nsd/ixfr.db for zone example.net notice: Zone verifying done... Good: 0, Bad: 1. info: Zone example.net serial 20 is discarded. Reverting to serial 19.
After fixing the zone and bumping the serial number, my master server once again NOTIFYs the credns server which transfers the zone and launches the verifier. The latter succeeds, and credns starts serving serial number 21, thus opening the "tap" for the slaves (on the right of above diagram) to obtain the zone via AXFR.
info: Zone example.net has changed. info: Zone example.net verified successfully. info: Following commit trail for zone example.net to set it to 1 in file /tmp/nsd/var/db/nsd/ixfr.db info: Written 1 on pos 11687 of file /tmp/nsd/var/db/nsd/ixfr.db for zone example.net notice: Zone verifying done... Good: 1, Bad: 0. info: Zone example.net serial 19 is updated to 21.
It is important to note, that the server will not attempt re-transfer of a zone it determined to be bad -- I must bump the serial to have credns re-transfer the zone.
The verifier is a program or script you write yourself. It obtains the zone's content
via stdin (which is what I tested), or it can transfer the zone
from a particular address, to differentiate it from "normal" slaves. If the verifier
program exits with 0, credns considers the zone verified. When using stdin, my
program gets two special environment variables passed to it:
ought to be self-explanatory, and
VERIFY_ZONE=example.net tells me which zone the program must
check. Note, that the zone cannot be modified "in transit": i.e. the verifier program's stdout is discarded.
But how should the verifier actually verify the zone? Several possibilities come to mind, and these can even be combined into a single verifier script to really catch faulty zones:
- use the
ldns-verify-zoneutility from the ldns project.
- OpenDNSSEC has an auditor that could be plugged in.
- Anton Berezin's validns DNS and DNSSEC zone file validator would also do the trick. (Thank you, Paul.)
server: ip-address: 127.0.0.1 ip-address: 192.168.1.218 verifier-count: 1 zone: name: "example.net" zonefile: "example.net.zone" allow-notify: 192.168.1.145 NOKEY request-xfr: 192.168.1.145 NOKEY provide-xfr: 0.0.0.0/0 NOKEY verifier-feed-zone: yes verifier: /usr/local/sbin/jverify
verifier-* options are new:
verifier_countspecifies how many concurrent verifier programs may be launched
verifier-feed-zonespecifies whether or not the verifier program should be fed the zone via stdin.
verifiercontains the program to use and any arguments you want to pass to it.
A few additional options exist to control whether the verifier program will obtain the zone via zone transfer, and if so, the program is given appropriate environment variables. Unless you have a particular reason not to do so, I can't readily think of a reason not to use the stdin method.
credns is still a work in progress, but you can give it a spin by obtaining it from its SVN repository: in the presentation.
It would be good to have a "reference" verifier program/script included with credns, so that we don't all have to re-invent the wheel. Other than that, I believe this is a very nice addition to the DNS software toolkit.