DNSSEC
SixXS allows you to sign your reverse zones with DNSSEC, utilizing DLV from ISC anchor.
Once you have zones signed and updated across primary/secondary servers, you can add delegate record to reverse zone.
Contents
Howto: Signing your zones with LDNS toolkit
!!! NOTE: When using DNSSEC domain case does matter: zone in uppercase will not pass some validators (i.e. dlv.isc.org) which are using canonical (lowercase) names. !!!
Signing script
Below script can be used to simplify zone signing or to understand the process:
#!/bin/bash # Input parameters ZONE=$1 FILE=$2 # Ok, but I'm always using $ORIGIN at the beginning of the zone, so why bother if [ -z $FILE ] then FILE=$ZONE ZONE=$(head -5 $FILE | awk '/^\$ORIGIN /{print$2}' | sed 's/\.$//') fi # Checking existing keys - keys should be at least one year old KSK=$(find . -name "K$ZONE.+0*+*.key" -mtime -365 -exec grep -q ksk \{} \; -printf '%T@ %f\n' | sort -rn | head -1 | sed 's/[0-9.]\+ //;s/.key$//') ZSK=$(find . -name "K$ZONE.+0*+*.key" -mtime -365 -exec grep -q zsk \{} \; -printf '%T@ %f\n' | sort -rn | head -1 | sed 's/[0-9.]\+ //;s/.key$//') # If there're no suitable keys if [ "x" = "x$KSK" -o "x" = "x$ZSK" ] then # Generating new keys echo "No valid keys found, generating new set for $ZONE" KSK=$(ldns-keygen -a ECDSAP256SHA256 -k $ZONE) ZSK=$(ldns-keygen -a ECDSAP256SHA256 $ZONE) # Adding keys to zone echo "Adding keys to zone file $FILE" echo "\$INCLUDE \"$PWD/$KSK.key\"" >> $FILE echo "\$INCLUDE \"$PWD/$ZSK.key\"" >> $FILE # Calculating expiration date EXP=$(date '+%Y%m%d' -d 'next year + 5 day') else echo "Found existing keys $KSK & $ZSK, proceeding" # Key file mtime in secs since epoch + number of seconds in 370 days EXP=$( date '+%Y%m%d' -d @$(( `stat -c '%Y' $KSK.key` + 31968000 )) ) #EXP=$( date '+%Y%m%d' -d @$(( `stat -c '%Y' $KSK.key` + 31643326 )) ) fi # Checking serial: Unsigned zone should have comment '; serial' next to serial # Signed zone will have SOA in one line with full spec (name class type params) OLDSER=$( awk '/[ \t]+IN[ \t]+SOA[ \t]+/{print$7}' $FILE.signed 2>/dev/null ) SERIAL=$( awk '/; serial/{print$1}' $FILE ) # !!! TODO:We're not following RFC 1982 to check wraps !!! if [ $(( $OLDSER + 0 )) -ge $SERIAL ] then # Incrementing zone's serial echo "Adjusting zone's serial" NEWSER=$(( $SERIAL + 1 )) sed -i "/; serial/s/$SERIAL/$NEWSER/" $FILE fi # Signing zone # !!! TODO: We're not doing key rollover here, just re-signing with new keys !!! echo "Signing zone file $FILE with keys $KSK & $ZSK untill $EXP" ldns-signzone $FILE $KSK $ZSK -n -e $EXP
Signing Makefile
The below Makefile is created for NSD daemon, however it should not be difficult to adopt it for other daemons.
BINHOME=$(PWD) BINPROG=sh $(BINHOME)/dnsec DNSHOME=/etc/nsd ZONES:=$(wildcard $(DNSHOME)/*.signed) VPATH=$(DNSHOME) NSDC=nsd-control all: /var/lib/nsd/nsd.db /var/lib/nsd/nsd.db: $(ZONES) $(NSDC) reload $(NSDC) notify %.zone.signed: %.zone $(BINPROG) $?
Putting everything together
root@ruff:~/dnssec# make sh ~/dnssec/dnsec /etc/nsd3/2001.db8.1f15.1b0a.rev.zone Found existing keys Ka.0.b.1.5.1.f.1.8.b.d.0.1.0.0.2.ip6.arpa.+007+09693 & Ka.0.b.1.5.1.f.1.8.b.d.0.1.0.0.2.ip6.arpa.+007+08819, proceeding Adjusting zone's serial Signing zone file /etc/nsd3/2001.db8.1f15.1b0a.he.rev.zone with keys Ka.0.b.1.5.1.f.1.8.b.d.0.1.0.0.2.ip6.arpa.+007+09693 & Ka.0.b.1.5.1.f.1.8.b.d.0.1.0.0.2.ip6.arpa.+007+08819 until 20120710 sh ~/dnssec/dnsec /etc/nsd3/2001.db8.ff6d.rev.zone Found existing keys Kd.6.f.f.8.b.d.0.1.0.0.2.ip6.arpa.+007+23370 & Kd.6.f.f.8.b.d.0.1.0.0.2.ip6.arpa.+007+48407, proceeding Adjusting zone's serial Signing zone file /etc/nsd3/2001.db8.ff6d.rev.zone with keys Kd.6.f.f.8.b.d.0.1.0.0.2.ip6.arpa.+007+23370 & Kd.6.f.f.8.b.d.0.1.0.0.2.ip6.arpa.+007+48407 until 20120710 sh ~/dnssec/dnsec /etc/nsd3/example.com.zone Found existing keys Kexample.com.+007+21303 & Kexample.com.+007+13910, proceeding Adjusting zone's serial Signing zone file /etc/nsd3/example.com.zone with keys Kexample.com.+007+21303 & Kexample.com.+007+13910 until 20120710 nsdc rebuild nsdc reload root@ruff:~/dnssec# make make: Nothing to be done for `all'. root@ruff:~/dnssec#
---
Setting up DNSSEC/IPv6 enabled recursive cache
I prefer software to be little, light and efficient, and doing precisely what it is intended to do. That's why if I need authoritative IPv6 and DNSSEC enabled DNS server I install NSD rather than BIND, and when I need recursive cache with the same features I install Unbound - from the same vendor btw. As such, when I'm troubleshooting master zones I'm not affecting cache used by my wife to surf her blogs.
Unbound
Server is supplied with extensive config file, where majority of default options are sufficient for normal run. On ubuntu you can install with simpe apt-get install unbound, on gentoo with emerge unbound. On ubuntu server is pre-installed with control certificates, on gentoo with root anchor. Here is configuration sufficient for following features:
- IPv6 socket support
- DNSSEC root anchor support
- DNSSEC DLV support (from dlv.isc.org anchor)
- remote control (unbound-control)
- Forwarding of google to SixXS cache
server: verbosity: 1 interface: 127.0.0.1 interface: ::1 interface: 10.0.0.252 interface: 2001:db8:ff6d:1::1 do-ip4: yes do-ip6: yes do-udp: yes do-tcp: yes access-control: 10.0.0.128/25 allow access-control: 127.0.0.1/8 allow access-control: 2001:db8:ff6d::/48 allow access-control: 2001:db8:ff00:e8::2/128 allow access-control: 0.0.0.0/0 deny access-control: ::0/0 deny chroot: "" auto-trust-anchor-file: "/etc/unbound/root.key" dlv-anchor-file: "dlv.isc.org.key" val-log-level: 2 remote-control: control-enable: yes control-interface: 127.0.0.1 control-interface: ::1 server-key-file: "/etc/unbound/unbound_server.key" server-cert-file: "/etc/unbound/unbound_server.pem" control-key-file: "/etc/unbound/unbound_control.key" control-cert-file: "/etc/unbound/unbound_control.pem" forward-zone: name: "google.com" forward-addr: 2001:b18:0:1000:2e0:81ff:fe61:ae0d forward-addr: 2001:14b8:0:3007::6 forward-addr: 2001:1418:10:2::2 forward-addr: 2001:41e0:ff00::5 forward-addr: 2001:16d8:aaaa:3::2 forward-addr: 2001:7b8:3:4f:202:b3ff:fe46:bec
Now fetch root anchor (unbound-anchor -a "/etc/unbound/root.key"), adjust its permissions (chown unbound "/etc/unbound/root.key"), fetch dlv root anchor (wget http://ftp.isc.org/www/dlv/dlv.isc.org.key -O /etc/unbound/dlv.isc.org.key) and start the server (/etc/init.d/unbound start). Check control tool works:
~# unbound-control status version: 1.4.9 verbosity: 1 threads: 1 modules: 2 [ validator iterator ] uptime: 329051 seconds unbound (pid 6054) is running...
That's it, check google is properly resolving:
~# drill aaaa google.com @::1 ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 48741 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;; google.com. IN AAAA ;; ANSWER SECTION: google.com. 300 IN AAAA 2a00:1450:8007::67 ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ;; Query time: 186 msec ;; SERVER: ::1 ;; WHEN: Wed Jul 13 22:22:04 2011 ;; MSG SIZE rcvd: 56