DNSSEC mit Debian/squeeze: dnssec-tools, bind9
Fangen wir mal so an:
Ich habe in den letzten zwei Wochen sehr sehr viel getestet und mich dann gestern dazu entschlossen, DNSSEC für alle meine privaten Domains live zu stellen. Im folgenden dann kurz - primär für mich als Gedächtnisstützte, aber vielleicht ja auch für andere Leute interessant - die Dokumentation dazu, was ich alles dafür tun musste.
Dokumentation zu DNSSEC gibt es zahlreich, aber sie krankt, ebenso wie die vorhandene Tool-Unterstützung dafür, teilweise sehr in den Bereichein Aktualität oder Zuverlässigkeit. Über Google stolpert man recht schnell über das DNSSEC-HOWTO von nlnetlabs.nl - und wer sich mit DNSSEC noch gar nicht beschäftigt hat, der findet hier einen guten Einstieg. Ebenso empfehlenswert ist dnssec.net, gespickt mit Dutzenden hilfreicher weiterführender Links. Da ich die Umsetzung bei mir mit BIND vorgenommen habe ist es natürlich auch sinnvoll, das Bind 9 Administrator Reference Manual zur Hand zu haben. Den Part der Tool-Unterstützung habe ich mit den DNSSEC-Tools abgedeckt, auch wenn ich eine wenig erfolgreiche Iteration meines Test-Zyklusses mit OpenDNSSEC durchgeführt habe. Und auch mit DNSSEC Look-aside Validation (aka DLV) sollte man sich mal beschäftigt haben .
Zu den Voraussetzungen: Es ist sinnvoll, seine eigene DNS-Infrastruktur zu betreiben (an dieser Stelle mal wieder herzlichen Dank an Andreas Scherbaum, seines Zeichens nicht nur PostgreSQL-Gott, sondern auch Spender des dritten Nameservers für meine Domains). Ebenso ist die Einführung von DNSSEC nichts für Unerfahrene Administratoren, man sollte sich mit DNS, mit Unix und mit Testprozeduren auskennen. Ein dediziertes Test-Lab bietet sich an, in Ermangelung dessen geht natürlich auch eine Sammlung virtueller Maschinen. Und es erfordert einen gewissen Mut, den endgültigen Switchover durchzuführen. Sinnvoll ist ebenso ein Registrar, der die DNS-Keys denn auch bei der Registry hinterlegt, daran arbeite ich gerade - und solange laufe ich via DLV.
Als Scope hatte ich für mich persönlich festgelegt, daß ich keine Software selber installieren und keine Backports durchführen will. Diese Entscheidung hat bei mir dann leider OpenDNSSEC aus dem Rennen geworfen - die Version in Debian/stable hat einfach zu viele Fehler. Das fing damit an, daß der ods-auditor mit meinen DKIM-RRs nicht klargekommen ist und hörte damit auf, daß die signierten Zonen unvollständig waren. Neuere Versionen sind hier bestimmt zuverlässiger, so signiert z.B. ICANN die ip6.arpa-Zone mit einem OpenDNSSEC-Cluster (ok, gut, da war neulich mal Land unter, aber trotzdem) und z.B. auch .fr ist mit OpenDNSSEC verwaltet (schön zu erkennen an den mindestens fünf DNSKEY-RRs in der Zone, KSK live, KSK emergency, ZSK live, ZSK emergency, ZSK prepublish - OpenDNSSEC kann da gierig werden). Ebenso musste ich zkt außen vor lassen. Meine Wahl fiel dann jedoch auf die klassischen dnssec-tools und so war der erste Schritt denn auch die Nachinstallation der benötigten Pakete (bind9 hatte ich natürlich schon):
|
|
Der erste Schritt bestand für mich darin, meinen Nameserver DNSSEC-fähig zu machen. Unter Debian liegt die Konfiguration unter `/etc/bind`. Dort fügt man als erstes drei Zeilen in die Datei `named.conf.options` ein:
|
|
Die erste Zeile bewegt BIND dazu, überhaupt DNSSEC zu sprechen, also z.B. die AD und CD-Flags zu unterstützen. Mit derzweiten Anweisung bringt man BIND dazu, DNS-Antworten zu validieren. Von besonderem Interesse ist die dritte Zeile - mit ihr sagt man BIND nämlich, daß man nicht nur die Trust-Chains von der Root-Zone abwärts benutzen will, sondern aktiviert auch die Nutzung von DLV - z.B. eben wenn die Registriy offiziell noch kein DNSSEC kann bzw. die Zone noch nicht signiert wurde wie in .de oder der Registrar einem DNSSEC nicht anbietet. Innerhalb der DLV-Registry wird dann für jede Zone ein DLV-RR hinterlegt (das ist jetzt nur ein Beispiel, keine Sorge, ihr habt nix vergessen):
|
|
Damit das unter Debian ohne hässliche Fehlermeldungen beim Start des Nameservers
funktioniert, muß man noch eine Zeile an den Anfang der Datei
named.conf.local
anfügen:
|
|
Die zweite Zeile in der named.conf
(dnssec-validation yes;
) habe
ich übrigens nur da drin stehen, weil die Kiste für die VMs als Resolver
auftritt. Das kann ich tun, weil sich meine Clients nicht im geringsten dafür
interessieren, ob AD oder AA gesetzt ist. Würden sie das tun, müsste ich mit
match-recursive-only
und Views in der BIND-Konfiguration arbeiten.
Da ich am Anfang etwas unsicher mit der ganzen DNSSEC-Geschichte war habe ich
mir zusätzlich in der named.conf.local
eine Debugging-Ausgabe für DNSSEC
nach /tmp/dnssec.log
eingerichtet:
|
|
Jetzt wäre dann der richtige Moment, um ein paar Tests durchzuführen und dabei das Debug-Log im Auge zu behalten. Funktioniert alles wie erwartet, kann man die Änderungen auf allen Nameservern, die die eigenen Zonen verwalten, durchführen und auch dort testen.
Bevor man mit dem DNSSEC-Deployment weitermacht, bietet es sich an, sich Gedanken über die Verzeichnisstruktur zu machen, die man einsetzen möchte. Für jede Zone, die man verwaltet, wird es am Ende eine ganze Reihe von Dateien geben:
- Die eigentliche Zonendatei - bei mir einfach wie die Zone benannt, also z.B.
incertum.net
- Die signierte Zonendatei mit der Endung
.signed
, also z.B.incertum.net.signed
- Mindestens drei Schlüsselpaare (private + public) im Format
K$zonename.+$algorithm+$keyid
jeweils mit den Endungen.key
und.private
, also z.B.Kincertum.net.+008+40084.key
undKincertum.net.+008+40084.private
- Eine Datei mit den DS-Records zu Übermittlung an den Registrar/die Registry,
z.B.
dsset-incertum.net
- Ein sogenanntes Key Rollfile, in dem sich die dnssec-tools merken,
wann welcher Schlüssel generiert wurde, wie lang die Signaturen, die damit
erstellt wurden, gültig sind, ob der Schlüssel gerade im Rollover ist etc. Der
Name wäre z.B.
incertum.net.krf
Der Dämon, der die Key-Rollovers (also den Prozess einen neuen Key im DNS
einzufügen und den alten außer Dienst zu nehmen) durchführt, benötigt ebenfalls
eine Steuerdatei (bei mir: all.rollrec
). Das ganze kann dann ungefähr so
aussehen:
|
|
Ich habe den ganzen Kram nach /etc/bind/forward-zones/
gelegt.
Bevor wir die erste Zone mit DNSSEC signieren sollte man noch einen kleinen
Fehler in der Datei /etc/dnssec-tools/dnssec-tools.conf
ausbügeln:
|
|
Jetzt könnte man die erste Zone signieren - und ich weise noch ein allerletztes
Mal drauf hin, daß man die Dokumentation und die Konfigurationsfiles lesen und
verstehen sollte! Das initiale Signieren einer Zone erfordert das manuelle
Generieren von Schlüsseln - 1xKSK, 2xZSK. Übrigens verwenden wir derzeit noch
/dev/urandom
- wenn das bei Euch viele Zonen sind mit vielen Keys, dann
solltet ihr einen irgendeine Hardware benutzen, die Euch Entropy zur Verfügung
stellt, bevor ihr das ändert! Der Aufruf dazu ist - wenn die Zonen-Datei genauso
heißt wie die Zone denkbar einfach:
|
|
Der Aufruf erstellt die Datei incertum.net.signed
- und die KÖNNTE man
jetzt schon in BIND einlesen, allerdings würde ich diesen Schritt erst am Ende
durchführen. Es sollte jetzt auch klar sein, daß sich für die Zukunft der
Workflow für das Ändern von DNS-Einträgen anders darstellt: Man editiert die
Zonendatei, überprüft sie, signiert sie und sagt BIND erst dann, daß man die
Zone gerne neu geladen hätte. Das ist natürlich eine klassische Aufgabe für ein
Makefile
. Es gibt bestimmt elegantere Lösungen, aber für mich
funktioniert:
|
|
Damit kann man dann nach Änderungen an den Zonenfiles einfach ein make
einwerfen und sich freuen. Man bemerkt übrigens, daß hier der Parameter
--genkeys
beim zonesigner
-Aufruf fehlt.
Jetzt wo wir die ersten Zonen signiert haben wäre es an der Zeit, sich die
signierten Zonendateien mal anzusehen. Wir stellen fest, daß sie drei
DNSKEY-Einträge enthalten. Zwei davon sollten in den Flags ein 256 3 8
tragen. Damit sind sie sogenannte Zone Signing Keys, also die Schlüssel
mit denen wir die RRs der Zone signieren, gekennzeichnet. Signaturen die wir
mit diesen Schlüsseln erstellen sind kurzlebig und müssen in sehr regelmäßigen
Abständen getauscht werden. Die von uns verwendete Toolchain verwendet dazu
einen Key-Rollover mit Pre-Publishing - deswegen gibt es zwei ZSKs. Kommt der
Zeitpunkt des Rollovers wird ein neuer Key generiert und der derzeit verwendete
in Ruhestand geschickt - natürlich immer mit Augenmerk auf die TTL der Zone.
Der Key mit den Flags 257 3 8
ist der Key Signing Key oder KSK.
Mit ihm signiert die Toolchain die ZSKs und das ist auch derjenige, der bei der
Registry hinterlegt werden muß (Lemma: Ist die erste Nummer eine Primzahl, so
geht man von einem KSK aus, sonst von einem ZSK. Die zweite Zahl bezeichnet den
Verwendungszweck, 3 steht für DNSSEC. Und die letzte Ziffer bezeichnet den
Algorithmus, hier RSA/SHA-256). Aus all dem folgen zwei wichtige Dinge:
- Man muß Signaturen in regelmäßigen Abständen erneuern.
- Ein ZSK-Rollover ist relativ unkompliziert da ich ihn selbst ausführen kann, bei einem KSK dagegen muß der Registry neues Schlüsselmaterial mitgeteilt werden.
Unsere Toolchain unterstützt uns beim Key-Rollover mit den Tools
rollderd(1p) und
rollctl(1p)
Ersteres ist der Dämon, der die Key-Rollovers automatisch durchführt,
Signaturen erneuert etc., letzteres ist das Control-Programm dafür. Der
rollerd
benötigt eine Steuerdatei, die man mit dem Utility
rollinit
erstellt (die Mailadresse hinter -admin
bitte sinnvoll
setzen!):
|
|
Der Dämon selbst hat kein Init-Skript, ich habe ihn in die /etc/rc.local
verfrachtet und starte ihn dort folgendermaßen:
|
|
Die Logausgaben findet man in der Datei /var/log/dnssec-tools/rollerd.log
.
Als letzte Komponente der Infrastruktur benötigen wir noch ein Tool, das unsere
Zonen im Auge behält. Unsere Toolchain liefert dafür den Donuts Demon
mit (was für ein Name, echt mal…). Auch der
donutsd hat kein
Init-Skript, das ist aber nicht weiter schlimm. Wiederum in der
/etc/rc.local
:
|
|
Das File checkzones.txt
sieht folgendermaßen aus:
|
|
Sollte klar sein, Zonendatei, Zonenname, Kontaktperson. Der Donut kippt Mails
standardmäßig via SMTP auf 127.0.0.1
, Port 25
ein. Das Ding ist recht simpel,
es prüft die Zone und wenn sich die Ausgabe des gegenwärtigen Runs von der
letzten Ausgabe unterscheidet dann schickt er uns eine Mail.
Jetzt haben wir es eigentlich fast geschafft. Bevor wir jedoch Key-Material bei
unserer Registry oder z.B. bei der ISC DLV Registry
einkippen, müssen wir zum einen in der BIND-Konfiguration noch das unsignierte
Zonenfile durch das signierte Zonenfile ersetzen ($serial++
und rndc reload
nicht vergessen!), testen, ob die Key-Rollovers funktionieren (siehe
Link oben zu rollctl
) und mit unserem Registrar den Abstand der
KSK-Rollover (kann man in der dnssec-tools.conf
anpassen) sowie einen
Transportweg des Schlüsselmaterials klären. Und dann, dann ist es auch wirklich
geschafft.
Wisst ihr Bescheid. Ich gehe jetzt das Klavierkonzert Nummer vier von Rachmaninov anhören. Schönen Sonntag noch!
Update 1: Folgende Punkte ergänzt:
- Verwendung von
/dev/urandom
vs./dev/random
- Vermischen von authoritativen Nameservern (geben AA-Bit zurück) und rekursiven Servern (geben AD-Bit zurück).
Update 2 Auf Anregung von Alexander Wirt ein paar Absätze umgebaut und das Makefile
überarbeitet.