Tweeluik DNSSEC en BIND named

Deel 1: het ondertekenen van de zones

Beheerders die zelf hun DNS -servers onderhouden zullen daarvoor meestal gebruik maken van BIND named. Ondanks dat er de afgelopen jaren enorm veel op internet is gepubliceerd over de configuratie van DNSSEC voor deze DNS-server, blijken de meeste van die pagina's inmiddels verouderd te zijn. Omdat Google vooral achterhaalde informatie opleverde en het al met al toch behoorlijk wat tijd kostte om alle instellingen bij elkaar te scharrelen, zetten we in twee hands-on artikelen de hele configuratie nog eens op een rijtje.

De afgelopen maanden hebben we op DNSSEC.nl vooral veel aandacht besteed aan PowerDNS, een DNS-server van Nederlandse oorsprong. Deze wordt door veel Nederlandse en steeds meer buitenlandse DNS-operators gebruikt, en ondersteunt DNSSEC al vanaf versie 3.0, uitgebracht in 2006.

DNS in eigen beheer

Het leeuwendeel van de 1,4 miljoen .nl-domeinnamen die inmiddels zijn beveiligd wordt beheerd met behulp van PowerDNS. En dat is nog maar het begin, want volgens een schatting van Bert Hubert, de lead developer van deze DNS-server, neemt de top dertig van registrars het beheer van negentig procent van de domeinnamen voor hun rekening.

Naast PowerDNS voor de grote DNS-operators is er natuurlijk BIND named, tegenwoordig onderhouden door het Internet Systems Consortium (ISC). Beheerders die zelf hun DNS-servers onderhouden zullen daarvoor meestal gebruik maken van dit software-pakket, de standaard op alle Unix-achtige platforms.

Vandaar dat we in dit artikel uitgebreid ingaan op de configuratie van DNSSEC voor bind. Hier beperken we ons tot de basis-configuratie van de DNS-server zelf. In een volgend verhaal bouwen we hier op voort met sleutelbeheer, automatische ondertekening en andere beheersaspecten.

Verouderde informatie

Ondanks dat er de afgelopen jaren op internet enorm veel is gepubliceerd over de configuratie van DNSSEC voor BIND named, blijken de meeste van die pagina's inmiddels verouderd te zijn. Zo moesten voordat de root zone ondertekend was de publieke sleutels voor de trust anchors handmatig in de configuratie-file worden opgenomen. Hoewel het inmiddels tweeënhalf jaar geleden is dat de root zone werd ondertekend, is zelfs de DNSSEC-pagina op de site van het ISC nog niet aangepast aan de "nieuwe" situatie.

Verder maken alle voorbeelden gebruik van SHA1, terwijl die hash-methode om veiligheidsredenen inmiddels niet meer gebruikt zou moeten worden. Daarnaast wordt de ondersteuning voor NSEC(3) zelden genoemd. En de publieke sleutels worden vaak nog handmatig aan de zone files toegevoegd, terwijl dnssec-signzone daarvoor inmiddels handige opties biedt.

Juist omdat Google vooral verouderde informatie opleverde en het al met al toch behoorlijk wat tijd kostte om alle instellingen bij elkaar te scharrelen, zetten we in deze twee hands-on artikelen de hele configuratie nog eens op een rijtje. Daarbij hebben we gebruik gemaakt van BIND named versie 9.8.2 op CentOS versie 6.3.

DNS zone file

Uitgangssituatie voor dit artikel is een goed werkende DNS-installatie. Dat wil in dit geval zeggen dat we een zone file hebben voor het domein example.com:

$TTL 1d ; ttl is 1 day
@               IN      SOA     dns1.example.com. dns.example.com. (
                                2012112100      ; serial (date & version)
                                8h              ; refresh every 8 hours
                                20m             ; retry after 20 minutes
                                4w              ; expire after 4 weeks
                                20m             ; negative caching ttl is 20 minutes
                                )

; DNS name servers
                IN      NS      dns1.example.com. ; primary name server
                IN      NS      dns2.example.com. ; secondary name server

; SMTP mail gateways
                IN      MX      10 mx.example.com. ; MX gateway
                IN      MX      100 fallback-mx.example.com. ; fallback MX gateway

; hosts
                IN      A       192.168.129.36 ; server
                IN      AAAA    a022:2f87:1098::2:14 ; server (IPv6)
www             IN      CNAME   example.com. ; WWW server
ftp             IN      CNAME   example.com. ; FTP server
mx              IN      A       192.168.128.34 ; mail gateway
mx              IN      AAAA    a022:2f87:1098::1:6 ; mail gateway (IPv6)
mail            IN      A       192.168.128.35 ; mail server
mail            IN      AAAA    a022:2f87:1098::1:7 ; mail server (IPv6)

; exterior hosts
dns1            IN      A       172.16.64.5 ; primary name server
dns1            IN      AAAA    2f87:a022:0941::8:5 ; fallback mail gateway (IPv6)
dns2            IN      A       172.16.128.6 ; secondary name server
dns2            IN      AAAA    2f87:a022:0941::16:6 ; fallback mail gateway (IPv6)
fallback-mx     IN      A       10.184.172.36 ; fallback mail gateway
fallback-mx     IN      AAAA    0941:20a2:7f34::32:7 ; fallback mail gateway (IPv6)

En dat deze als primary staat geconfigureerd in de file /etc/named.conf:

zone "example.com" {
  type master;
  file "db.example.com";
  };

Generen sleutels

Om te beginnen zetten we DNSSSEC aan in de configuratie file:

dnssec-enable yes;
dnssec-validation auto;
dnssec-lookaside auto;

Vervolgens kunnen we ons eigen domein example.com gaan ondertekenen. Daarvoor moeten we om te beginnen twee sleutelparen (KSK en ZSK) genereren. Voor het KSK-paar gebruiken we het volgende commando:

mkdir -p /etc/bind/keys/
cd /etc/bind/keys/
dnssec-keygen -f KSK -3 -a RSASHA256 -b 2048 -r /dev/random -n ZONE example.com
[root@services]# dnssec-keygen -f KSK -3 -a RSASHA256 -b 2048 -r /dev/random -n ZONE example.com
Generating key pair.....................+......+...................+..........+...+....................+.........+..........+...+.............+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++* ....+.........+.+..+................+..............+...+....+...............+........+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++* 
Kexample.com.+008+07470

We hebben hier gekozen voor het RSASHA256-algoritme: RSA public key cryptografie in combinatie met SHA2 hashing. Deze methode voor digitale handtekeningen is veiliger dan de inmiddels verouderde RSASHA1-combinatie (de default-waarde) die in bijna alle online handleidingen wordt aangeraden. De SHA1 hash functie (Secure Hash Standard) heeft over de laatste jaren zijn betrouwbaarheid verloren en wordt inmiddels afgeraden voor gebruik in nieuwe toepassingen. Hoewel RSASHA256 op dit moment de de facto standaard is, wordt het DSA-algoritme (Digital Signature Algorithm) — dat eveneens gebruik maakt van SHA2 — inmiddels ook voldoende ondersteund om deze voor DNSSEC te kunnen gebruiken.

De '-3' optie zorgt ervoor dat een variant van het crypto-algoritme wordt geselecteerd die compatible is met de NSEC3-standaard (DNSSEC Hashed Authenticated Denial of Existence). Daarmee kunnen ook ondertekende antwoorden worden teruggestuurd als een naam niet gevonden is, zonder dat alle adressen binnen een domein op die manier kunnen worden afgelopen en geïnventariseerd (name walking).

De '-n ZONE' optie (tevens de default-waarde) geeft aan wat het type van de sleutels moet zijn. In dit geval willen we een zone ondertekenen en vragen we op deze manier om een DNSKEY.

Voor het genereren van het ZSK-sleutelpaar gebruiken we een vergelijkbaar commando, maar nu zonder de '-f KSK' optie:

dnssec-keygen -3 -a RSASHA256 -b 1024 -r /dev/random -n ZONE example.com
[root@services]# dnssec-keygen -3 -a RSASHA256 -b 1024 -r /dev/random -n ZONE example.com
Generating key pair....+..+....+..+................+....+++++++++++++++++++++++++++++++++++++++++++++++++++* .+........+.+...+...+..........+..........+....+...........+.......+.+.......................................+...+.......+.....+.........................+..+........+..........+........+........+++++++++++++++++++++++++++++++++++++++++++++++++++* 
Kexample.com.+008+32165

We hebben bij het genereren van beide sleutelparen gekozen voor de pseudo-random generator /dev/random. Vooral op een machine waar maar weinig gebeurt kan het zijn dat deze generator erg langzaam is omdat er op dat moment te weinig random bits beschikbaar zijn. Een alternatief is de /dev/urandom generator; deze wacht niet tot er voldoende bits beschikbaar zijn maar levert in dat geval bit strings met minder "entropie" (randomness). Dat resulteert dus in een onveilig sleutelpaar. Voor productie-systemen wordt dan ook aangeraden altijd de '-r /dev/random' optie te gebruiken.

Tenslotte nog iets over de naamgeving van de bestanden: de '+008' staat voor het gebruikte crypto-algoritme. Het andere getal is de key indentifier, niet meer dan een nummer om de verschillende sleutels uit elkaar te kunnen houden. Om te zien welke sleutels nu bij de KSK horen en welke bij de ZSK moeten we in het bestand zelf kijken. De DNSKEY records gebruiken de nummers 256 en 257 om respectievelijk de ZSK en KSK aan te duiden.

Ondertekening zone file

De verschillende sleutels staan nu in vier verschillende files in de directory /etc/bind/keys/:

Kexample.com.+008+06786.key
Kexample.com.+008+06786.private
Kexample.com.+008+44549.key
Kexample.com.+008+44549.private

Voorheen moesten de publieke sleutels (de key files) "handmatig" worden toegevoegd aan de zone file voordat deze werd ondertekend. Inmiddels kan de locatie van de sleutels bij het tekenen als optie worden meegegeven (de '-S -K' opties voor "smart signing"), zodat de originele zone file intact kan blijven.

Voor het ondertekenen van de zone file db.example.com gebruiken we het volgende commando:

dnssec-signzone -S -K /etc/bind/keys/ -g -a -r /dev/random -o example.com db.example.com
[root@services]# dnssec-signzone -S -K /etc/bind/keys/ -g -a -r /dev/random -o example.com db.example.com
Fetching ZSK 6786/RSASHA256 from key repository.
Fetching KSK 44549/RSASHA256 from key repository.
Verifying the zone using the following algorithms: RSASHA256.
Zone signing complete:
Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                      ZSKs: 1 active, 0 stand-by, 0 revoked
db.example.com.signed

De '-a' optie zorgt ervoor dat de gegenereerde handtekeningen gelijk ook geverifieerd worden.

Naast de ondertekende zone file is er (als gevolg van de '-g' optie) ook een bestand met de naam dsset-example.com. gegenereerd. Dat bevat de DS records (uittreksels van sleutels) die in de bovenliggende zone in de domeinnamen-hiërarchie moeten worden opgenomen.

example.com.    IN DS 44549 6 1 CF7BB92480621D205E189E0D62019CD38572C6A6
example.com.    IN DS 44549 6 2 8C775F7FA1E68D103718F28FDA7A2D0D21DFBDB4A4DA26E42A20544D 3D32594F

De laatste, die met "Digest type" 2, is het KSK uittreksel dat naar de registrar geupload moeten worden. SIDN gebruikt daarvoor echter de DNSKEY records, dus voor .nl-domeinen zijn de dsset-bestanden niet nodig.

Als de registrar en internet service provider DNSSEC ondersteunen, kun je voor het uploaden van het sleutelmateriaal in de beheer-console terecht.

DNSSEC records

De file db.example.com.signed bevat nu voor elk DNS record een extra RRSIG record waarin de digitale handtekening is geplaatst, en de nieuwe DNSKEY records. Om deze ondertekende zone file in te laden in de BIND named server hoeft alleen de configuratie file /etc/named.conf aangepast te worden en opnieuw ingelezen:

zone "example.com" {
  type master;
  file "db.example.com.signed";
  };
rndc reload

Dit commando kan worden gebruikt om te controleren of de DNSSEC records inderdaad worden opgehoest:

dig @localhost +dnssec example.com
[root@services]# dig @localhost +dnssec example.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.5 <<>> @localhost +dnssec example.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12284
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 11

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;example.com.			IN	A

;; ANSWER SECTION:
example.com.		86400	IN	A	192.168.3.34
example.com.		86400	IN	RRSIG	A 6 2 86400 20121220140826 20121120140826 32165 example.com. CJd9SrpADTsx2VCAsYXUFY+DRy4jPlu/ZXxZSxhh2FjYQZpSRscmYqc=

;; AUTHORITY SECTION:
example.com.		86400	IN	NS	dns2.example.com.
example.com.		86400	IN	NS	dns1.example.com.
example.com.		86400	IN	RRSIG	NS 6 2 86400 20121220140826 20121120140826 32165 example.com. CKYNbGDJxxTmLqhgXOI8UKiD7CtKu7C1gt7sk59lgkQeDKIDb4P5u9o=

;; ADDITIONAL SECTION:
dns1.example.com.	86400	IN	A	192.168.64.106
dns1.example.com.	86400	IN	AAAA	20a2:2f78:1908::1:5
dns2.example.com.	86400	IN	A	192.168.128.110
dns2.example.com.	86400	IN	AAAA	20a2:2f78:1908::f:5
dns1.example.com.	86400	IN	RRSIG	A 6 3 86400 20121220141000 20121120141000 6786 example.com. CLCdC5Rvwi4eaCwoiL5rIngnv0K0/GpqRyalYpLnQyhihG4lchAOouM=
dns1.example.com.	86400	IN	RRSIG	AAAA 6 3 86400 20121220141000 20121120141000 6786 example.com. CMBsu9CRVtH7946xzSQlqZGKipHKPWifnn7DERgCwVaMRPIh8FrIFQw=
dns2.example.com.	86400	IN	RRSIG	A 6 3 86400 20121220141000 20121120141000 6786 example.com. CO67IYVWk4delFLcqpgt0bM3VxB+K/uJJ7nFjciFRU0dayAC6tZ6wTE=
dns2.example.com.	86400	IN	RRSIG	AAAA 6 3 86400 20121220141000 20121120141000 6786 example.com. CMjoC78Rgwm1JcfMc8un7ocC3Gxp1yiqb3d+mRiiugLuOWZruiAmd8I=

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed Nov 21 12:37:12 2012
;; MSG SIZE  rcvd: 825

Beheersaspecten

In dit artikel hebben we ons beperkt tot de configuratie van DNSSEC voor de DNS-server zelf. Het moge duidelijk zijn dat deze handmatige aanpak niet geschikt is voor grotere hoeveelheden domeinnamen en voor het beheer op langere termijn. In het volgende verhaal bouwen we hier op voort met sleutelbeheer, automatische ondertekening en andere beheersaspecten.