Content tagged dnssec

DNSsec-Signaturen überprüfen mit Bind

posted on

Wer einen authoritativen Nameserver betreibt sollte die eigenen Zonen mit DNSsec sichern. Hier zeige ich euch, wie ihr einen rekursiven Nameserver so einrichtet, dass der DNSsec-Signaturen prüft. Was ist der Unterschied? Authoritative Nameserver sorgen beim Besitzer einer Domain, dass diese gefunden werden kann. Rekursive Nameserver suchen für einen Internetanschluss die richtige Verbindung zu fremden Domains.

Warum soll ich DNSsec aktivieren?

Klar gibt es auch immer ein paar Nachteile:

Manche meinen ein weiterer Nachteil sei, dass die Signaturen bei DNSsec nicht im Client sondern im Nameserver des Zugangsproviders geprüft werden. Die Verbindung zwischen Provider-Nameserver und Client sei so nicht geschützt. Dieses Problem lässt sich jedoch leicht dadurch lösen, dass der Client selbst Signaturprüfungen vornimmt. Wenn er das nicht tut, kann man dies nicht dem Protokoll anlasten.

Meiner Ansicht nach überwiegen die Vorteile bei weitem.

Umkonfiguration von Bind

Wir können DNSsec bei der Namensauflösung in bind sehr einfach aktivieren. Im options-Bereich der Konfigurationsdatei müssen nur zwei Zeilen eingetragen werden:

options {
        directory "/var/cache/bind";
        
        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };

        allow-recursion { 127.0.0.1; ::1; };

        dnssec-enable yes;
        dnssec-validation yes;
};

Die Einstellung „dnssec-enable“ aktiviert den grundlegenden Support für DNSsec in Bind. Die Einstellung „dnssec-validation“ aktivert, dass beim Auflösen von Domains die DNSsec-Signaturen mit angefordert und überprüft werden.

Überprüfen, ob eine Domain DNSsec unterstützt

Mit der neuen Konfiguration gehört jede Namensauflösung in eine von zwei Kategorien:

  1. Die aufgelöste Domain ist nicht mit DNSsec geschützt. Das Ergebnis ist nicht sicherer als bisher.
  2. Die aufgelöste Domain ist durch DNSsec geschützt. Das Ergebnis, das wir bekommen, wurde von Bind überprüft. Wenn die Überprüfung fehlschlägt bekommen wir das Ergebnis gar nicht mehr.

Wie können wir feststellen in welchen dieser beiden Fälle eine Namensauflösung gehört? Entweder wir installieren uns ein Plugin in den Webbrowser. Der DNSsec-Status wird dann in der Adressleiste angezeigt. (z.B. hier für Firefox, hier für Chrome und hier für den Internet Explorer).

Auch auf der Kommandozeile können wir eine Domain überprüfen. Wie für alles hat der Befehl dig auch hierfür die passende Option: +dnssec. Der Parameter lässt dig den DNSsec-Status vom Resolver anfordern. Dieser wird dann von dig mit ausgegeben. Im Header wird hierzu das Flag „ad“ angezeigt, wenn die DNSsec-Prüfung erfolgreich war:

# dig switch.ch +dnssec

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> switch.ch +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36976
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 10

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

;; ANSWER SECTION:
switch.ch. 60 IN A 130.59.108.97
[...]
;; Query time: 330 msec
;; SERVER: ::1#53(::1)
;; WHEN: Mon May  6 21:33:12 2013
;; MSG SIZE  rcvd: 1211

Achtung Falle: Wer so testen will, ob die eigene Zone korrekt mit DNSsec gesichert ist, kann falsche Ergebnisse bekommen. Wenn ein Nameserver eine Anfrage zu einer selbst gehosteten Domain beantwortet ist das ad-Flag nie gesetzt. Das liegt daran, dass er in diesem Fall keine Überprüfung der Signaturen durchgeführt hat. Das muss er auch nicht, da er bereits weiß, dass die Daten korrekt sind.

Wollt ihr eure eigene Zone überprüfen? Der öffentliche Nameserver von Google macht das für euch: dig example.com +dnssec @8.8.8.8 (8.8.8.8 ist eine der IP-Adressen unter denen Google öffentliche Nameserver betreibt.)

Mein DNSsec-Setup

posted on

Vor ein paar Tagen habe ich bereits über einen Teil meines Nameserver-Setups mit Bind geschrieben. Ich habe erklärt, wie DDNS mit bind verwendet werden kann um beispielsweise Kunden die Möglichkeit zu geben Änderungen an Ihren Zonen über ein standardisiertes Protokoll durchzuführen oder die sich häufiger ändernde IP des Internetanschlusses zuhause immer aktuell im DNS zu hinterlegen. Dabei habe ich erwähnt, dass ein interessantes Argument für den Einsatz von DDNS zum Updaten von Zonen auch ist, dass bind in diesem Fall sich automatisch darum kümmert diese erneut zu signieren. Wie dieses Setup funktioniert möchte ich in diesem Artikel beschreiben.

Ziele meines Setups

Wenn man versucht etwas kryptografisch abzusichern, dann sollte der erste Schritt immer der gleiche sein. Es ist zu bestimmen, gegen welche Arten von „Angriffen“ man sich schützen möchte. Je nachdem was man sich hier für Vorgaben macht kommt man zu teilweise komplett verschiedenen „optimalen Lösungen“.

In meinem Setup kommt es mir nicht darauf an die höchstmögliche Sicherheit herzustellen. Vielmehr ist das Ziel meines DNSsec-Einsatzes die Grundsicherheit zu erhöhen. Einfache Angriffe mit dem Ziel DNS-Einträge im Cache von DNS-Resolvern zu verfälschen sollen verhindert werden. DNSsec soll bei mir deswegen möglichst breit und damit für alle Zonen verwendet werden. Es ist deshalb wichtig, dass möglichst kein zusätzlicher Aufwand in der Verwaltung der Zonen entsteht oder dieser nur minimal ist.

Indem ich bei meinem Setup die zur Signatur der Zonen genutzten Private-Keys auf meinem Server ablege(n muss), habe ich an einem anderen Punkt jedoch keinen erhöhten Schutz meiner Zonen: wenn es einem Angreifer gelingt durch irgendeine Lücke in meinen DNS-(Master-)Server einzudringen, so kann er Modifikationen an meiner Zone vornehmen und für diese trotzdem eine gültige Signatur erzeugen.

Ein weiterer Punkt bei dem mein Setup keine Verbesserung der Sicherheit bringt ist der Schutz gegen Angriffe, die meine Zonen unerreichbar machen. Es gibt sogar Überlegungen, dass der Einsatz von DNSsec prinzipiell die Sicherheit im Internet gegen DOS-Angriffe vermindert. Bei der DNS Amplification Attack werden DNS-Server genutzt um andere Server mit einem DOS-Angriff zu überziehen. Die Aktivierung von DNSsec vergrößert dabei die Gefahr, dass der eigene DNS-Server hierfür missbraucht wird.

Konfiguration von bind

In diesem Abschnitt erkläre ich welche Änderungen an den Konfigurationsdateien von bind vorgenommen werden müssen, damit die eigenen Zonen signiert ausgeliefert werden. Wie sich zeigen wird ist dies gar nicht viel. Es reichen zwei kleine Änderungen.

Grundsätzliches aktivieren von DNSsec

Damit bind grundsätzlich den Umgang mit DNSsec aktiviert, muss dies in der Konfiguration im options-Abschnitt angegeben werden:

options {
    directory "/var/cache/bind";

    auth-nxdomain no;    # conform to RFC1035
    listen-on-v6 { any; };

    allow-recursion { 127.0.0.1; ::1; };

    dnssec-enable yes;
    dnssec-validation yes;

    allow-transfer {
        key doux.amessage.eu.;
        key eder.amessage.eu.;
    };
};

Zur Aktivierung muss hier einfach der Eintrag „dnssec-enable yes;“ angegeben werden. (Der Eintrag „dnssec-validation yes;“ ist nicht notwendig und auf einem reinen autoritativen Nameserver auch nicht sinnvoll. Der Eintrag ist bei mir nur vorhanden, da ich meinen bind für localhost als recursive DNS-Server nutze.)

Diese Konfigurationsänderung muss sowohl auf dem Master-Nameserver wie auch auf allen Slave-Nameservern erfolgen.

Den einzelnen Zonen mitteilen wo sich die zugehörigen Keys befinden

Die zweite notwendige Änderung ist es, dass die Definition der Zone noch um zwei Zeilen erweitert wird:

zone "mwimmer.com" in {
    auto-dnssec maintain;
    type master;
    notify yes;
    file "/etc/bind/zones/mwimmer.com.zone";
    update-policy {
        grant root.user.invalid.     subdomain mwimmer.com. ANY;
        grant matthias.user.invalid. subdomain mwimmer.com. ANY;
    };
    allow-transfer {
	key root.user.invalid.;
	key doux.amessage.eu.;
        key matthias.user.invalid.;
    };
    key-directory "/etc/bind/keys";
};

Hier habe ich über „auto-dnssec maintain;“ bind mitgeteilt, dass er bei Updates der Zone diese automatisch neu signiert. Außerdem habe ich mit „key-directory "/etc/bind/keys";“ angegeben wo bind nach den notwendigen Private-Keys zur Signatur der Zone sucht. Ohne letzteren Eintrag würde bind in seinem working Directory suchen. Dieses ist auf einem Debian-System (wie man auch im vorherigen Config-Ausschnitt sieht) /var/cache/bind, was für eine Ablage der DNSsec-Keys nicht geeignet ist, da dieses Verzeichnis normalerweise nicht mit gebackupt wird.

Diese Änderung ist nur auf dem Master-Nameserver notwendig.

Einrichten einer Zone

Zum Einrichten einer neuen Zone auf meinem Nameserver erstelle ich hierfür zuerst eine normale, nicht signierte Zonendatei. Außer den Einträgen auto-dnssec und key-directory in der Bind-Konfiguration, die ich sofort mit eintrage, wird die Zone also zuerst vollkommen normal und ohne Signaturen angelegt und mit einem Aufruf von rndc reconfig auch aktiviert. (Wurde die Konfiguration einer bestehenden Zone geändert um beispielsweise bei einer bereits vorhandenen Zone DNSsec nachzurüsten, so muss stattdessen rndc reload benutzt werden.)

Die Zone wird ab diesem moment von bind ausgeliefert, ist aber noch unsigniert. Im nächsten Schritt geht es jetzt also darum die notwendigen DNSsec-Schlüssel zu erzeugen. Es werden hierzu zwei Schlüsselpaare erzeugt. Das eine paar ist der Key-Signing-Key (KSK). Ein Fingerabdruck hiervon sollte soweit möglich später in die übergeordnete Zone hinterlegt werden. Mit diesem Key-Signing-Key wird später von bind das zweite Schlüsselpaar, der sogenannte Zone-Signing-Key (ZSK), unterschrieben. Erst mit dem Zone-Signing-Key werden dann tatsächlich die eigenen Records in der Zone unterschrieben.

Die Erstellung der beiden Schlüsselpaare erfolgt mit dem Tool dnssec-keygen, das Teil der bind-Distribution ist (Debian-Paket: bind9utils):

dnssec-keygen -K /etc/bind/keys -a RSASHA512 -b 2048 -f KSK mwimmer.com
dnssec-keygen -K /etc/bind/keys -a RSASHA512 -b 1024 mwimmer.com

Je nachdem wie viel Entropie auf eurem System vorhanden ist, kann die Erzeugung dieser zwei Schlüsselpaare durchaus mehrere Stunden beanspruchen. Also nicht verzweifeln, wenn lange Zeit nichts vorwärts geht. Am besten startet ihr die Schlüsselerzeugung also in einem screen.

Nach der Erstellung der Schlüsselpaare muss noch sichergestellt werden, dass die Schlüssel von bind gelesen werden können. Da dnssec-keygen den Private-Key nur für den Datei-Owner lesbar macht (Zugriffsrechte „rw-------“) müssen wir auf einem Debian-System die erzeugten Dateien beispielsweise dem User „bind“ zuweisen.

Wenn nun beide Schlüsselpaare erzeugt und für bind lesbar sind, müssen wir bind noch mitteilen, dass er diese Keys ab sofort zur Signatur der Zone verwenden soll: rndc sign mwimmer.com

Voilà: bind liefert ab diesem Moment eine signierte Zone aus und kümmert sich auch darum, wann die Zone neu signiert werden muss.

Signaturen der Zone in der übergeordneten Zone eintragen (lassen)

Damit fremde Nameserver die Signaturen in der Zone prüfen können, müssen diese wissen welche Keys überhaupt berechtigt sind die Zone zu signieren. Bei DNSsec geschieht dies, indem die Signatur(en) des/der berechtigten Keys in die übergeordnete Zone eingetragen werden. Die Keys mit denen ich die Zone „mwimmer.com“ signiere sind entsprechend also in der Zone „com“ eingetragen. Indem die Zone „com“ wiederum selbst signiert ist und deren Schlüssel in der DNS-Root-Zone eingetragen ist usw. reicht es auf anderen Nameservern aus, dass dort nur die gültigen Keys für die Root-Zone eingetragen werden müssen. Die Funktionsweise ist also sehr ähnlich zu der von X.509-Zertifikaten. Auch bei diesen müssen einem Browser nur die Stammzertifikate der Zertifizierungsstellen bekannt.

Wie konkret in die übergeordnete Zone eingetragen wird was die gültigen Key-Signing-Keys sind ist sehr unterschiedlich. Was man allgemein nur sagen kann ist, dass dieser Eintrag über den Registrar erfolgt bei dem man die Domains registriert hat. Ob dieser DNSsec überhaupt unterstützt und wenn ja wie man ihm die Keys bekannt macht, ist von Registrar zu Registrar verschieden.

Ich persönlich habe mir für InterNetX entschieden und bin wegen DNSsec extra zu diesem Provider gewechselt, da meine vorherigen Provider leider alle nicht in der Lage waren DNSsec-Signaturen anzunehmen.

Außerdem ist es auch so, dass noch nicht bei allen Top-Level-Domains überhaupt eine Delegation mit DNSsec möglich ist. Bei den meisten größeren TLDs (z.B. .DE, .com, .net, .org, .eu) ist dies allerdings kein Problem mehr.

Ich möchte euch noch kurz zeigen, wie die Konfiguration der DNSsec-Delegation vom Falle von InterNetX geschieht.

DNSsec bei InterNetX (AutoDNS 3.0)

Hinweis vorweg: DNSsec unterstützt das Eintragen der Fingerprints von DNSsec-Schlüsseln in die übergeordneten Zonen. Wenn man DNSsec benutzen möchte, so muss man die Nameserver jedoch (mit den oben beschriebenen Einstellungen) selbst betreiben. Die Nameserver, die man über den AutoDNS verwalten kann, sind selbst nicht für DNSsec aktiviert.

Damit InterNetX die Signatur des Schlüssels mit dem wir unsere Zonen signieren an die übergeordnete Registry weiter gibt, müssen wir unseren öffentlichen Teil des Key-Signing-Keys bei der jeweiligen Zone hinterlegen. Damit der entsprechende Reiter bei der Zone im AutoDNS erscheint, müssen wir „DNSSEC aktivieren“ in den Einstellungen der Benutzeroberfläche aktivieren.


Grundsätzliches aktivieren von DNSsec in der Oberfläche des AutoDNS 3.0

Nachdem diese Einstellung aktiviert ist, erhalten wir in der Domainverwaltung wenn wir eine Domain bearbeiten einen zusätzlichen Reiter „DNSSEC“:


Reiter „DNSSEC“ in der Oberfläche des AutoDNS 3.0

In diesem Reiter müssen wir den verwendeten Algorithmus unseres Key-Signing-Keys eintragen (in obigem Beispiel haben wir einen RSASHA512-Schlüssel erzeugt, wir wählen also „10 (RSA/SHA-512)“. Außerdem tragen wir den BASE64-enkodierten öffentlichen Schlüssel (public Key) in das darunter stehende Eingabefeld ein. Zu diesem öffentlichen Schlüssel kommen wir am einfachsten, wenn wir unseren Nameserver fragen:

dig mwimmer.com DNSKEY | grep 257

Hinweis: Ich habe die Erfahrung gemacht, dass es mit AutoDNS 3.0 bei DE-Domains nicht funktioniert, wenn ich den DNSsec-Schlüssel bereits bei der Registrierung mit angebe. Die Domain wird dann zwar registriert, aber der Fingerprint des DNSsec-Keys nicht mit eingetragen. Ich habe mir deswegen auch bei der Registrierung angewöhnt diese zuerst ohne DNSsec durchzuführen und wenn sie fertig ist, bearbeite ich die Zone nochmals und trage die DNSsec-Einstellungen im AutoDNS 3.0 nach.

DDNS mit Bind einrichten

posted on

Der Nameserver Bind bringt von Hause aus die Möglichkeit mit, dass Änderungen in Zonen dynamisch durchgeführt werden können. Dies kann zum Beispiel genutzt werden um selbst etwas wie DynDNS zu realisieren. In der Tat nennt sich das was Bind da implementiert auch DDNS. Spezifiziert ist das Protokoll in RFC 2136: Dynamic Updates in the Domain Name System (DNS UPDATE).

Da ich heute eh den größten Teil dieses Textes als Mini-HOWTO für einen Kollegen geschrieben habe, möchte ich ihn auch hier auf meinem Weblog für andere zur Verfügung stellen. Alle hier verwendeten Befehle sind Befehle von Bind. Unter Debian sind diese Utility-Befehle im Paket dnsutils verpackt. Aktuell benutze ich die Version 9.8.4 von Bind.

Ich zeige in diesem Artikel:

  1. wie man einen kryptografischen Schlüssel zur Sicherung des Zugriffs erstellt,
  2. wie die Konfiguration von Bind angepasst wird,
  3. wie dynamische Updates an Bind geschickt werden und
  4. was zu beachten ist, wenn weiterhin auch klassische Updates an der Zone durchgeführt werden sollen.

Bei max.example.com handelt es sich im folgenden um den Namen des erzeugten Keys. Dieser hat die Form einer Domain, muss aber nicht zwangsläufig einer existierenden Domain entsprechen. Ich empfehle die E-Mail-Adresse des Schlüsselinhabers in dem das @-Zeichen durch einen Punkt ersetzt ist zu verwenden (im Beispiel wäre als die E-Mail-Adresse des Inhabers max@example.com). Bei example.net um die Zone, die für DDNS konfiguriert werden soll. Ein Key kann dabei für mehrere Zonen gemeinsam genutzt werden. Genauso ist es möglich mehreren Keys die Änderung einer Zone zu erlauben.

Key erzeugen

# dnssec-keygen -a HMAC-SHA512 -b 512 -n USER max.example.com

Das kann einen Moment dauern. Es entstehen zwei Dateien mit den Namen Kmax.example.com.*.key und Kmax.example.com.*.private. Beide Dateien enthalten den gleichen Key in unterschiedlichen Formaten, da wir für DDNS einen symmetrischen Key benutzen (d.h. kein Public-Key-Verfahren). Entsprechend muss der Inhalt beider Dateien geheim gehalten werden.

Konfigurieren von Bind

Zuerst muss der erzeugte Schlüssel in die Konfiguration von bind eingefügt werden:

key max.example.com. {
    algorithm hmac-sha512;
    secret "nc/Q3sL8LDpBE6XpPFdXji2VlhRirN3zxIErqA8xmS8JSMbqQ1PGZrAEdTHl0ekduiQGwDt9zicKtJCSBvaLJw==";
};

Der Inhalt von „secret“ ist dabei aus der Datei Kmax.example.com.*.key übernommen.

Außerdem wird die Konfiguration der Zone angepasst indem eingetragen wird mit welchem Key welche Änderungen gemacht werden dürfen:

zone "example.net" in {
    type master;
    notify yes;
    file "/etc/bind/zones/example.net.zone";
    update-policy {
        grant max.example.com.         subdomain example.net. ANY;
    };
};

Neu eingefügt ist hier der „update-policy“-Abschnitt. (Es gibt auch das Keyword allow-update, da kann man allerdings nicht konfigurieren was (nicht) geändert werden darf mit einem Key.)

Bind muss damit alles funktioniert Schreibzugriff auf die Zonenfiles und das Verzeichnis in dem diese liegen haben.

Editieren der Zone mit DDNS-Befehlen

# nsupdate -k Kmax.example.com.*.private
update delete example.net A
update add example.net 500 A 192.0.2.128
send
quit

Manuelles Editieren des Zonefiles

Wenn für eine Zone DDNS aktiv ist, dann darf nicht mehr einfach das Zonenfile geändert werden. Grund hierzu ist, dass Bind nicht für jede Änderung eine neue Version des Zonenfiles erzeugt sondern ein Journal anlegt. (Datei wie die Zonendatei plus Endung *.jnl.) Um die Zonendatei zu editieren muss bind gesagt werden, dass er keine weiteren Updates für die Zone annimmt und alle vorhandenen Updates in die Zonendatei schreibt. Das geht mit:

# rndc freeze example.net

Jetzt kann die Zonendatei editiert werden.

# rndc thaw example.net

Mit dem "thaw"-Kommando von rndc wurde die Annahme von Updates wieder aktiviert und gleichzeitig Bind instruiert die Zonendatei neu einzulesen, also gemachte Updates zu übernehmen.

Ich habe inzwischen aber komplett aufgehört Zonendateien auf diesem Weg zu editieren. Ich mache alles über nsupdate. Das hat den großen Vorteil, dass nichts schiefgehen kann. nsupdate übernimmt einerseits nur korrekte Änderungen und kümmert sich andererseits auch automatisch darum, dass der Serial im SOA-Record inkrementiert wird. Wenn DNSsec auf dem Nameserver aktiviert ist, so sorgt sich nsupdate sogar darum, dass die Zone automatisch neu signiert wird.


Unless otherwise credited all material Creative Commons License by Matthias Wimmer