DNS und BIND


Dirk Geschke, LUG-Erding

Letzte Änderung: 7.11.2007


Vorwort

Der Inhalt des Vortrages baut im wesentlichen auf das hervorragende Buch von Cricket Liu und Paul Albitz auf. Da ich die aktulle Auflage des Buches gerade gelesen hatte bot es sich an einen Votrag zu diesem Thema zu halten.

Dabei spielt auch die Erfahrung, dass die wenigsten zu wissen schienen wie DNS eigentlich genau funktioniert eine nicht unwesentliche Rolle. DNS funktioniert meistens recht gut und im Hintergrund, so dass sich vermutlich die meisten nicht wirklich Gedanken zu diesem Thema gemacht haben.

Den Inhalt des Vortrages habe ich dann in einzelnen Portionen und etwas aufbereiteter per E-Mail an die Mailingliste linux@lug-erding.de versendet. Als alle E-Mails erstellt und versendet waren habe ich dann noch einmal alles in ein Dokument zusammengefasst und überarbeitet. Das Ergebnis liegt nun hiermit vor.

Viel Spaß bei der Lektrüe, möge es dem Einen oder Anderen hilfreich oder auch nur informativ sein.

Dirk Geschke, Erding im Dezember 2006

Historie der Namensverwaltung im Arpanet

Gegen Ende der 70er Jahren bestand das Arpanet, der Vorläufer des Internets, nur aus gut hundert Systemen. Um sich deren Adressen besser merken zu können gab es eine Abbildung von Namen zu Adressen. Diese wurden in einer zentralen Datei HOSTS.TXT gespeichert.

Jeder Teilnehmer des Arpanets musste diese von Zeit zu Zeit aktualisieren um die Adressen der neuen Systeme zu erhalten. Diese Datei wurde vom Stanford Research Institute's Network Information Center (SRI-NIC) verwaltet.

Diese Datei findet sich heute noch auf Unix-Systemen als /etc/hosts und dient noch immer der Adreßumsetzung. Jedoch wird diese nicht mehr zentral verwaltet.

Der Grund dafür lag in er Entwicklung von TCP/IP in Berkeley bzw. bei BBN (Bolt, Beranek und Newman), was jedoch in BSD implementiert wurde. Hier gab es auch diverse Streitigkeiten zwischen BBN und Bill Joy der eine bessere Implementation entwickelt hatte die effektiver aber nicht so elegant war.

Eine Folge war eine explosionsartige Zunahme der Systeme die am Arpanet teilnahmen. RFC 1296 listet z.B.:

   Aus RFC 1296  
Date Hosts Host table
08/81 213 #152
05/82 235 #166
08/83 562 #300
10/84 1.024 #392
10/85 1.961 #485
02/86 2.308 #515
11/86 5.089   
12/87 28.174   
07/88 33.000   
10/88 56.000   
01/89 80.000   
07/89 130.000   
10/89 159.000   
10/90 313.000   
01/91 376.000   
07/91 535.000   
10/91 617.000   
01/92 727.000   

Es war klar, dass dies nicht mehr über eine zentrale Datei beim NIC verwaltet werden konnte:

Diese RFC's sind heute nicht mehr gültig, sie wurden durch RFC 1034 und RFC 1035 ersetzt.

RFC - Request For Comment

Das Arpanet als Vorläufer des heutigen Internets sollte über sogenannte IMPs, Interface Message Processors, verbunden werden.

Die Idee war, dass das eigentliche Netzwerk über IMPs realisiert wird um die Probleme der vielen unterschiedlichen Host-Architekturen besser in den Griff zu bekommen. Diese IMPs wurden bei BBN, Bolt, Beranek and Newman, entwickelt, die den Auftrag dafür von der ARPA, Advance Research Projects Agency, bekamen.

Auf diese Weise konnte BBN das eigentliche Arpanet entwickeln ohne sich Gedanken um die unterschiedlichen Hosts zu machen. Damit diese dann an die IMPs angeschlossen werden konnten benötigte man spezielle Interfaces.

Im Sommer 1968 traf sich eine Gruppe fortgeschrittener Studenten (graduate students) von UCLA (University of California, Los Angeles), SRI (Stanford Research Institute), UCSB (University of California, Santa Barbara) und University of Utah in Santa Barabara.

Diese vier Standorte stellten später das erste Arpanet dar. (Genaugenommen bestand das erste Arpanet aus UCLA und SRI. Aber wir wollen hier nicht kleinlich sein.) Diese Gruppe nannte sich Network Working Group.

Diese Treffen fanden regelmäßig in Form von Seminaren statt und es wurde diskutiert wie die Anbindung Host <-> IMP gestaltet werden sollte.

Nun setzte sich die Einsicht durch, dass diese Treffen wenig sinnvoll sind wenn nicht die wichtigsten Überlegungen niedergeschrieben werden. Mithilfe einer Niederschrift konnte vielleicht alles besser geordnet und durchdacht werden.

Steve Crocker schrieb die ersten Gedanken nieder. Dabei hatte er weniger Bedenken was er schrieb sondern wie. Er wollte niemanden zu Nahe treten oder verärgern:

The basic ground rules were that anyone could say anything and that nothing was official.

Um nicht so zu klingen als ob alles schon in Stein gemeisselt ist gab er seiner Niederschrift die Aufschrift

Request for Comments

Diese wurde am 7. April 1969 mit dem Titel Host Software an die anderen Teilnehmer versendet. Dieser RFC existiert natürlich auch heute noch: ftp://ftp.rfc-editor.org/in-notes/rfc1.txt

Der RFC wurde natürlich NICHT per E-Mail versendet, dieses Verfahren existierte Mangels Netzwerk noch nicht.

Vermutlich ist diese Namensgebung und die Art wie dieser RFC (oder besser gesagt der Ton?) geschrieben wurde ein Grund warum das Arpanet bzw. heutige Internet in dieser Form entstanden ist.

Aus diesem Kreis stammt übrigens auch der Name Protokoll im Bereich von Computernetzwerken. Auf der einen Seite ist die Verwendung in diplomatischen Kreisen recht adäquat, es mussten viele Seiten dem Prozedere des Netzwerkes zustimmen.

Auf der anderen Seite stammt das Wort aus dem griechischem und bezeichnete das Deckblatt eines Papyrus-Stapels der eine Zusammenfassung des Inhaltes darstellte. Das passt natürlich gut zum Schichtensystem der Netzwerke...

Das Domain Name System

Um die Probleme der zentralen HOSTS.TXT Datei zu lösen lag es nahe eine verteilte Datenbank zu verwenden. Dadurch war die Einführung einer dezentralen Verwaltung möglich.

Die Idee war Domainnamen zu verwenden die entsprechend auf anderen Servern verwaltet werden können. Dazu gibt es zwei Dienste:

Die DNS-Struktur ähnelt der des Unix-Dateisystems, anstelle von Slashes ("/") werden jedoch Punkte (".") verwendet.

Es gibt aber einen weiteren wichtigen Unterschied: Die Pfade sind im Unix Dateisystem von links nach recht, im DNS jedoch umgekehrt, von rechts nach links:

/etc/bind/named.conf
  / -> etc/ -> bind/ -> named.conf
www.lug-erding.de.
www <- .lug-erding <- .de <- .

So wie einzelne Verzeichnisse auf unterschiedlichen Partitionen liegen können, so können Domainnamen auf unterschiedlichen Servern liegen.

Das Konzept hat einen offensichtlichen Vorteil: Namenskollisionen sind nur innerhalb einer Domain möglich, d.h. es darf mehrere Systeme mit den Namen www geben solange sie in unterschiedlichen Domains liegen.

Sprechweise
Ein Computername wird gewöhnlich in zwei Teile interpretiert. Der erste Teil (bis zum Punkt) stellt den Hostnamen dar, der Rest den Domainnamen.

Innerhalb von DNS wird diese Unterscheidung gewöhnlich nicht gemacht, dort wird ein Computername ebenfalls als ein Domainname verwendet. (Ähnlich wie es im Dateisystem oft nicht offensichtlich ist ob es sich bei einer Pfadangabe um ein Verzeichnis oder um eine Datei handelt.)

Der Ursprung des Dateisystems wir Root-Verzeichnis genannt. Analog werden die obersten Nameserver Root-Nameserver genannt. Diese delegieren den ersten Domainnamen an verschiedene andere Nameserver, Delegation heißt einfach ausgedrückt, dass für diese Domains ein anderer Nameserver zuständig ist.

Toplevel-Domains

Die ersten Domains unterhalb von Root heissen Topleveldomains. Die klassischen Topleveldomains sind:

   com: kommerzielle Organisationen
   edu: edu_cational -> Schulen, Universitäten
   gov: government -> Regierungsstellen, z.B. NASA.gov
   mil: militärische Einrichtungen
   net: Netzwerkbetreiber, seit 1996 frei
   org: nicht-kommerzielle Einrichtungen, seit 1996 frei
   int: internationale Einrichtungen, z.B. NATO.int
  arpa: Übergangsdomain HOSTS.TXT -> DNS

.net und .org wurden 1996 freigegeben, d.h. jeder kann in diesen Toplevel-Domains seine eigenen registrieren (lassen).

Da der Übergang von HOSTS.TXT in das DNS nicht auf einmal erfolgen konnte wurde die Übergangs-Toplevel-Domain .arpa eingeführt. Hier waren alle Systeme aus der HOSTS.TXT in der .arpa Domain zu finden.

Gab es z.B. ein System frodo in HOSTS.TXT so fand man dieses als frodo.arpa im DNS wieder. Hier konnte es keine Namenskollisionen geben, da dies bereits in der HOSTS.TXT verboten war.

Da das Arpanet in den USA entstand wurden diese Domains gewöhnlich auch dort verwendet. Um andere Länder mit aufzunehmen und deutlich zu machen wo diese zu finden sind wurden die Länderdomains ebenfalls als Toplevel-Domains eingeführt.

ISO-3166-1 definiert eindeutige 2-Buchstaben-Abkürzungen für jede Nation. Diese wurden dann als Toplevel-Domains eingeführt. Die einzige Ausnahme hier ist .uk anstelle von .gb für Großbritannien.

Diese werden auch ccTLDs genannt, country code TopLevel-Domains.

Einige dieser Domains sind:

  de: Deutschland
  us: USA, selten benutzt
  by: Weißrussland, nicht Bayern! 
  tv: Tuvalu
  za: Südafrika

Es gibt auch bei einigen Nationen das Bestreben die klassischen Toplevel-Domains als Second-Level-Domains einzuführen, dabei beschränkte man sich dann auf 2 Buchstaben, z.B.: co.uk für commercial Domains in Großbritannien.

Es gibt aber nun auch einige neue Toplevel-Domains:

   aero  : Luftfahrt, gesponsort
   biz   : business, generisch
   coop  : generisch, Kooperationen 
   info  : generisch
   museum: Museen, gesponsort
   name  : Privatpersonen, generisch
   pro   : Professionelle Anbieter, generisch
   mobi  : Mobilfunk, gesponsort
   jobs  : Stellenvermittlungen, gesponsort
   travel: Reiseunternehmen, gesponsort

Nur Mitglieder dürfen in den gesponsorten Domains Einträge registrieren lassen, die anderen sind frei. Allerdings ist bei den meisten fraglich wozu diese gut sein sollen. Die einzigen die davon profitieren sind wohl die Internet-Registrare...

Als eventuelle neue Toplevel-Domains stehen noch folgende Domains an:

  cat : katalanisch sprechende Mitglieder
  post: postbezogene Einträge
  asia: asiatische Mitglieder
  mail: für spamfreie E-Mails
  tel : Kommunikationskontakte
  xxx : Erwachsenenindustrie

Nun, die xxx TLD hat vielleicht seine gute Berechtigung, lassen sich dadurch diese Seiten zum einen guten blockieren, sofern dies gewünscht ist, zum anderen wird hier nur das gefunden was explizit gesucht wird, falls man es sucht.

Laut Heise-Newsticker sind 1,1 Prozent aller Webseiten pornographischer Natur.

Ob allerdings den Betreibern ein leichtes Filtern ihrer Seiten wünschenswert erschent lasse ich einmal dahingestellt.

Delegation

DNS ist eine dezentrale Datenbank, d.h einzelne Domains können über andere Server verwaltet werden. Diesen Prozess wird Delegation genannt.

Delegierte Domains sind vollständige Domains. Um aber deutlich zu machen, dass diese hierarchisch tiefer stehen werden oft auch in diesem Zusammenhang die Begriffe Unterdomain bzw. Subdomain verwendet.

Eine Subdomain, sofern sie delegiert wurde, wird von einem anderen Nameserver verwaltet. Allerings muss eine Subdomain nicht delegiert werden.

Hier ist ein Beispiel für Subdomains in der Domain lug-erding.de:

www		IN	A	89.110.147.240
www.debian	IN	A	...
www.gentoo	IN	A	...

Dies ist ein Auszug aus einer (möglichen) Zonendatei der Domain lug-erding.de. (Die Syntax wird später noch ausführlicher erläutert.) Die Kurzversion ist, dass der erste Teil der Name ist an dem die Domain .lug-erding.de noch angehängt wird. IN steht für die Internet-Klasse und A für einen Adress-Typ. Der letzte Wert stellt die IP-Adresse dar.

Hier ist www.debian.lug-erding.de in der Zone lug-erding.de obwohl es ein Host in einer Subdomain ist. Es wird nun deutlich, dass eine Zone durchaus mehr umfassen kann als nur eine Domain.

Wenn diese Subdomains delegiert werden sollen, so würde die Zonendatei so aussehen:

www		IN	A	89.110.147.240
debian		IN	NS 	ns1.debian.lug-erding.de
debian		IN	NS 	ns2.debian.lug-erding.de
gentoo		IN	NS 	ns1.gentoo.lug-erding.de
gentoo		IN	NS 	ns2.gentoo.lug-erding.de

ns1.debian	IN	A	...
ns2.debian	IN	A	...
ns1.gentoo	IN	A	...
ns2.gentoo	IN	A	...

Hier ist der Typ NS für Nameserver hinzugekommen. Es kann auch erkannt werden, wie mehr als ein Nameserver für eine Domain angegeben werden kann.

Ein weiterer wichtiger Punkt ist der, dass die Nameserver für die Subdomain debian.lug-erding.de in der gleichen Subdomain liegen. Hier gibt es nun ein Problem: Eigentlich müssten die Einträge ns1 und ns2 nur in der Zone debian.lug-erding.de vorhanden sein. Nur wie sollen diese Einträge gefunden werden, wenn nicht klar ist welcher Nameserver dafür zuständig ist?

Aus diesem Grund sind sogenannte glue records notwendig und auch erlaubt. Daher sind ns1.debian und ns2.debian in der Zone für lug-erding.de eingetragen obwohl sie formal da nicht hingehören.

Wie jetzt in dem obigen Beispiel zu sehen ist, können mehr als ein Nameserver für eine (Sub-) Domain angegeben werden. Von außen gesehen sind beide (es können auch noch mehr sein) Nameserver identisch, es gibt hier keine Präferenz für einen Server.

Von innen gesehen muss es jedoch eine Koppelung zwischen den Nameservern geben. Historisch wird hier unterschieden zwischen:

Diese Begriffe werden auch heute noch zum Teil verwendet, insbesondere Microsoft verwendet diese Sprechweise. Die eigentlich aktuelle Sprechweise ist:

Diese Bezeichnungen sind eigentlich präziser, die alte Sprechweise suggerierte Präferenzen die nicht existieren.

Der master ist nun der Hauptnameserver bei dem alle Änderungen, Ergänzungen und Löschungen vorgenommen werden. Der slave synchronisiert seine Zonen mit dem master.

Der Abgleich wird dabei Zonentransfer genannt und erfolgt in der Regel vom master zum slave, er kann aber auch von slave zu slave erfolgen, wenn z.B. ein slave keinen direkten Kontakt zum master hat.

Eine Anmerkung gegen Ende: Wenn von einem master oder slave gesprochen wird, so wird immer eine konkrete Zone betrachtet. Jeder Nameserver kann sowohl slave als auch master für unterschiedliche Zonen sein!

Zum Begriff Zone
Dies ist oft eine delegierte Subdomain, sie kann aber auch mehr sein wie man oben im nicht-delegierten Beispiel sehen kann. So gesehen kann eine Zone eine oder mehrere Subdomains enthalten, sie (und vielleicht noch ein paar andere) bilden dabei die übergeordnete Domain.

Um das zu verdeutlichen sei hier noch einmal ein Beispiel:

Die Zone lug-erding.de bestehe aus

lug-erding.de
gentoo.lug-erding.de
redhat.lug-erding.de

Die Zone debian.lug-erding.de besteht nur aus dieser einen Subdomain.

So besteht in diesem Fall die Domain lug-erding.de aus den Zonen lug-erding.de und debian.lug-erding.de.

Das klingt jetzt vermutlich alles etwas irritierend und verwirrend. Es ergibt aber einen Sinn wenn einmal näher darüber nachgeacht wird.

Ansonsten ist die pauschalen Annahme, dass eine Subdomain und Zone das gleiche ist nicht völlig verkehrt: Oft ist dies auch so.

Resolver

Der Resolver ist der Client-Prozess für die Namensauflösung und wird in der Regel über Bibliotheken realisiert. Im Fall von Linux ist der Resolver Bestandteil der glibc.

Wenn eine Applikation, z.B. der Browser, eine Namensauflösung durchführen muss, so fragt die Resolver-Routine einen Nameserver nach der IP-Adresse, wertet die Antwort aus und liefert das Ergebnis - IP-Adresse, DNS-Namen oder auch einen Fehler - an die Applikation zurück.

Namensauflösung

Bei der eigentlichen Namensauflösung gibt es zwei Verfahren:

  1. iterative Auflösung
  2. rekursive Auflösung

Bei der iterativen Namensauflösung erfolgt die Auflösung Schritt für Schritt. Soll z.B. www.lug-erding.de iterativ aufgelöst werden, so wird als erstes einer der Root-Nameserver gefragt wer für die Toplevel-Domain de zuständig ist. Der Root-Nameserver liefert dann:

de.	IN	NS   a.nic.de.
de.	IN	NS   c.de.de.
de.	IN	NS   f.nic.de.
de.	IN	NS   l.de.net.
de.	IN	NS   s.de.net.
de.	IN	NS   z.nic.de.

Ferner liefert er auch die zugehörigen IP-Adressen von diesen Nameservern. Den Aufbau von DNS-Paketen werde ich später noch genauer beschreiben, hier wäre das vermutlich nur verwirrend und wenig hilfreich.

Der nächste Schritt besteht jetzt darin einen dieser Server - alle müssen die Antwort wissen - nach der Domain lug-erding.de zu befragen. Die Antwort ist:

lug-erding.de.  IN      NS      ns1.partnerpanel.de.
lug-erding.de.  IN      NS      sns1.partnerpanel.de.

(Genaugenommen werden die Server immer nach www.lug-erding.de befragt, sie liefern aber nur das aus was sie selber wissen: Die Delegation zur nächsten Zone. Nur für den Fall, dass; einer sich die Frage stellt was passieren würde wenn www.lug-erding.de bereits ein Eintrag in der de-Zone wäre. Hier wird dann klar ob der Unterschied zwischen Domain und Zone verstanden wurde.)

Einer dieser 2 Nameserver (beide wissen natürlich die gleiche Antwort) liefert nun die finale Antwort:

www.lug-erding.de.  IN      A       89.110.147.240

Wie jeder wohl sofort einsieht ist diese Art der Namensauflösung viel zu aufwendig um in einem Resolver implementiert zu werden. Anderenfalls müsste jede Applikation dieses Verfahren durchführen.

Die Antwort auf dieses Problem ist die rekursive Auflösung von DNS-Namen.

Bei einer rekursiven Anfrage sendet der Resolver die DNS-Anfrage an seinen Nameserver mit der Bitte diese rekursiv zu beantworten.

Dieser Namserver führt nun (in der Regel) selber das iterative Verfahren zur Namensauflösung durch und liefert nur das Endergebnis an den Resolver zurück. Effektiv ist damit das Problem der Namensauflösung vom Resolver auf seinen Nameserver verlagert.

Der Resolver findet dabei seinen Nameserver über die Datei /etc/resolv.conf. (Die Namensauflösung selber kann auch über /etc/hosts, NIS oder LDAP erfolgen, dies wird bei Linux über die Datei /etc/nsswitch.conf geregelt, hier kann sowohl das Verfahren als auch die Reihenfolge festgelegt werden. Wir beschäftigen uns hier aber nur mit DNS. Daher interessiert uns hier nur die /etc/resolv.conf.)

Es gibt noch einen weiteren Vorteil, warum der Resolver besser einen Nameserver rekursiv befragen sollte: Dadurch werden alle DNS-Anfragen an den (bzw. die) gleichen DNS-Server gesendet. Diese können nun sehr effektiv die Ergebnisse cachen, d.h. sie merken sich die erhaltenen Resultate.

So können sich diese Nameserver bereits merken welcher für die Domain de zuständig ist und müssen nicht erneut die Root-Nameserver befragen! Es ist auch nicht selten, dass mehrfach der gleiche Name angefragt wird, wie z.B. ein beliebter Webserver.

Wer jetzt die berechtigte Frage stellt:

Wie lange darf ein Nameserver Einträge cachen?

Das wird später beim Thema SOA erklärt

reverse DNS

Normalerweise erfolgt die Zuordnung vom DNS-Name zur IP-Adresse. Nun möchte man gelegentlich auch wissen welcher DNS-Name sich hinter einer IP-Adresse verbirgt. Das Verfahren wird reverse DNS genannt. Dies ist leider kein triviales Unterfangen, es existiert keine direkte Koppelung zwischen diesen Einträgen.

Wenn in der Domain lug-erding.de ein neues System aufgenommen wird, so bewirkt dies noch kein funktionierendes reverse DNS für diesen Namen. Hier ist deutlich mehr zu tun, woher sollte jemand wissen, dass er den Namen zu dieser Adresse in der Domain lug-erding.de suchen müsste?

Die Lösung dieses Problems liegt in der Verwendung einer eigenen Domain für das reverse DNS!

Nun könnte hierfür eine eigene Toplevel-Domain erschaffen werden, es geht aber auch etwas einfacher durch Verwendung einer bereits existierenden Domain. Diese ist die arpa-Domain, diese war eigentlich nur für den Übergang von HOSTS.TXT zum DNS gedacht.

Die Subdomain für die umgekehrte Abbildung (reverse mapping) heißt "in-addr.arpa". In diesen (Sub-) Domainen befinden sich die IP-Adresse und die Zuordnung zu einem(!) DNS-Namen. (Warum da ein Ausrufezeichen steht erkläre ich später.)

Hier gibt es aber ein erneutes Problem: Wie sollen die IP-Adressen hier aufgeteilt werden? Alle Adressen in einer Zone ist wohl nicht realistisch, das wären ca. 4 Milliarden Einträge.

Die Idee ist jetzt, dass die IP-Blöcke verwendet werden, analog zum normalen DNS wird an den Punkten delegiert. Ursprünglich waren die Class-Einteilungen geplant, das ist auch derzeit noch möglich. Jedoch ist es heute eher unüblich, dass z.B. jemand ein komplettes Class-A Netz als reverse Zone verwaltet.

Hier offenbaren sich jedoch wieder zwei Probleme:

  1. DNS-Namen werden von rechts nach links aufgelöst, z.B.: . -> .de -> .lug-erding -> www IP-Adressen jedoch von links nach rechts, z.B.: 89. -> 110. -> 147. -> 240.
  2. Die kleinste Einheit umfasst 256 Adressen, eine kleinere Unterteilung ist mit diesem Schema nicht möglich!

Das erste Problem lässt sich auch so formulieren: Zuerst wird gesucht wer das 89er Netzwerk verwaltet, dann das 110er und letztlich der für das 147er. Der letzte sollte nun wissen welcher DNS-Namen zur Adresse 240 gehört.

Die Lösung dieses Problems ist relativ einfach: Die IP- Blöcke werden einfach umgedreht!

In unserem Fall ist die Antwort zu obiger IP-Adresse hier zu finden:

147.110.89.in-addr.arpa.  IN   NS    ns5.netclusive.de.
147.110.89.in-addr.arpa.  IN   NS    ns10.netclusive.de.
147.110.89.in-addr.arpa.  IN   NS    sns5.netclusive.de.

D.h. diese Nameserver wissen die Antwort:

240.147.110.89.in-addr.arpa.  IN   PTR   mail.lug-erding.de.

Wie leicht zu erkennen ist, wird hier kein A verwendet, es wird auch keine IP-Adresse ausgeliefert. Hier wird der Typ PTR verwendet und damit ist klar, dass die Antwort ein DNS-Name ist.

Das zweite Problem mit den Blockgrenzen ist etwas schwieriger zu lösen. Eine Antwort darauf gibt es im nächsten Kapitel:

Classless Delegation

Hier wird auch klar, dass es durchaus ein Problem sein kann den richtigen Betreiber des zugehörigen Nameservers zu finden und davon zu überzeugen einen Eintrag vorzunehmen!

Zum Schluss noch ein paar Worte zu obigem Ausrufezeichen:

Es können mehrere Systeme im DNS auf die gleiche IP- Adresse (A-Record) verweisen. Nur leider ist dies reverse nicht einfach möglich, hier wird in der Regel nur eine Adresse ausgeliefert. BIND ist in der Lage mit mehreren PTR-Einträgen zur gleichen IP-Adresse zu arbeiten. Diese werden auch alle ausgeliefert, jedoch jedesmal in einer anderen Reihenfolge (das wird round-robin genannt und auch bei anderen Records wie A-Records verwendet).

Leider sind jedoch die meisten (fast alle) Applikationen nicht in der Lage die zusätzlichen Domains auszuwerten!

Hier kann erkannt werden wie schwierig es ist wenn z.B. Mailserver verlangen, dass sowohl der A-Record als auch der PTR-Record zu identischen Einträgen gehören müssen. Oft beschränken sich die Anforderungen dann darauf das wenigstens die Domains gleich sein sollen. Aber auch hierfür gibt es keine zwingende Notwendigkeit.

Hinzu kommt noch das Problem, überhaupt einen PTR-Eintrag zu bekommen. Manchmal ist der eigene Provider nur ein Sub-Provider und muss den PTR-Eintrag bei seinem Provider beantragen. Und ob der immer mitspielt oder gar selber nur ein Sub-Provider ist kann leider nicht garantiert werden.

Zudem können mehrere unterschiedliche Domainnamen für einen Server vergeben werden. So verwenden z.B. Webhoster in der Regel eine IP-Adresse für eine Vielzahl von Webauftritten.

Und da wir schon beim Thema sind: In keinem RFC wird verlangt, dass erstens ein PTR-Record existieren muss und zweitens dieser mit dem Namen des A-Records identisch sein muss.

Von daher bewegen sich einige Mailprovider außerhalb der RFC's. Allerdings wo kein Richter existiert...

Classless Delegation

Reverse DNS kann eigentlich nur an IP-Blockgrenzen delegiert werden, d.h. die kleinste Einheit einer reverse Zone verwaltet maximal 256 Adressen.

Die andere Lösung ist, dass jeder einzelne Eintrag eine eigene reverse DNS-Zone darstellt. D.h. jeder einzelne PTR-Eintrag befindet sich in einer eigenen Zone!

Das ist natürlich viel zu viel Verwaltungsaufwand, es musste doch eine Möglichkeit geben z.B. nur 32 oder 64 IP-Adressen zu delegieren. Da dies eine Delegation nicht an den Grenzen einer Klasse (A, B oder C) ist, wird dies classless delegation genannt.

Diese kann recht elegant über CNAMEs realisiert werden. Zuerst hatte dies Verfahren Glen Herrmannsfeldt von CalTech in der Newsgroup comp.protocols.tcp-ip.domains erläutert. Es ist mittlerweile als RFC 2317 veröffentlicht worden:

Classless IN-ADDR.ARPA delegation

Angenommen es gibt drei Organisationen mit Subnetzen mit weniger als 256 Adressen:

           192.0.2.0/25   to organization A
           192.0.2.128/26 to organization B
           192.0.2.192/26 to organization C

(Der Anteil hinter dem Slash gibt an wieviel Bits der Adresse das Netz bestimmen, diese Notation wird auch CIDR, Classless Inter-Domain Routing gennant.)

Klassisch gesehen müssten diese alle in einer Zone verwaltet werden:

   $ORIGIN 2.0.192.in-addr.arpa.
   ;
   1               PTR     host1.A.domain.
   2               PTR     host2.A.domain.
   3               PTR     host3.A.domain.
   ;
   129             PTR     host1.B.domain.
   130             PTR     host2.B.domain.
   131             PTR     host3.B.domain.
   ;
   193             PTR     host1.C.domain.
   194             PTR     host2.C.domain.
   195             PTR     host3.C.domain.

Der Trick besteht nun darin, dass man CNAMEs verwendet:

   $ORIGIN 2.0.192.in-addr.arpa.
   @       IN      SOA     my-ns.my.domain. hostmaster.my.domain. (...)
   ;...
   ;  <<0-127>> /25
   0/25            NS      ns.A.domain.
   0/25            NS      some.other.name.server.
   ;
   1               CNAME   1.0/25.2.0.192.in-addr.arpa.
   2               CNAME   2.0/25.2.0.192.in-addr.arpa.
   3               CNAME   3.0/25.2.0.192.in-addr.arpa.
   ;
   ;  <<128-191>> /26
   128/26          NS      ns.B.domain.
   128/26          NS      some.other.name.server.too.
   ;
   129             CNAME   129.128/26.2.0.192.in-addr.arpa.
   130             CNAME   130.128/26.2.0.192.in-addr.arpa.
   131             CNAME   131.128/26.2.0.192.in-addr.arpa.
   ;
   ;  <<192-255>> /26
   192/26          NS      ns.C.domain.
   192/26          NS      some.other.third.name.server.
   ;
   193             CNAME   193.192/26.2.0.192.in-addr.arpa.
   194             CNAME   194.192/26.2.0.192.in-addr.arpa.
   195             CNAME   195.192/26.2.0.192.in-addr.arpa.

Der Domainname des CNAMEs ist hier eher nebensächlich, manche würden hier z.B. satt 0/25.2.0.192.in-addr.arpa. einfach den lesbareren Namen 0-127.2.0.192.in-addr.arpa. verwenden.

Die delegierte Zone sieht nun so aus:

   $ORIGIN 0/25.2.0.192.in-addr.arpa.
   @       IN      SOA     ns.A.domain. hostmaster.A.domain. (...)
   @               NS      ns.A.domain.
   @               NS      some.other.name.server.
   ;
   1               PTR     host1.A.domain.
   2               PTR     host2.A.domain.
   3               PTR     host3.A.domain.

Der Trick besteht also darin einen CNAME zu verwenden der in einer anderen Zone liegt! Um nun die Adresse aufzulösen würde die klassisch zuständige Zone einen Verweis auf einen CNAME liefern der in einer anderen Zone liegt. Voila: Wir haben unsere Delegation ohne an irgendwelche Grenzen gebunden zu sein!

Die Zonen von B und C sehen analog aus:

   $ORIGIN 128/26.2.0.192.in-addr.arpa.
   @       IN      SOA     ns.B.domain. hostmaster.B.domain. (...)
   @               NS      ns.B.domain.
   @               NS      some.other.name.server.too.
   ;
   129             PTR     host1.B.domain.
   130             PTR     host2.B.domain.
   131             PTR     host3.B.domain.


   $ORIGIN 192/26.2.0.192.in-addr.arpa.
   @       IN      SOA     ns.C.domain. hostmaster.C.domain. (...)
   @               NS      ns.C.domain.
   @               NS      some.other.third.name.server.
   ;
   193             PTR     host1.C.domain.
   194             PTR     host2.C.domain.
   195             PTR     host3.C.domain.

Theoretisch ist es sogar möglich auf Domains zu verweisen, die nicht in der in-addr.arpa Domain liegen. Man sollte dies aber besser nicht machen, so ist es eindeutiger, dass es eine reverse DNS-Zone ist.

Aufbau einer Zone

Sprechweise bei Zonendaten
Ein Record ist ein Eintrag in einer Zone. Alle Records zu einem DNS-Eintrag werden Ressource-Record (RR) genannt.

Im Allgemeinen ist der erste Eintrag einer Zone die TTL, die Time to Live, die angibt wie lange ein gültiger Eintrag von anderen Nameservern gespeichert (gecachet) werden darf. Dieser Wert kann pro Zoneneintrag, d.h. für jeden Namen, separat gesetzt werden.

Erfolgt dies nicht, so greift der globale TTL-Wert der Zone. Dieser Wert wird über die Variable $TTL gesetzt.

Ein Record hat formal die Struktur:

Name   {TTL}  <Klasse>  <Typ>   Wert

Die TTL ist hier optional und gilt dann nur für diesen einen Eintrag.

Klasse

Es existieren 4 Klassen:

Interessant ist hier nur die erste Klasse: IN. Diese bezieht sich auf das Internet, Die CSNet-Klasse wird gelegentlich in RFCs bei Beispielen verwendet.

In der Chaos-Klasse verwaltet BIND seine Versionsnummer sowie die Namen der Autoren.

Typen

Es gibt eine Vielzahl unterschiedlicher Typen die auch die Art des nachfolgenden "Wertes" festlegen.

Die klassischen Typen sind:

A
Adresseintrag, liefert die IP-Adresse
CNAME
canonical name, dies ist ein Alias auf anderen Namen
HINFO
host info, zusätzliche Informationen zu einem HOST
MX
mail exchanger, wohin soll eine E-Mail gesendet werden?
NS
nameserver, welcher Nameserver ist zuständig?
PTR
pointer, wird für reverse DNS verwendet, s.o.
SOA
start of authorization, Beginn einer Zone
TXT
zusätzlicher Texteintrag, beliebiger ASCII-Text
WKS
well known services, welche Dienst bietet der Server an?

Einige dieser Typen werden nicht mehr verwendet, so sollte z.B. via HINFO festgelegt werden was für ein Betriebssystem und Version auf dem System installiert sind und eventuell auch der Aufstellungsort.

Da dies nützliche Informationen für Angreifer darstellte ist man dazu übergegangen diese Werte nicht mehr zu verwenden. Bei WKS verhält es sich ähnlich, mir ist kein Programm bekannt das diesen Wert heute noch verwenden würde.

CNAMEs sind recht praktisch wenn ein System mehr als einen Namen hat. Oft wird dies verwendet wenn der andere (canonical) Name in einer anderen Zone liegt. Nameserver und Mailserver dürfen aber nicht über einen CNAME angegeben werden. Als einfache Regel kann man sich merken, dass ein CNAME niemals rechts stehen darf.

Dies waren die klassischen Typen, mittlerweile gibt es auch ein paar neue Typen die aber zum Teil noch experimentell sind. Diese Typen sind:

AFSDB
Andrew File System data base, experimentell
ISDN
Integrated Services Digital Network, experimentell
RP
responsible person, experimentell
RT
route through, experimentell
X25
X.25 Adressen, experimentell
PX
X.400 / RFC Abbildungen
AAAA
A-Record für IPv6 Adressen
SRV
Lokalisierung von Serverdiensten
NAPTR
naming authority pointer

Von Bedeutung sind hier eigentlich nur die AAAA und SRV-Typen. AAAA wird für IPv6 verwendet, dazu kommt später noch ein eigener Abschnitt.

SRV-Typen werden hauptsächlich von Microsoft und ADS-Diensten verwendet. Hier besteht z.B. die Möglichkeit explizit Dienste an IP-Adressen zu binden, z.B.:

_http._tcp.www.movie.edu.  IN  SRV  0  2  80 www.movie.edu.

Dies besagt, dass der http-Server (die TCP-Version) für www.movie.edu auf Port 80 von www.movie.edu zu finden ist.

Die beiden anderen Zahlenwerte sind die Priorität und das Gewicht. Die Priorität ähnelt der bei MX-Records (diese werde ich später noch erläutern), je niedriger der Wert desto höher ist der Name priorisiert. D.h. bei mehreren Einträgen muss zuerst der mit dem niedrigsten Wert ange- sprochen werden. Antwortet dieser Server nicht, so muss der nächste in der Prioritätsliste verwendet werden.

Das Gewicht bestimmt wie die Last bei Records mit gleicher Priorität verteil werden soll.

SOA

Als nächstes (nach der $TTL) folgt der eigentlich Start der Domain: Der sogenannte SOA-Record, start of authorization.

Der Aufbau ist (hier am Beispiel der Zone lug-erding.de):

lug-erding.de.   IN      SOA     ns1.partnerpanel.de.  
         hostmaster.lug-erding.de. 2006100401 10000 1800 604800 480

Der erste Wert gibt den Domainnamen an, für den diese Zone zuständig ist: lug-erding.de. Der abschließende Punkt ist nicht unwichtig, er zeigt einen absoluten Namen an. Dies ist analog zu dem Slash (/) bei Pfadangaben unter Unix zu sehen. Bei fehlendem Punkt wird der Zonenname angehangen!

Der zweite Wert (IN) besagt, dass es sich um einen Eintrag in der Klasse Internet handelt. Danach folgt der Typ des Records: SOA für Start Of Authorization.

Der DNS-Eintrag danach ist der Name des master Nameservers. Es folgt die Mailadresse eines Ansprechpartners wobei das AT-Zeichen (@) durch einen Punkt (.) ersetzt wird. In diesem Fall ist dies die Adresse hostmaster@lug-erding.de.

Diese Werte sind nur informeller Natur, sie werden von keinem automatischen Prozess ausgewertet.

Die Zahlenwerte die nun folgen sind:

  1. Seriennummer (serial, 2006100401)
  2. Refresh-Zeit (10000 Sekunden = 2.8 Tage)
  3. Retry-Zeit (1800 Sekunden = 30 Minuten)
  4. expire Zeit (604800 Sekunden = 7 Wochen)
  5. negative TTL (480 Sekunden = 8 Minuten)

Die Seriennummer gibt die Aktualität der Zone an, jedesmal wenn sich ein Record ändert muss diese Zahl erhöht werden. Slave Nameserver erkennen an diesem Wert der SOA ob ihre Daten noch aktuell sind oder die Zone erneut vom master geladen werden muss. Falls dem so ist findet ein sogenannter Zonentransfer statt, damit erhält ein slave wieder die aktuellen Daten.

Der eigentliche Wert ist irrelevant so lange er kleiner 32 Bit ist und bei jeder Änderung erhöht wird. Es hat sich aber eingebürgert hierfür das aktuelle Datum in umgekehrter Reichenfolge zu verwenden mit zusätzlichen 2 Stellen für Änderungen die innerhalb von einem Tag stattfinden können.

Das Datum wird deswegen umgekehrt, damit mit jedem Tag die Seriennummer erhöht wird. Anderenfalls ist dies nicht gewährleistet. Nehmen wir einmal den 10.2.2006 und den 1.4.2006. Die Seriennummern wären dann - wenn das Datum nicht umgedreht wird:

   10022006
   01042006

Wie leicht zu erkennen ist wäre der zweite Wert nun kleiner!

Bei umgekehrter Reihenfolge ergibt sich:

   20060210
   20060401

Nun stimmt es mit dem gewünschten Ziel überein.

Die Refresh-Zeit gibt an in welchen Abständen ein slave die Seriennummer überprüfen soll. Wenn dies fehlschlägt, so gibt der Retry-Wert an wann ein slave es erneut versuchen soll.

Die Expire-Zeit gibt an ab wann alle Werte als ungültig anzusehen sind. Dies betrifft nur slave Nameserver die innerhalb dieser Zeit keinen Kontakt zum master hatten.

Dieser Wert ist in der Regel sehr hoch und kann zu Problemen führen. Ändert sich z.B. die IP-Adresse des masters und wird dem vergessen dem slave dieses mitzuteilen kann es sehr lange dauern bis dieser slave Nameserver den Dienst einstellt.

Dann ist gewöhnlich der Bezug zur geänderten IP-Adresse nicht mehr unbedingt präsent und die Suche warum der Server seinen Dienst einstellt kann etwas länger dauern.

Der letzte Wert ist die sogenannte negative caching Zeit bzw. negative TTL, sie gibt an wielange ein Nameserver einen nicht-existierenden DNS-Eintrag cachen (d.h. sich merken und ausliefern) darf.

In früheren Versionen war dies die default-TTL aller Records, die Definition wurde aber in [RFC 2308 (ftp://ftp.rfc-editor.org/in-notes/rfc2308.txt)] abgeändert und für die default-TTL wurde die Variable $TTL (s.o.) eingeführt.

Allerdings kommen die 4er BIND-Versionen mit dieser neuen Definition nicht klar. Aber eigentlich sollten dieser Versionen nicht mehr im Umlauf sein, eigentlich...

Nameserver bei Delegationen

Der Typ NS wird verwendet um den Nameserver für die Zone festzulegen. Dies ist innerhalb der Zone eher weniger wichtig, ein relevanter Nameserver muss hierfür bereits befragt worden sein.

Die wichtigere Verwendung besteht bei der Delegation von Zonen, d.h. das Zuweisen von Zonenzuständigkeiten an andere Server.

Streng genommen müssen beide Einträge existieren, sowohl in der übergeordneten Zone als auch in der Zone selber.

Für lug-erding.de lautet der Eintrag:

lug-erding.de.    IN     NS    ns1.partnerpanel.de.
lug-erding.de.    IN     NS    sns1.partnerpanel.de.

In BIND-Syntax geht dies einfacher:

lug-erding.de.    IN     NS    ns1.partnerpanel.de.
                  IN     NS    sns1.partnerpanel.de.

Wenn kein Name in der ersten Spalte steht, so gilt der letzte der darüber steht. Aber es geht noch einfacher, BIND verwendet das @-Zeichen als Abkürzung für den Zonennamen:

@                 IN     NS    ns1.partnerpanel.de.
                  IN     NS    sns1.partnerpanel.de.

Und da wir schon dabei sind: Wenn der abschließende Punkt fehlt, so wird der Zonennamen angehangen. Dieser Name kann durch die Variable $ORIGIN verändert werden.

Adresseneinträge

IP-Adressen werden durch A-Records (address record) dargestellt. Dabei können durchaus mehrere verschiedene Namen zur gleichen IP-Adresse auflösen, z.B.:

www       IN     A     89.110.147.240
mail      IN     A     89.110.147.240
@         IN     A     89.110.147.240

Der letzte Eintrag dürfte den einen oder anderen vielleicht überraschen aber es ist durchaus erlaubt der Zone selber eine IP-Adresse zuzuweisen. Dies wird gelegentlich bei Webservern verwendet, insbesondere auch die Verwendung unterschiedlicher Namen mit der gleichen Adresse (diese heißen bei Apache dann virtual hosts und liefern je nach Namen andere Inhalte aus.)

A-Records sind wohl die am häufigsten verwendeten Zoneneinträge.

Bei BIND gibt es auch die Möglichkeit wild-card Einträge vorzunehmen. In diesem Fall wird die wild-card Adresse jedesmal als Antwort geliefert wenn kein Eintrag für diesen Namen existiert. So gesehen gibt es dann keine nicht-existierenden Namen (vom Resolver aus gesehen).

Diese Verwendung ist nicht zu empfehlen, hat es doch mitunter ungewünschte Nebenwirkungen. Insbesondere wenn vergessen wurde den localhost zu definieren, der würde dann eine andere Adresse als 127.0.0.1 bekommen.

CNAMEs

CNAMEs sind Aliase, sie verweisen auf einen Namen der einen A-Record besitzt, das ist dann ein canonical Name.

Z.B. könnte man in der Zone lug-erding.de folgenden CNAME definieren:

www.gentoo   IN    CNAME    www.mglug.de

Man beachte den fehlenden Punkt hinter gentoo, hier wird dann der Zonenname lug-erding.de angehängt!

Ein Resolver fragt gewöhnlich nach einem A-Record. Erhält dieser als Antwort einen CNAME so nimmt er diesen Namen und startet eine neue Anfrage nach dem A-Record (für den neuen Namen).

Also: www.gentoo.lug-erding.de liefert www.mglug.de zurück. Der Resolver nimmt nun www.mglug.de und startet erneut eine Anfrage nach der IP-Adresse (A-Record).

Aber vorsicht: Sollte hinter www.mglug.de ein virtueller Webserver stehen, so wird www.gentoo.lug-erding.de vermutlich nicht zu der gewünschten Webseite führen!

Von der Namensauflösung her spricht eigentlich nichts dagegen, dass ein CNAME wieder auf einen CNAME verweist. BIND hat eine spezielle Option um dies zu erlauben, sinnvoll ist dies jedoch nicht. Dies könnte zu sehr langen Anfragen führen und die Namensauflösung unnötig in die Länge ziehen.

CNAMEs sind auch als NS oder MX Records verboten, die dürfen hier nicht verwendet werden! Als einfache Regel kann man sich merken, dass ein CNAME niemals rechts in einer Zone stehen sollte.

BIND bietet noch eine Erweiterung: DNAME. Ein DNAME ist quasi ein wild-card CNAME. D.h. existiert kein Zoneneintrag für einen Namen, so wird ein CNAME mit gleichem Hostnamen erstellt.

Dies kann hilfreich sein, wenn Zoneneinträge delegiert werden. Dann wird die alte Domain einfach auf die neue Domain weitergeleitet.

reverse Einträge

Diese sind recht einfach, sie sind eigentlich "vertauschte" A-Records, z.B. steht in der Zone 147.110.89.in-addr.apra:

240    IN    PTR     mail.lug-erding.de.

Die Zahl 240 ist der Wert im 4. IP-Block: 89.110.147.240

Jetzt fehlt nicht mehr viel erwähnenswertes über Zonen- einträge. Die nicht angesprochenen Typen funktionieren eigentlich alle nach dem gleichen Schema.

Mailzustellung - MX-Records

E-Mails werden an MX-Records versendet. Der MX-Record gibt an, welche Server für die Mailzustellung verwendet werden soll. Für die LUG-Erding gilt:

lug-erding.de.   IN   MX   10   mail.lug-erding.de.

Die Zahl 10 gibt hier die Priorität des Servers an. Dies ist nur relevant wenn mehrere MX-Einträge existieren. In diesem Fall wird zuerst versucht eine E-Mail an den Server mit der niedrigsten Priorität zu senden.

Wenn dieser nicht erreicht werden kann (oder er keine E-Mails entgegennimmt), so wird der nächste Mailserver verwendet.

Dieser relayed die E-Mails, d.h. er sieht dass er nicht der primäre Mailserver für diese Domain ist. Dieser nimmt die E-Mail entgegen und versucht diese an den primären Mailserver zu senden. Relayen heißt also eigentlich nur, dass die E-Mails zwischengespeichert und dann weitergesendet werden.

Wichtig: Der angegebene Mailserver darf kein CNAME sein!

SPF und TXT

SPF heißt Sender Policy Framework und ist ein Ansatz die Spamflut zu bekämpfen. Rein thematisch passt es nicht in den Aufbau einer Zone wohl aber zur Mailzustellung. Da dies aber über den TXT-Typ realisiert wird passt es dann doch in den Rahmen.

TXT-Records sind einfach nur ASCII Zeichenketten die einem Namen quasi als Attribut zugeordnet werden können. Diese dürfen einen beliebigen Inhalt haben, jedoch ist die Maximallänge 256 Bytes.

Die Idee bei SPF besteht darin über DNS festzulegen wer E-Mails einer Domain verschicken darf. Um nicht extra einen neuen DNS-Typ einzuführen wird dieses einfach als TXT-Typ implementiert, z.B.:

oreilly.com. IN TXT "v=spf1 mx ptr include:oreillynet.com -all"

Der erste Eintrag (v=spf1) markiert diesen TXT-Record als SPF-Eintrag Version 1. (Es können durchaus mehrere TXT-Records existieren und es müssen nicht alles SPF-Einträge sein.)

mx bedeutet nun, dass alle Mailserver die als MX für oreilly.com gelistet sind E-Mails mit dieser Adresse versenden dürfen.

ptr wiederum verlangt, dass ein PTR-Record für den Sender existieren muss und dieser zu einem Server in der oreilly.com Domain auflösen muss.

include:oreillynet.com besagt, dass die SPF-Regeln für oreillynet.com auch für oreilly.com gelten. Dies wird oft verwendet wenn relaying über Server eines Providers (ISP) möglich sein soll.

-all verbietet allen anderen Server E-Mail mit dem Absender oreilly.com zu verbieten.

Es existieren noch ein paar Optionen mehr:

a
DNS-Namen die E-Mail versenden dürfen, z.B. +a:smtp1.oreilly.com
ip4
gibt eine IPv4-Adresse an die E-Mails versenden darf, es können auch Netze in CIDR-Notation angegeben werden.
ip6
wie ip4 allerdings für IPv6 Adressen.

Es existieren nun auch noch ein paar Qualifier, die zum Teil oben in den Beispielen verwendet wurden:

+
E-Mails erlauben (Pass)
-
E-Mails verbieten (Fail)
~
E-Mails können angenommen werden, sollten aber genauer geprüft werden (SoftFail)
?
ohne Wirkung (Neutral)

Ist kein Qualifier angegeben, so ist der default +.

Einige der Qualifier ergeben erst einen Sinn wenn man alles in Betracht zieht. So ist das ? durchaus dann sinnvoll, wenn danach z.B. ein -all folgt. Hier ist dieser neutrale Wert nicht explizit verboten.

Wenn alle Einträge die maximale Länge von 256 Bytes für einen TXT-Eintrag überschreiten, so können sie über mehrere TXT-Records verteilt werden.

SPF hat aber einige Probleme. So muss ein funktionierendes DNS vorhanden sein um E-Mails anzunehmen. Das Relaying über verschiedene Server, das ist eigentlich eine Grundfunktion von E-Mail Servern gewesen, ist nur noch bedingt möglich, es müssten alle möglichen Server berücksichtigt werden.

Ein nicht ganz unwichtiger Aspekt ist, dass der Versender es implementieren und der Empfänger es prüfen muss. D.h. wenn jemand selber SPF-Einträge vornimmt kann das höchstens das Spamaufkommen beim Empfänger reduzieren, nicht aber bei einem selber.

Und letztlich kann SPF nur wirklich effektiv sein, wenn nahezu alle es implementiert haben. Dies ist aber bei weitem (noch) nicht der Fall und die Voreinstellung aller E-Mailserver sollte sein, dass sie E-Mails annehmen sofern kein SPF-Eintrag für die Sender-Domain existiert.

Alles in allem ist es also eher fraglich ob sich das jemals wirklich durchsetzten wird.

Update: Mittlerweile existiert ein eigener RR-Typ: SPF, damit ist die Implementierung via TXT-Record obsolet. Die Frage ist nur wie die Übergangszeit realisiert werden soll: Nur noch auf SPF-Recordtypen achten oder auf beide? Wenn weiterhin der TXT-Record verwendet wird, so ist der SPF-Recordtyp überflüssig.

Zum Glück muss die Abfrage nur auf Mailservern erfolgen und nicht in jedem Client, so dass eine Migration von TXT auf SPF durchaus leicht möglich ist.

Besonderheiten

Der localhost sollte in jeder Zone existieren und zu 127.0.0.1 auflösen. Wenn diese Adresse nicht zu diesem Wert aufgelöst werden kann dann verhalten sich manche Applikationen sehr seltsam.

Für den reverse-Eintrag gilt das gleiche: Jeder Nameserver sollte master für 127.in-addr.arpa sein.

Dies dürfte auch der Hauptgrund sein warum via nsswitch.conf die Datei /etc/hosts noch verwendet wird. Diese enthält in der Regel immer localhost.

Ferner benötigt jeder Nameserver eine Hints-Datei. Diese enthält alle 13 Root-Nameserver. Bei BIND heißt diese Datei in der Regel db.cache.

Diese kann via HTTP von ftp://ftp.internic.net (192.0.34.27) heruntergeladen werden. Die Datei befindet sich im domain-Verzeichnis und heißt db.cache.

Die Aktualisierung dieser Datei muss manuell erfolgen, es gibt keinen Automatismus hierfür im DNS Schema.

Allerdings ist diese Liste in BIND Version 9 eincompiliert. Es schadet aber nicht, eine Hints-Datei anzugeben. In diesem Fall wird dann die hinterlegte Datei verwendet.

Nach dem Laden der Hints-Datei bzw. der Verwendung der eincompilierten Daten wird zuerst ein Root-Nameserver nach der Liste der aktuellen befragt. D.h. die Hints-Datei ist in der Tat nur ein Hinweis darauf wo die eigentlichen Root-Nameserver erfragt werden können.

TTL

Bei der TTL sollte beachtet werden, dass Änderungen an einem Resource Record erst nach Ablauf der TTL überall im Internet erfolgt sind. Bis dahin können noch immer gecachete alte Werte im Umlauf sein.

Wird z.B. ein Provider-Wechsel und damit der Wechsel von IP-Adressen geplant, so sollte rechtzeitig vorher die TTL heruntergesetzt werden um möglichst schnell die Änderungen nach der Umstellung verbreiten zu können.

Es gibt auch Load-Balancer die den Netzwerkzugriff auf Server über extrem kurze TTL's realisieren. Derartige Nameserver überwachen die Last-Verteilung in einer Serverfarm und liefern die IP-Adresse mit der geringsten Load zurück.

Durch die extrem kurze TTL kann effektiv kein Nameserver den erhaltenen Wert speichern, es muss jedesmal neu nachgefragt werden und der Netzwerkverkehr oder die Last kann erneut neu verteilt werden.

Format von DNS-Paketen

Normale DNS-Anfragen erfolgen via UDP, der Server antwortet gewöhnlich auf Port 53.

Es gibt aber Begrenzungen in der Größe:

Labels
63 Bytes (ein Label ist der Domainpart zwischen 2 Punkten)
Namen
255 Bytes, das sind alle Labels aneinandergehängt
TTL
positiver Wert einer 32-Bit signed number
UDP-Paket
512 Bytes Nutzlast

Gerade der letzte Wert ist eine starke Begrenzung, Pakete die größer sind werden auf 512 Bytes gekürzt. Der Hauptgrund für die Begrenzung auf 512 Bytes dürfte RFC 1122 (bzw. der Vorgänger RFC 791) sein. Hier wird festgelegt, dass jedes Hostsystem in der Lage sein muss; mindestens 576 Bytes pro Paket verarbeiten zu können. Dabei ist es übrigens unab- hängig ob die Pakete vollständig oder fragmentiert ankommen.

Hierin sind alle Header enthalten, bei obigen 512 Bytes kommen noch UDP- und IP-Header hinzu. Damit ist gewährleistet, dass das Gesamtpaket weniger als 576 Bytes hat.

Es gibt aber auch eine Erweiterung auf Paketgrößen bis 4096 Bytes Nutzlast was im Rahmen von IPv6 und DNSSec notwendig wurde. Dies muss aber explizit vom Client vermerkt werden. Das Verfahren nennt sich EDNS0. In diesem Rahmen lässt sich auch die Länge von Labels erhöhen.

RFC 2671 beschreibt dieses Verfahren, dazu kommt später noch etwas. Hier wird erst einmal nur der Paketaufbau nach [RFC 1035 (ftp://ftp.rfc-editor.org/in-notes/rfc1035.txt)] beschrieben.

Nun sind Zonentransfers gewöhnlich größer als 512 Bytes. Der Ausweg aus diesem Dilemma ist recht einfach, hier wird dann TCP verwendet, hier gilt die UDP-Größenbeschränkung nicht. Prinzipiell können aber auch alle Anfragen über TCP abgewickelt werden. Allerdings führt der Verbindungsaufbau und Verbindungsabbau zu einigem Overhead und verlangsamt die Namensauflösung deutlich.

DNS-Pakete bestehen aus 5 Teilen, von denen manche leer sein können:

  1. DNS-Header mit Flags, Ids,....
  2. Query, die eigentliche Anfrage
  3. Answer, die Antwort auf die Frage
  4. Authority, welcher Server ist zuständig (authoritive)?
  5. Additional, kann die IP-Adressen der authoritive Server enthalten

Formal ist der Aufbau somit:

    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

Header

Der DNS Header enthält folgende Felder (aus RFC 1035):

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
ID
ist ein 16-bit Identifier. Dieser Wert wird von dem Programm erzeugt, dass die Frage generiert. Das Antwortpaket muss die gleiche ID enthalten. UDP ist ein verbindungsloses Protokoll und daher ist diese ID dazu gedacht die Antworten zur Frage identifizieren zu können.
QR
Ein Wert von 0 signalisiert eine Frage, ein Wert von 1 eine Antwort.
Opcode
spezifiziert um welche Art von Frage es sich handelt:
Bedeutung der Opcodes
Opcode Bedeutung  
0 normale Standardfrage      
1 reverse Frage (Frage nach einem PTR-Eintrag)
2 Serverstatus        
3-15 reserviert für zukünftigen Gebrauch  
AA
Authoritative Answer, wenn dieses Bit in einer Antwort gesetzt ist, dann handelt es sich um eine authoritative Antwort (sie stammt nicht aus dem Cache!). Der Nameserver der diese Antwort liefert ist für diese Domain zuständig. Da die Antwort mehrere Namen beinhalten kann bezieht sich dieses Bit auf die Antwort die zur Frage passt oder aber auf den Eigentümer der ersten Antwort.
TC
Truncation, Kürzung. Wenn ein Antwortpaket größer als die erlaubten 512 Bytes ist, so wird das Paket auf diesen Wert gekürzt und dieses Bit gesetzt.
RD
Recursion Desired, rekursive Anfrage erwünscht. Dieses Bit signalisiert, dass der Anfragende eine rekursive Namensauf- lösung wünscht. Dieses Bit wird in die Antwort kopiert, diese Art der Namensauflösung ist aber optional.
RA
Recursion Available, rekursive Anfragen über diesen Name- server sind möglich wenn das Bit gesetzt ist. Dieses Bit ist nur in einem Antwortpaket sinnvoll.
Z
reserviert für den zukünftigen Gebrauch. Es muss derzeit sowohl in einer Frage als auch Antwort auf Null gesetzt sein.
RCODE
Response Code, wird als Teil der Antwort gesetzt.
Bedeutung der Response Codes
Wert Bedeutung
0 kein Fehler
1 Formatfehler, der Nameserver konnte die Frage nicht interpretieren
2 Serverfehler, der Nameserver war nicht in der    Lage die Frage zu bearbeiten weil er auf ein   Problem gestoßen ist
3 Name Error, nur von Bedeutung bei Anfragen an   einen authoritativen Nameserver, dieser Wert   zeigt an, dass der angefragte Domainname nicht existiert
4 nicht implementiert, der Nameserver unterstützt die Art der Anfrage nicht. Dies ist z.B. die Antwort, wenn rekursive Namensauflösung gewünscht ist, der Server dies aber nicht bereitstellt
5 zurückgewiesen, der Nameserver verweigert die Ausführung der Frage aus Policy-Gründen. Dies wird z.B. verwendet wenn ein Zonentransfer nicht erlaubt ist.
6-15 reserviert für zukünftigen Gebrauch
QDCOUNT
Zahl der Einträge in der Fragesektion (query section)
ANCOUNT
Zahl der RR's in der Antwortsektion
NSCOUNT
Zahl der Nameserver RR's in der Authority-Sektion
ARCOUNT
Zahl der RR's im zusätzlichen Bereich

Einige der reservierten Felder dürften mittlerweile auch vergeben sein, das RFC stammt aus dem Jahr 1987. Insbesondere EDNS0, dem Extension Mechanisms for DNS (EDNS0), fehlt hier noch, das wird für IPv6 und DNSSec benötigt.

Fragesektion

Dieser Bereich enthält die Frage, sie muss auch in der Antwort enthalten sein. Ihr Aufbau ist recht einfach, die Zahl der QNAME-Einträge ist gewöhnlich 1 und wird im Header angegeben:

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                     QNAME                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QTYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QCLASS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QNAME
ist der Domainname der als Folge von Labels angegeben wird. Dabei wird jeder Label durch ein Längenbyte gefolgt von der Zahl an Bytes dargestellt wird. Der Domainname wird durch ein Null-Längenbyte abgeschlossen.
QTYPE
spezifiziert die Art der Frage, hier sind alle Fragetypen aus einer Zone erlaubt und ein paar mehr, wie z.B. 252 (AXFR), Anfrage für einen Zonentransfer oder 255 (ALL), Frage nach allen Einträgen zum Domainnamen
QCLASS
gibt die gewünschte Klasse der Frage an, diese sollte IN sein. Ein Wert von 255 bedeutet irgendeine Klasse.

Antwortsektion, Authority und zusätzliche Sektion

Diese drei optionalen Einträge (in der Frage fehlen sie) haben alle den gleichen Aufbau: eine variable Anzahl an RR's. Dabei wird deren Zahl im Header angegeben. Jeder RR hat folgendes Format:

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
NAME
Domainname zu dem dieser RR gehört.
TYPE
Gibt den Typ im RDATA-Feld an.
CLASS
Klasse der Daten im RDATA-Feld, dürfte meistens IN sein.
TTL
Zeit in Sekunden wielange der RR gecachet werden darf
RDLENGTH
Länge in Bytes des RDATA-Feldes
RDATA
Zeichenkette variabler Länge, das Format ist durch den Typ und die Klasse bestimmt ist. Beim Typ A und Klasse IN ist das RDATA-Feld 4 Bytes lang (IPv4 Adresse).

Komprimierung

Um die Größe der Mitteilungen zu reduzieren kann ein Kompressionsverfahren verwendet werden um die Wiederholung gleicher Domainnamen oder Labels einzusparen. Dadurch kann ein kompletter Domainname oder eine Liste von Labels am Ende eines Eintrages durch einen Zeiger auf einen vorherigen Eintrag ersetzt werden.

Dieser Zeiger hat folgenden Aufbau:

    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    | 1  1|                OFFSET                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Hier wird es jetzt interessant. Die ersten beiden Bits sind auf eins gesetzt, d.h. sie können nicht mit einem Längenfeld für ein Label verwechselt werden. Zur Erinnerung: Labels dürfen nur 63 Bytes lang sein, d.h. die ersten beiden Bits des Längenfeldes sind zwei Nullen! Jetzt wird auch klar warum Labels auf 63 Bytes in der Länge begrenzt sind.

Der OFFSET gibt den Abstand vom Anfang des Pakets an, d.h. bei einem Wert von Null wird auf das ID-Feld.

Dieses Kompressionsverfahren erlaubt es einen Domainnamen auf drei Arten darzustellen:

Jetzt wird klar, warum es nur 13 offizielle Root-Nameserver gibt und diese sich alle in der gleichen Domain "root-servers.net" befinden und der Hostname jeweils nur ein Byte (A - M) lang ist, hierdurch wird eine maximale Komprimierung ermöglicht.

Diese 13 Nameserver werden alledings derzeit durch 34 Server realisiert. Da nur 13 IP-Adressen existieren kommt hier das anycasting zum Einsatz: Mehrere Server ( C, F, I, J, K und M) teilen sich jeweils die gleiche IP-Adresse. Dabei routen die ISP's zu dem nächstgelegen Router.

Sicherheitsbetrachtungen

Da UDP ein verbindungsloses Protokoll ist birgt es ein gewisses Sicherheitsrisiko. Dass eine Antwort wirklich zu der gesendeten Frage gehört wird dabei durch 3 Dinge verifiziert:

  1. Das Query-Feld muss die ursprüngliche Frage enthalten.
  2. Die IP-Adresse und der UDP-Port müssen stimmen.
  3. Das ID-Feld muss den gleichen Wert haben.

Man könnte meinen, dass dies ausreicht um sicherzustellen, dass die Antwort wirklich zur Frage gehört. Leider ist dem jedoch nicht so.

Ein Verfahren um einen Nameserver zu falschen Antworten zu bringen nennt sich Cache Poisoning. Es gibt noch zahlreiche andere Verfahren, die meisten wurden aber durch aktuellere Versionen von BIND entschärft. Daher beschränke ich mich hier auf ein noch immer mögliches und verwendetes Verfahren.

Der Schlüssel besteht darin, dass rekursive Anfragen für alle Resolver erlaubt sind. Das ist die Voreinstellung der meisten Nameserver, sie erlauben jedem Client rekursive Anfragen zu stellen.

Innerhalb von Firmennetzen ist dies auch legitim, die DNS-Anfrage wird an den eigenen Nameserver weitergeleitet, dieser erfragt die Antwort im Internet und liefert diese zurück.

Worin besteht jetzt das Problem wenn dies jeder kann?

Ganz einfach: Ein Angreifer stellt rekursiv eine Anfrage für einen Domainnamen dessen IP-Adresse er verbiegen will. Als erstes sollte er sicher sein, dass sich dieser nicht im Cache befindet. Da heutzutage aufgrund von Loadbalancing manche Nameserver eine extrem kleine TTL ausliefern erleichtert dies einem Angreifer das Leben ungemein.

Nun wird eine Anfrage rekursiv an den Nameserver gesellt. Der Nameserver muss als Folge eine Anfrage an den Server dieser Domain stellen. Da bekannt ist welche Server das sind und wann die Anfrage losgeschickt wird ist die Hälfte schon erledigt.

Alles was ein Angreifer nun tun muss ist anstelle des eigentlichen Nameservers zu antworten. Da das verwendete Protokoll UDP ist kann eine Absendeadresse in der Regel beliebig gefälscht werden.

Jetzt bleiben noch zwei Probleme:

  1. Der UDP-Port muss stimmen.
  2. Die ID muss korrekt sein.

Wenn es also gelingt den UDP-Port zu bestimmen und die ID zu erraten, dann hat der Angreifer so gut wie gewonnen. Alte Nameserver (BIND Version 4) verwendeten als UDP-Absendeport ebenfalls den Port 53, das machte es recht leicht diesen zu raten. (Das dürfte wohl auch der Grund sein warum neuerer Versionen von BIND dies nicht mehr tun!)

Viele setzen den Source-Port der Anfrage aber fest um dann über Paketfilterregeln festlegen zu können was erlaubt ist und was nicht. Wenn also dieser Port einmal herausgefunden wurde ist der Angreifer einen guten Schritt näher am Ziel.

Alles was dafür benötigt wird ist eine rekursive Anfrage zu einem Nameserver auf den ein Zugriff besteht. Dann kann leicht mitgesnifft werden, z.B. via tcpdump, von welchem Port die Anfrage kommt. Oft können so auch Hinweise auf die Art der ID-Vergabe bekommen werden.

Manche wählten zudem recht einfache ID-Schemata, sie zählten dieser einfach hoch anstatt sie zufällig zu wählen.

Selbst wenn die ID unbekannt ist, so sind maximal 65535 UDP-Pakete notwendig um eine Antwort zu fälschen, das ist bei heutigen sehr schnellen Netzwerken kein Problem mehr diese Zahl an Paketen in endlicher Zeit zu versenden.

Eine aggressivere Variante nennt sich Birthday Attack, diese geht auf die überraschend klingende Wahrscheinlichkeit von mehr als 50% zurück, dass 2 oder mehr Leute aus eine Gruppe von 23 am gleichen Tag Geburtstag haben.

Nun wie kann sich jemand diese Erkenntnis zunutze machen? Ganz einfach, werden deutlich mehr Anfragen für den gleichen DNS-Namen gesendet, so kann mit knapp 300 Datenpaketen ein DNS-Eintrag mit 50% Wahrscheinlichkeit gefälscht werden.

Was ist wenn der Original-DNS-Server antwortet? Das ist aus Sicht eines Angreifers in der Tat ein Problem, er muss seine korrekt geratene Antwort lossenden bevor dieser Server antwortet. Um dies zu gewährleisten wird gewöhnlich eine (D)DoS Attacke parallel gegen diesen Server gefahren.

Dieses Problem führen Autoren gerne an um auf die Designschwäche von BIND zu hinzuweisen. Ein besonderer Vertreter dieser Gattung ist Daniel J. Bernstein der mit seinem DNS-Server djbdns eine angeblich sichere Variante erstellt hat.

Dabei hat BIND schon lange ein Lösung für dieses Problem, es kann explizit eingeschränkt werden wer rekursive Anfragen stellen darf. Es verbleibt dann noch das Restrisiko das der Angreifer einfach eine Adresse als Absender verwendet die rekursiv anfragen darf.

Allerdings sollte soetwas von jeder guten Firewall geblockt werden da die Pakete über ein falsches Interface eintreffen.

Zu den behobenen Problemen zählt übrigens auch, dass nicht explizit überprüft wurde ob die Antwort überhaupt zur Frage passt. Aber diese Lücken sind mittlerweile längst behoben und es gibt Leute die sich beschweren, dass der BIND in der aktuellen Version zu pingelig wäre.

Aber das ist das alte Thema: Entweder Software ist tolerant und verringert dadurch die Sicherheit oder sie ist sehr strikt und verwirft alle Antworten die nicht 100% korrekt sind.

Zum Glück hält sich BIND an die zweite Variante. Würden Webbrowser auch so konsequent sein, dann gäbe es heute nicht so viele Sicherheitsprobleme in diesem Bereich.

IPv6

Da die Zahl der möglichen IP-Adressen von IPv4 mit ca. 4 Milliarden als zu gering für diese Welt angesehen wurde (und die Verteilung mehr als ungerecht) gibt es Bestrebungen das IP-Protokoll zu erneuern.

Aktuell in der Diskussion ist die Version 6 des Internetprotokolls, dieses wird hauptsächlich im asiatischen Raum vorangetrieben. Der Grund dürfte darin zu finden sein, dass Asien die meisten Einwohner aber wohl fast die wenigsten IP-Adresse bekommen hat. (Gut Afrika und Südamerika haben noch weniger Adressen. Aber dort ist die Zahl der Einwohner die zudem an Internet partizipieren wollen deutlich geringer.)

Es gibt aber noch mehr Aspekte die einen Wechsel des Protokolls ratsam erscheinen lassen. Hierunter zählen auch Sicherheitsprobleme. So ist IPSec ursprünglich für IPv6 entwickelt worden.

Hier betrachten wir aber nur die IPv6-relevanten Details für das DNS.

Allgemeines

Die Adresslänge ist bei IPv4 32 Bit was zu 2^32 möglichen Adressen führt. Das sind dann rund 4 Milliarden Adressen.

Bei IPv6 wird das Adressfeld auf 128 Bits erweitert. Wer nun glaubt, das wären viermal soviele Adressen hat sich leicht verrechnet. Es sind vielmehr:

340282366920938463463374607431768211456

oder 3.4*10^38 Adressen.

Die Erde hat einen Durchmesser von rund 6350km, d.h. die Erdoberfläche inklusive der Meere hat eine Größe von ca. 2109754894419566239897118 m^2. Als Hausaufgabe überlasse ich Euch dann auszurechnen wieviele Geräte in einem Haushalt eine eigene IP-Adresse bekommen können...

Und dabei sind Mond und Mars noch garnicht eingeplant.

Die alte Schreibweise mit Punkten als Trennschema der Blöcke ist hier nicht mehr praktikabel, statt 4 hätte wären es 16 Blöcke.

Stattdessen werden nun zwei Bytes zu einem Block zusammenge- fasst und diese 8 werden durch Doppelpunkte getrennt, z.B.:

2006:1204:0123:4567:89ab:cdef:0123:4567

Um die Schreibweise weiter zu vereinfachen können führende Nullen in einem Block weggelassen werden. Also kann genausogut geschrieben werden:

2006:1204:123:4567:89ab:cdef:123:4567

Ferner können mehrere Null-Blöcke durch "::" abgekürzt werden. Dies geht natürlich nur einmal pro Adresse. Die einfachste Adresse ist vermutlich die neue Loopback-Adresse:

::1

Die Adressen werden formal wie bisher in drei Teile gegliedert:

  1. globaler Routingprefix
  2. Subnetz-ID
  3. Interface-ID

Da die Adressen nun deutlich größer sind und UDP DNS-Pakete auf 512 Bytes beschränkt sind musste eine Möglichkeiten gefunden werden diese Grenze zu verschieben.

Dies kann mit EDNS0: Extended mechanism for DNS, version 0 aus RFC 2671 realisiert werden. Damit sind Paketgrößen bis 4096 Bytes möglich. Allerdings muss in der Anfrage explizit vermerkt sein, dass der Anfragende in der Lage ist damit umzugehen.

1. Ansatz

Bei IPv4 sind A-Records 32-bit Adressen, dies legt nahe für IPv6 den Typen AAAA einzuführen (4*32=128, also 4*A):

ipv6-host IN AAAA 2006:1204:123:4567:89ab:cdef:123:4567

Bei den reverse-Einträgen kann leider nichts abgekürzt werden:

7.6.5.4.3.2.1.0.f.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.4.0.2.1.6.0.0.2.ip6.arpa.   IN   PTR   ipv6-host

Ursprünglich hieß die reverse-Zone ip6.int, diese wurde aber in ip6.arpa umbenannt. Dieses Verfahren ist auch das alte und wieder das aktuelle, neue Verfahren. Zwischenzeitlich gab es noch einen anderen Ansatz.

Da dieser mittlerweile nicht mehr aktuell ist kann dieser als obsolet betrachtet werden. Allerdings war er zwischenzeitlich aktuell und daher kann die eine oder andere Implementation diesen noch verwenden.

2. Ansatz

Bei diesem Ansatz bestand die Idee darin einen Adresswechsel von einem ISP zu einem anderen zu erleichtern. Prinzipiell könnten die Interface-IDs beibehalten werden und nur der Provider ändert die Subnetz-ID.

Diese Records wurden A6 getauft und können auch nur einen Teil spezifizieren:

ipv6-host.movie.edu.   IN  A6  64  ::89ab:cdef:123:4567   subnet1.v6.movie.edu.
^<<

Die Zahl 64 gibt nun an wieviele Bits zur kompletten Adresse
fehlen. Diese Bits werden durch ''subnet1.v6.movie.edu.'' näher
spezifiziert, z.B.:

^<<
$ORIGIN v6.movie.edu.
subnet1.v6.movie.edu.  IN  A6  48  0:0:0:1::  movie-u.isp-a.net.
subnet1.v6.movie.edu.  IN  A6  48  0:0:0:1::  movie-u.isp-b.net.

Hier sind Adressen von zwei Providern angegeben, diese bestimmen die fehlenden Teile näher, z.B. könnte der von dem ersten ISP so asussehen:

movie-u.isp-a.net.   IN   A6  50 0:0:21::  isp-a.rir-1.net.

Dieser hat vielleicht seine Registrar-Adresse:

isp-a.rir-1.net.   IN   A6  36  0:0:0500:: rir2.top-level.v6.net.

Und beim Toplevel-Registrar endet die Kette:

rir2.top-level.v6.net.   IN  A6  0  2006:1204::2

Alles zusammen ergibt dann die vollständige Adresse.

Wie leicht zu erkennen ist war dieses Verfahren von der Idee her nicht schlecht, nur die Realisierung konnte zu vielen einzelnen DNS-Anfragen führen. Dies hätte die Namensauflösung aber mitunter erheblich verzögert.

Daher wurde der 1. Ansatz wieder herangezogen, allerdings mit ip6.arpa statt ip6.int für die reverse Zone.

Eine Anmerkung noch zum Schluss
DNS-technisch gesehen stellt der Umstieg auf IPv6 kein großes Problem dar. Allerdings arbeiten die meisten Netzwerkapplikationen intern mit 32-bit Speicherstellen für IP-Adressen. Es genügt also nicht einfach eine IPv6-Adresse zu binden und den Nameserver umzustellen!

Domains mit Umlauten

Genaugenommen handelt es sich um internationlisierte Domains, d.h. hierunter fallen auch z.B. die asiatischen Darstellungen. Aber von Interesse sind hier, wenn überhaupt, wohl in erster Linie die Umlautdomains a la www.müller.de.

Der offiziell Name ist auch Internationalizing Domain Names in Applications'' (IDNA) und wird in RFC 3490 beschrieben.

Um das Leben von DNS-Serverbetreiber zu erleichtern kommt das sogenannte ACE zum Einsatz: ASCII Compatible Encoding. Dabei werden die Sonderzeichen so kodiert, dass sie über einen reinen ASCII-String darstellbar sind. Auf diese Weise ändert sich für Betreiber von Nameservern nichts.

Die Umwandlung in reine ASCII-Strings muss; die Applikation und nicht der Resolver vornehmen. Für die Codierung kommt der sogenannte Puny-Code mit Delta-Kodierung zum Einsatz. Dieses Verfahren wird in RFC 3492 ( beschrieben.

Vereinfacht ausgedrückt wird nur der Label bearbeitet indem ein nicht-ASCII Zeichen verwendet wird. Diesem Label wird ein xn-- vorangestellt. Das oder die nicht-ASCII Zeichen werden dann weggelassen und codiert mit einem Minus-Zeichen angehängt.

Die Kodierung beinhaltet sowohl die Art des Zeichens sowie die Position im Lrwendet wird ist eine andere Frage, aber es gab eine Firma in Redmond die dieses Verfahren sehr gefördert hat. Dabei werden in den Bereichen bei denen mehrere Systeme vernetzt sind gewöhnlich RFC 1918 Adressen hinter einer Firewall verwendet. Von diesen Adressen gibt es bekanntlich reichlich.

Es gibt mehrere Varianten wer wie dyn-DNS Einträge vornehmen kann. Ratsam ist es hier, nur dem DHCP-Server dies zu erlauben wenn er eine neue IP-Adresse vergibt.

Theoretisch kann es auch den Clients selber überlassen werden und bei dem Betriebssystem aus Redmond ist dies die Voreinstellung. Das ist dann besonders interessant wenn ein Client auch noch Namen verändern darf und dadurch einen Servernamen auf seinen Client legt.

Um die Problematik noch weiter zu treiben kann sich ein Client mit dem lokalen Nameserver für dynamische Einträge verbinden und diesen beauftragen dies in anderen Domains oder Servern vorzunehmen. Letzteres kann dann sinnvoll sein, wenn der eigene Nameserver nur ein slave der Zone ist.

Aus all diesen Gründen ist eine Absicherung notwendig, so sollte nur dem DHCP-Server dieses Verfahren erlaubt werden und dies zudem über einen Key abgesichert werden.

Bei BIND funktioniert das mit TSIG, einer Transaktionssignatur. Dazu wird ein one-way Hash auf Basis eines geteilten Geheimnisses verwendet.

Da sich die Zonen nun dynamisch verändern ist es auch ratsam inkrementelle Zonentransfers zu ermöglichen. Anderenfalls müsste bei jeder Namensänderung immer die komplette Zone zu allen slave Servern transferiert werden.

Daher wurden die inkrementellen Zonentransfers eingeführt. Dabei muss der Server sich den Zustand der Zonendatei über mehrere Änderungen (Seriennummern) merken um lediglich die Unterschiede transferieren zu können. Der slave meldet dabei, welche Seriennummer seine Zonendaten haben und der master überträgt nur die Änderungen.

Hat der master diese nicht mehr parat, z.B. weil er einmal neu gestartet wurde, so wird die vollständige Zone neu übertragen.

Notifys

Normalerweise verifiziert ein slave Nameserver nach der Refresh-Zeit ob die Zone noch aktuell ist. Nun wäre es doch eigentlich recht interessant wenn der master Nameserver seine slaves darüber informieren würde wenn sich an einer Zone etwas geändert hat.

Dieses Verfahren existiert und nennt sich DNS Notify. Dies funktioniert auch zwischen zwei slave Nameservern da auch hier Zonentransfers möglich sind.

Hierbei sendet der Nameserver den Namen der Zone sowie die aktuelle Seriennummer an alle anderen slaves. Die slaves können dann feststellen wie aktuell ihre Zone ist und gegebenenfalls einen Zonentransfer anfordern. Dies wirkt aber nur hinsichtlich dem Abgleich von Zonen, nicht jedoch wenn gecachete Werte sich geändert haben, das wäre auch illusorisch.

DNSSec

Die DNS Security Extension ist ein vergleichsweise neues Verfahren um das DNS sicherer zu machen. Ursprünglich wurde das Verfahren in RFC 2065 beschrieben, es wurde aber in [RFC 4033 (ftp://ftp.rfc-editor.org/in-notes/rfc4033.txt)], [RFC 4034 (ftp://ftp.rfc-editor.org/in-notes/rfc4034.txt)] [RFC 4035 (ftp://ftp.rfc-editor.org/in-notes/rfc4035.txt)] wesentlich überarbeitet. Demzufolge unterstützen nicht viele Nameserver das aktuelle DNSSec Verfahren.

Wenn DNSSec eingesetzt werden sollte, so ist es ratsam BIND Version 9.3.2 oder neuer zu verwenden.

Public-Key Verfahren

DNSSec setzt auf das asymmetrische Public-Key Verfahren. Bei diesem Verfahren werden zuerst zwei Keys in einem Prozess generiert: ein öffentlicher Schlüssel (public key) und ein privater Schlüssel (private key).

Das besondere ist, daher stammt auch der Name asymmetrisches Verfahren, dass Nachrichten die mit dem private key verschlüsselt wurden mit dem public key entschlüsselt werden können.

Daher stammt auch der Name der Schlüssel

Beim symmetrischen Verfahren wird mit dem gleichen Schlüssel sowohl ver- als auch entschlüsselt. Daher muss hier jeder beteiligte den gleichen Schlüssel kennen und von diesen kann jeder eine Nachricht verschlüsseln.

Beim asymmetrischen Verfahren kann das nur derjenige, der den privaten Schlüssel besitzt!

Der Nachteil dieses doch sehr eleganten Verfahrens ist jedoch die Geschwindigkeit, diese ist um Größenordnungen langsamer als bei einem symmetrischen Verfahren.

Signaturen

Da der Inhalt der Zoneneinträge oder der Zonen selber nicht geheim gehalten werden braucht bietet sich ein Verfahren an, dass weniger zeitintensiv ist: Auf die Daten wird ein One-Way Hash-Verfahren angewendet. Dieser Hash wird mit dem private key verschlüsselt.

Dieses Verfahren wird signieren genannt.

Nun können die Daten (unverschlüsselt) zusammen mit dem verschlüsselten Hash versendet werden. Der Empfänger trennt die Daten von der Signatur, entschlüsselt diese und erhält den ursprünglichen Hash-Wert. Gleichzeigt berechnet er über die unverschlüsselten Daten den gleichen One-Way Hash.

Sind diese beiden Hash-Werte identisch, so ist sofort klar, dass diese nur von demjenigen stammen können, der den zum public key gehörenden private key besitzt!

Problem
Ein Problem besteht immernoch: Woher bekommt man den public key und woher weiß man, dass dieser der richtige ist?
Lösung
Der Nameserver verteilt den public key, dazu wurde der Record- Typ DNSKEY eingeführt. Der public key kann also vom Nameserver selber erfragt werden und wird Base64 codiert ausgeliefert.

Dieser Key ist in der Zonendatei. Es gibt noch einen weiteren Record-Typ: RRSIG. Dies ist jeweils mit dem private key signierte Resource Record

Nun ist der public key bekannt und die RR's können validiert werden. Allerdings: Was ist mit negativen Antworten?

Wenn ein RR nicht existiert: Wie soll das signiert werden?

Die Antwort ist der Record-Typ NSEC, er zeigt auf den nächsten existierende RR der wiederum korrekt signiert werden kann. Ein einfacher globaler Eintrag für negative Antworten wäre schlecht, der könnte abgefragt und für alles mögliche wiederverwendet werden.

Dilemma
Wie kann sichergestellt werden, dass der richtige Nameserver geantwortet hat? D.h. woher weiß ich, dass der public key korrekt ist?

Hier kommt die Chain of Trust, die Kette des Vertrauens, ins Spiel: Der public key muss von einer höheren Stelle zertifiziert werden. Diese bestätigt, dass der public key der Korrekte ist. Diese Stelle ist idealerweise der Parent der Zone, dieser gibt schließlich auch Auskunft darüber welcher Nameserver für die Zone zuständig ist. Da ist es naheliegend eine Signatur des public keys mitzusenden.

Dafür existiert der Record-Typ DS (delegation signer), dieser beinhaltet den signierten public key der delegierten Zone. Warum dies nur eine Signatur des Keys ist sollte jetzt wohl klar sein.

Wie kann sichergestellt werden, dass die Parent Zone auch wirklich
diese ist?

Ganz einfach, sie wird ebenfalls von dessen Parent Zone zertifiziert. Dies geht soweit bis man bei den Root-Nameservern angelangt ist.

Die public keys der Root-Nameserver hingegen sollten zum einen allgemein bekannt sein und zum anderen in jedem Nameserver hinterlegt sein der DNSSec unterstützt.

Neue Flags

Neben den vier neuen Record-Typen gibt es auch drei neue Header Flags. Es ist wohl unnötig extra zu erwähnen, dass EDNS0 verwendet werden muss um wegen der Key-Längen UDP-Pakete größer 512 Bytes verwenden zu können.

Die Flags sind:

DO
DNSSec Ok, der Anfrager versteht DNSSec und möchte DNSSec-bezogene Antworten
AD
Authenticated Data, damit kann ein DNSSec-Nameserver in der Antwort Kennzeichnen, dass er alle DNSSEC-bezogenen Antworten verifiziert hat
CD
Checking Disabled, hiermit kann ein Resolver kennzeichnen, dass er selber in der Lage ist die Daten zu verifizieren und der Nameserver dies nicht tun muss

Das ist im wesentlichen DNSSec, es gibt noch ein paar Feinheiten wie die Verwendung von verschiedenen Keys zur Signierung von anderen Keys und der Zone (Key-Signing-Key, Zone-Signing-Keys) aber das ändert nichts an der Funktionalität.

DNSSec kann auch verwendet werden um dynamische Updates zu signieren. Dies kann BIND 9 on the fly

Großes Dilemma

Damit DNSSec einwandfrei funktioniert muss die Chain of Trust existieren. Nur leider unterstützt derzeit kein Root-Nameserver DNSSec! Von den Toplevel-Domains wird DNSSec nur von der ccTLD se, also Schweden unterstützt.

Der Aufwarnd durch Signieren, Ver- und Entschlüsseln sowie die vergrößerten Datenpakete stellen auch ein großes Problem hinsichtlich der Performance dar.

Alles in allem ist die Zukunft vermutlich ähnlich wie bei IPv6, es ist ziemlich ungewiss wann (und ob?) sich das durchsetzt.

BIND - Historie

Der erste Nameserver hieß JEEVES und wurde von Paul Mockapetris, dem Erfinder des DNS geschrieben.

Die Berkeley Internet Name Domain Software entstand als eine DNS Implementierung im Rahmen einer Diplomarbeit (graduate student project) an der Universität in Berkeley. Diese wurde von (D)ARPA gesponsort (dem Initiator des Arpa- und späterem Internet).

Weiterentwickelt wurde BIND dann bei DEC von Kevin Dunlop (1985- 1987 und später Paul Vixie, der die Versionen 4.9 und 4.9.1 herausbrachte. Dieser verließ 1994 DEC um mit Rick Adams und Carl Malamud BIND ab Version 4.9.3 zu entwickeln und zu supporten. Dazu gründeten sie das Internet Software Consortium (ISC) das seit 2004 Internet Systems Consortium heißt.

Hier werden neben den aktuellen BIND-Versionen auch DHCP, INN, OpenReg und NTP verwaltet. Einer der 13 root-Nameserver werden vom ISC betrieben. Dies alles ist zu finden unter

http://www.isc.org/

Das ISC ist eine nicht-kommerzielle Einrichtung, die Sourcen sind frei und unterliegen - wie hätte es bei dem Namen auch anders sein können - der BSD-Lizenz.

BIND gibt es übrigens auch für Windows.

Der erste produktionsreife Version BIND Version 8 erschien im Mai 1997 und war eine Neuimplementierung des DNS.

Im September 2000 erschien die Version 9 bei der sehr viele Teile der Software neu geschrieben wurden. Diese Version wird von vielen Firmen unterstützt.

BIND Version 4 ist durchaus noch in Gebrauch, es wird aber davon abgeraten da diese Version u.a. viele neue Features nicht kennt bzw. mit diesen nicht umgehen kann.

BIND Version 8 ist maintenance-only, d.h. diese Version wird nicht mehr aktiv weiterentwickelt und es werden nur noch Bugs behoben. Es werden aber sowohl für BIND 4 und BIND 8 noch sicherheitsrelevante Patches erstellt.

Aktuell verwenden sollte jeder BIND Version 9, derzeit ist die letzte stabil deklarierte Version 9.3.2-P4.

Installation

Die meisten Distributionen sollten bereits eine Version von BIND 9 bereitstellen und die Installation ist dann recht einfach.

Aber auch wenn man von den Sourcen aus installieren möchte ist dies recht einfach:

  1. Sourcen von ISC holen
  2. Entpacken: tar xvzf bind-9.3.2-P2.tar.gz
  3. in das Verzeichnis wechseln und configure aufrufen: cd bind-9.3.2-P2; ./configure Soll IPv6 aktiviert werden, so benötigt man noch die configure-Option --with-ipv6
  4. make all aufrufen (all kann auch weggelassen werden).
  5. wenn alles sauber durchgelaufen ist: make install

Das war die Installation in aller Ausführlichkeit! Per default wird die Konfigurationsdatei /etc/named.conf verwendet.

Bei allen weiteren Betrachtungen beziehe ich mich nur noch auf BIND Version 9

Konfiguration

Die Konfigurationsdatei ist gewöhnlich /etc/named.conf, der Serverdienst heißt named, sie kann aber beim Starten von named auf der Kommandozeile angegeben werden.

Es gibt nicht viele Kommandozeilenparameter von named:

-4
verwende nur IPv4, kann nicht mit -6 verwendet werden
-6
verwende nur IPv6, kann nicht mit -4 verwendet werden
-c config-file
gibt an, was die Konfigurationsdatei für named ist und wo sie liegt
-d debug-level
hiermit kann man named explizit im Debugmodus starten, es gibt aber eine elegantere Methode das Debugging beim laufenden named einzuschalten bzw. zu erhöhen durch die

  Verwendung von rndc.

-f
starte den named im Vordergrund, keine Daemonisierung

-g
das gleiche wie -f, jedoch wird nach stderr geloggt anstelle von syslog, sehr hilfreich zum debuggen in Verbindung mit -d
-n Zahl-der-CPUs
hierdurch wird die Zahl der Arbeitsthreads bestimmt, wenn nicht angegeben, dann verwendet named soviele Threads wie er CPUs findet.
-p port
der Port auf dem named lauschen soll, gewöhnlich 53
-s
Speicherverbrauchsstatistiken werden beim Beenden aus- gegeben, eigentlich nur für BIND 9 Entwickler interessant
-t
Verzeichnis named führt ein chroot() in dieses Verzeichnis nach dem Starten aus, dabei wird zuerst die Kommandozeile ausgewertet aber die Konfigurationsdatei noch nicht gelesen. Beachte: Diese Option erhöht die Sicherheit von named, allerdings nur in Verbindung mit der Option -u um den Usernamen zu ändern!

-u User
nachdem alle privilegierten Prozesse abgearbeitet sind, wie z.B. das Öffnen von Port 53, wechselt der named Prozess seine UID zu einer nicht-priveligierten. Damit können mögliche Exploits von named nicht automatisch zu root- Rechten führen. Unter Linux (ab Kernel 2.2.18) verwirft named alle Rechte au$szlig;er dem sich an ein Interface zu binden.
-v
gibt lediglich die Versionsnummer aus
-x cache-file
nur für BIND 9 Entwickler interessant

Durch das Senden eines SIGHUP-Signals an den named-Prozess lädt dieser seine Konfiguration neu ein. Es sollte stattdessen aber besser das Kommandozeilentool rndc verwendet werden.

Aufbau named.conf

Der große Vorteil von BIND 9 ist, dass viele Optionen global wie unter BIND 8 aber auch nur innerhalb von Zonen angegeben werden können. Letzteres war mit BIND 8 nicht möglich.

Kommentare in der Konfigurationsdatei können sowohl in der C (/* ... */), C++ (//), Unix-Syntax (#) sowie durch ein vorgestelltes Semikolon angegeben werden.

Es können auch Dateien über

include Pfadname;

eingelesen werden, bzw. auf diese Weise ist es möglich Teile aus der zentralen Konfigurationsdatei auszulagern. Das kann interessant werden, wenn diese Teile von anderen verwaltet werden sollen die keine Root-Rechte haben und in der named.conf keys stehen.

Optionen

Globale Optionen werden durch das options-Statement angegeben, z.B.:

   options 
     {
        directory "/var/named"; 
     };

Es kann nur einen options-Eintrag geben, hier können aber beliebig viele Einträge vorgenommen werden. Derzeit gibt es über 100 Optionen auf die ich nicht alle eingehen werde.

ACL

Ferner gibt es ACL's:

  acl string { Adressenliste ; ... };

z.B.

  acl "intern" { 10.0.0.0/8; };

Diese können dann innerhalb von Optionen verwendet werden. Die Hochkommata ermöglichen es ACL-Namen von existierenden Optionsnamen zu unterscheiden.

Es existieren vier vordefinierte ACLs:

none
keine IP-Adresse
any
alle IP-Adressen
localhost
alle IP-Adressen die der lokale Computer besitzt
localnets
alle direkt angeschlossenen Netze (identifiziert über die Interface-Adressen und -Netzmasken)

KEY

Dieser Eintrag wird verwendet um TSIG, Transaktionssignaturen, anzugeben. Diese Keys können über One-Way Hash-Funktionen dazu verwendet werden zum Einen Authentisierungen zu gewährleisten, z.B. für dyn-DNS oder aber zum Anderen um Zonendateien zu signieren.

Das Format ist

    key domain-name 
       { 
          algorithm string;
	  secret "string";
       }

Derzeit werden nur HMAC-MD5 mit 128 Bit unterstützt. Das secret muss auf beiden Seiten bekannt sein, daher ist dies nur begrenzt Einsatzfähig, z.B. für dyn-DNS oder Zonentransfers bei denen diese Keys leicht geteilt werden können.

Als Key-Name wird angeregt einen Pseudo-Domainnamen mit beiden Hostnamen die diesen Key teilen zu verwenden, also z.B.:

   key ns1-ns2.lug-erding.de
      {
         algorithm hmac-md5;
	 secret "qWuJdSm+DJMZfxXGbAEEZg==";
      }

Der binäre Key ist hier Base64 kodiert.

controls

Hiermit kann der rndc-Zugriff auf den Nameserver konfiguriert werden. Mit rndc kann der Nameserver von außen beeinflusst werden, näheres gibt es später.

  controls 
    {
      inet ( IPv4-Adresse  | IPv6-Adress | * ) [ port (Zahl | * )]
           allow { ACL; ... } [ keys { string; ...} ];
    };

z.B.:

  controls { inet 127.0.0.1 port 953 allow { localhost; }; };

server

Dies kann verwendet werden um remote Nameserver näher zu spezifizieren:

  server ( IPv4-Adresse | IPv6-Adresse ) 
    {
      bogus boolean;
      edns boolean;
      provide-ixfr boolean;
      request-ixfr boolean;
      keys server_key;
      transfers integer;
      transfer-format ( many-answers | one-answer );
      transfer-source ( ipv4_address | * ) [ port ( integer | * ) ];
      transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ];
    };

Die meisten Optionen sollten selbsterklärend sein. Ein Nameserver der als bogus true; deklariert ist wird ignoriert. Dies ist oft hilfreich wenn ein Server falsch formatierte Antworten ausliefert und der Administrator nicht bereit ist dies zu beheben.

logging

Das Logging-Verhalten von BIND kann durch dieses Schlüsselwort näher spezifiziert werden:

       logging {
            channel string {
                 file log_file;
                 syslog optional_facility;
                 null;
                 stderr;
                 severity log_severity;
                 print-time boolean;
                 print-severity boolean;
                 print-category boolean;
            };
            category string { string; ... };
       };

Das meiste ist vermutlich wieder selbsterklärend. Es existieren verschieden Channels die definiert werden können. Vordefiniert sind default_syslog, default_stderr, default_debug und default_null. Der letzte Channel verwirft dabei einfach alle Meldungen. Diese vier können nicht umdefiniert werden.

Über das category Statement kann jetzt das Logging-Verhalten beeinflusst werden, z.B. loggt dies alle Bearbeitungsmeldungen der Konfigurationsdatei nach syslog:

   logging { category config { default_syslog; }; };

Es gibt eine Vielzahl von Kategorien:

default
   alles was sonst nicht abgedeckt wird
general
   alles nicht speziell klassifiziert sind
client
   Bearbeitung von Client-Anfragen
config
   Bearbeitung der Konfigurationsdatei
database
  interne BIND Datenbank, Zonendaten und Cache
dnssec
   Alles rund um DNSSec
lame-servers
Entdeckung falscher Delegationen
network
   Netzwerkoperationen
notify
   asynchrone Benachrichtigungen über Zonenänderungen
queries
   Loggen der Anfragen
resolver
  Namensauflösung
security
  geprüfte/ungeprüfte Anfragen
update
   dynamische Updates
update-security
unbestätigte dynamische Updates
xfer-in
   eingehende Zonentransfers
xfer-out
  ausgehende Zonentransfers

Dies alles zeigt wie flexibel BIND ist. Wer nun das Gefühl hat, dass BIND viel zu kompliziert ist: Der default passt fast immer, es ist extrem selten, dass hier etwas geändert werden muss.

trusted-keys

Diese Keys sind für DNSSec notwendig und können in der named.conf angegeben werden:

    trusted-keys 
      {
         domainname flags protokol algorithm key; ...
      };

Dies ist dann notwendig, wenn die Chain of Trust unterbrochen ist oder nicht existiert. Hiermit können dann keys eingetragen werden denen man vertraut.

lwres

Diese Optionen sind für den lightweight resolver daemon, ein abgespeckter caching only Nameserver. Da ich hier nicht näher darauf eingehe (ich wüsste auch nicht wer diesen benutzt) spare ich mir diesen Part. Obwohl es ein separates Programm ist benutzt es die gleiche Konfigurationsdatei named.conf:

   lwres 
     {
        listen-on [ port integer ] 
          {
             ( ipv4_address | ipv6_address ) [ port integer ]; ...
          };
        view string optional_class;
        search { string; ... };
        ndots integer;
     };

zone

Eine Zone wird durch das zone-Statement definiert:

  zone Zonen-Name optionale-Klasse 
    {
      type (master | slave | stub | hint | forward | delegation-only);
      file "Dateiname";
      masters { .... };
      diverse optionen 
      ...
   }

Einer der großen Vorteile von BIND 9 ist der, dass hier im Zoneneintrag ebenfalls Optionen angegeben werden können die die globalen überschreiben.

Die Typen master und slave sollte mittlerweile klar sein, hint ist der Hinweis auf die Root-Nameserver. Forward ist interessant, hierdurch können einzelne Domains an andere Server weitergeleitet werden. Dies kann innerhalb einer durch eine Firewall geschützten Umgebung sehr hilfreich sein.

Hier wird meistens ein globaler forward-Eintrag auf einen Nameserver der Firewall weitergeleitet. Der Nameserver kann dann nur Anfragen selber beantworten für die er zuständig ist oder diese an die Firewall weiterleiten.

Soll jedoch eine Delegation innerhalb der firewallgeschützten Umgebung an einen anderen Nameserver erfolgen, so kann dies hiermit geschehen.

Beispiele:

Master-Eintrag
++++++++++++++

  zone "lug-erding.de" in 
    {
        type master;
	file "db.lug-erding.de";
    };
      
Slave-Eintrag
+++++++++++++

   zone "mglug.de" in 
     {
        type slave;
	file "SEC.mglug.de";
	masters { ns1.croup.de; ns2.croup.de; };
     };

Forward-Eintrag
+++++++++++++++

    zone "mglug.de" in
      {
         type forward;
         forward only;
	 forwarders { ns1.croup.de; ns2.croup.de; };
      }; 

view

Dies ist ein neues sehr schönes Feature. Hiermit können effektiv zwei unterschiedliche Nameserver über einen realisiert werden. Dabei sind im wesentlichen die gleiche Vielzahl an Optionen möglich wie sie global oder innerhalb einer Zone definiert werden können.

Am einfachsten lässt sich der Vorteil an einem Beispiel erkennen:

acl "interneSysteme" { 10.0.0.0/8; };

view "internal" 
  {
     match-clients { "interneSysteme"; };
     recursion yes; // interne Systeme dürfen rekursiv Anfragen

     zone "lug-erding.de" in 
       {
          type master;
	  file "db.intern.lug-erding.de";
       };

   };

view "external"
  {
     match-clients { any; }; // alle anderen
     recursion no;           // rekursive Anfragen verboten 

     zone "lug-erding.de" 
       {
          type master;
	  file "db.extern.lug-erding.de";
       };
   };

Hier offenbart sich der elegante Vorteil durch Verwendung von views, es können nicht nur unterschiedliches Verhalten des Nameservers für interne wie externe Clients definiert werden (das geht auch über ein globales options-Statement). Es ist auch möglich verschiedene Zoneneinträge zu präsentieren, so kann db.intern.lug-erding.de auch interne Server beinhalten mit RFC 1918 Adressen die im Internet nicht verbreitet werden sollten.

Interessante Optionen von named

Hier werde ich einige der interessanteren Optionen von named vorstellen. Die meisten Optionen können sowohl global, in Zonen oder in Views angegeben werden. Dadurch ist BIND 9 sehr flexibel konfigurierbar geworden.

directory "Verzeichnis";
spezifiziert das Arbeitsverzeichnis von named. Alle weiteren nicht-absoluten Pfade sind relativ zu diesem Verzeichnis
dump-file "Dateiname";
hier schreibt ein rndc dumpdb die aktuelle Datenbank hinein

auth-nxdomain ( yes | no ) ;
wenn auf yes gesetzt, dann wird das AA bit immer gesetzt wenn eine Domain (also DNS-Name) nicht existiert. Dies verhindert z.B. das interne Nameserver auf die Idee kommen selber iterative Namensauflösungen versuchen
multiple-cnames ( yes | no );
erlaubt CNAMEs auf CNAMEs zu zeigen.
notify ( yes | explicit | no );
sende Benachrichtigungen an alle Nameserver einer Zone wenn diese sich ändert, explizit sendet notify nur an "also-notify" Adressen
also-notify [ port integer ] { IP-Adresse [ port integer ]; ... };
sende zusätzlich notifys an diese Adressen
allow-notify { Adressbereich; ... };
von wem werden notifys akzeptiert?
recursion ( yes | no );
erlaube rekursive Anfragen
allow-recursion { Adressbereich; ... };
wer darf rekursive Anfragen stellen?
recursive-clients #clients
spezifiziert wieviele Clients gleichzeitig rekursive Anfragen stellen dürfen, der default ist 1000
allow-query { Adressbereich; ... };
wer darf überhaupt Anfragen?
blackhole { Adressbereich; ... };
Anfragen von und an diese Adressen werden ignoriert, default ist none
allow-transfer { Adressbereich; ... };
wer darf Zonen beziehen?
provide-ixfr ( yes | no );
antworte mit inkrementellem Zonetransfer wenn dies angefordert wird, anderenfalls wird die gesamte Zone übertragen
request-ixfr ( yes | no );
sollen Zonentransfers für die man selber slave ist inkrementell angefordert werden?
multi-master ( yes | no );
eigentlich darf es nur einen master geben, gelegentlich gibt es aber mehrere, z.B. bei mehreren ADS-Nameservern die sich anders als über Zonentransfers ihre Daten replizieren. Hier kann es vorkommen, dass sich die serial-Nummer verkleinert. Mit dieser Option kann der named auch damit umgehen.
dnssec-enable ( yes | no );
soll DNSSec aktiviert sein? benötigt extra configure-Optionen beim compilieren
querylog ( yes | no);
sollen die DNS-Anfragen geloggt werden?
check-names ( master | slave | response ) ( fail | warn | ignore );
welches Verhalten soll verwendet werden wenn ein DNS-Name nicht dem Standard entspricht? In RFC 952, RFC 821 und RFC 1123 sind Hostnamen spezifiziert, danach sind z.B. Underscores "_" verboten.
forwarders [ port integer ] { IP-Adresse [ port integer ]; ... };
sollen forwarder benutzt werden, d.h. die Anfragen rekursiv weitergeleitet werden?
forward ( first | only );
wenn ein forwarder benutzt wird, dann werden bei forward only Anfragen grundsätzlich weitergeleitet wenn der Server die Antwort nicht weiß, bei first, wird erst der forwarder befragt und wenn der die Antwort nicht weiß eine iterative Anfrage gestartet
listen-on [ port integer ] { IP-Adresse [ port integer ]; ... };
spezifiert auf welchem Interface named seinen socket(s) öffnet
query-source { address ( IP-Adresse * ) port ( port * ); };
notify-source { address ( IP-Adresse * ) port ( port * ); };
transfer-source { address ( IP-Adresse * ) port ( port * ); };
von welcher Adresse und Port sollen Anfragen, Notifys oder Zonentransfers an andere Nameserver erfolgen? Hilfreich bei Paketfilter Firewalls.
max-journal-size Größe;
gibt an wie groß ein Journal bei inkrementellen Updates werden darf, der default ist unendlich!
max-cache-size Größe
hiermit kann die Cache-Größe des named eingeschränkt werden
max-ncache-ttl Zeit;
hiermit kann die maximale Dauer für das negative Caching eingestellt werden
edns ( yes | no );
ist ENDS erlaubt?
edns-udp-size Bytes
setzt die ankündbare Größe des EDNS UDP-Puffers, die Werte müssen im Bereich von 512 bis 4096 liegen, default ist 4096
version ( quoted_string | none );
hiermit kann der Versionsname geändert oder weggelassen werden

Resolver-Optionen

Das Verhalten des Resolvers (zumindest für DNS) wird über die Datei /etc/resolv.conf bestimmt. Hier gibt es ein paar Optionen die neben den Nameservern gesetzt werden können.

Die Optionen sind:

nameserver name
Hierdurch wird der Nameserver festgelegt der befragt werden soll. Bis zu 3 nameserver-Einträge, einer pro Zeile, sind möglich, sie haben auch Einfluss auf die mögliche Dauer für eine Auflösung.
search Liste
Eine Liste von möglichen Domainendungen die zwecks der Namensauflösung angehängt werden sollen. Normalerweise wird dies durch den lokalen Hostnamen mit Domainteil bestimmt. Aktuell können bis zu 6 Domainendungen hier angegeben werden.
domain domainname
Ähnlich wie search kann hier ein Domainname angegeben werden der bei der Namensauflösung angehängt werden kann. Dieser Eintrag ist veraltet und sollte nicht mehr verwendet werden.
sortlist IP-Netz
Mittels dieser Option kann eine Präferenz für bestimmte Adressen/Netze eingestellt werden. Existieren zu einem Namen mehrere Einträge so kann hier eine Reihenfolge der Antwort vorbestimmt werden. Bis zu 10 Netze können hier angegeben werden.
options Option ...
Hier können spezielle Optionen für den Resolver gesetzt werden.
Optionen für den Resolver
Name Funktion
debug    aktiviert das Debugging im Resolver
ndots:n spezifiziert wieviele Punkte in einem Namen vorhanden sein müssen damit er an den Resolver weitergereicht wird. Sind weniger Punkte vorhanden, so wird die Suchliste der Reihe nach angehängt, Voreinstellung ist n=1
timeout:n setzt den Timeout, also die Zeit in Sekunden die der Resolver auf eine Antwort warten soll bis der nächste Nameserver befragt oder eine erneute Anfrage gestellt wird, default sind 5 Sekunden, siehe unten
attempts:n Anzahl der Versuche bis der Resolver aufgeben soll sofern er keine Antwort erhält.
rotate bewirkt, dass die Nameserver in round-robin Verfahren verwendet werden sollen, also immer rotierend, nur sinnvoll bei mehr als einem nameserver-Eintrag, default ist immer der angegebenen Reihe nach
no-check-names moderne Resolver überprüfen den Namen vor der eigentlichen Anfrage an den Nameserver, dieses Verhalten kann hiermit abgestellt werden.
inet6 aktiviert zuerst die Anfrage nach einer IPv6 (AAAA) Adresse bevor ein A-Record gesucht wird, existiert nur ein A-Record, so wird dieser in eine IPv6 Adresse umgesetzt (tunnelled form)

Wie angedeutet: domain und search schließen sich gegenseitig aus.

Timeouts ab BIND 8.2.1

Der Timeout wird mit jedem Versuch verdoppelt und durch die Zahl der Nameserver dividiert:

Timeout vs. Zahl der Nameserver
retry 1 2 3
0 5s (2x) 5s (3x) 5s
1 10s (2x) 5s (3x) 3s
total 15s 20s 24s

Ältere Resolver verwendeten bis zu 4 Versuche bis sie aufgeben, so konnte es zwischen 75s und 81s (je nach Zahl der Nameserver) dauern bis der Resolver aufgibt. Da ist das neue Verhalten deutlich freundlicher.

Konfiguration von rndc

Mit dem Programm rndc kann das Verhalten des named beeinflusst werden. Auch dieses Programm hat ein paar Kommandozeilen- optionen:

-c config-file
rndc's Konfigurationsdatei, default ist /etc/rndc.conf
-k key-file
diese Datei ist per default /etc/rndc.key und enthält einen Key mit dem sich rndc beim named-Prozess authentisieren kann. Der key kann aber auch in der Konfigurationsdatei angegeben werden.
-s server
server ist die Adresse des Nameservers aus dem config-file mit dem rndc sich verbinden soll
-p port
der Port der verwendet werden soll um mit dem named zu kommunizieren, der default ist 953
-V
sei geschwätzig
-y keyid
verwende key keyid falls mehrere existieren, der default ist der erste in der Konfigurationsdatei

rndc versteht einige Kommandos:

reload
lade die Konfigurationsdatei neu
refresh zone
kontrolliere die Aktualität der Zone (checken des SOA-Records vom master)
retransfer zone
sofortiges holen der Zone ohne die Seriennummer zu prüfen
freeze zone
verbieten von dynamischen Update in dieser Zone, zu dynamischen Updates kommt später noch mehr
thaw zone
erlaube wieder dynamische Updates
reconfig [-noexpired]
prüfe ob sich Zonen geändert haben oder hinzugekommen sind -noexpired gibt an, dass; ausgelaufene TTLs ignoriert werden sollen
stats
hängt die aktuelle Statistik des Nameservers an named.stats an
querylog
aktiviert bzw. deaktiviert das Loggen aller Fragen an syslog
dumpdb
schreibt die interne aktuelle Datenbank des nameservers in die Datei nameddump.db_, mit -cache wird nur der cache geschrieben, mit -zones schreibt nur die authorativen Zonen und -all beides
stop
stoppt den Nameserver, dynamische Updates werden in die zonendatei geschrieben
halt
wie stop, schreibt aber keine ausstehenden Updates
trace [level]
schaltet das Debugging ein, je höher der level, desto mehr Informationen werden geloggt.
notrace
schaltet das Debugging wieder ab
flush
löscht den Cache des Nameservers
flushname name
löscht alle Domaineinträge zu name aus dem Cache
status
gibt einige nützliche Informationen über den aktuellen Status des Nameservers aus
recursing
schreibe informationen über rekursive Fragen die gerade bearbeitet werden in die Datei named.recursion im aktuellen Verzeichnis

Das sind wirklich sehr viele nützliche Optionen die wohl nur schwerlich über Signale abbildbar wären.

Sicherheitsüberlegungen

Um named sicher zu betreiben ist es zuerst einmal ratsam den Prozess; in einer chroot-Umgebung ohne Root-Rechte laufen zu lassen. BIND Version 9 unterstützt beides auf elegante Weise, es müssen weder Bibliotheken noch Devices oder Passwörter in die chroot-Umgebung kopiert werden, es ist nur notwendig die Optionen anzugeben, z.B.:

   named -u bind -t /var/named

Der named-Prozess linked alle Bibliotheken beim starten, wertet die Kommandozeile aus und initialisiert den Speicher. Erst danach wird ein chroot nach /var/named durchgeführt. Dann werden die notwendigen Sockets geöffnet und anschließend verwirft named die Root-Rechte und wechselt seine UID zu "bind".

Es gibt aber noch mehr zu bedenken damit die Integrität der Daten gewährleistet ist. Das hängt aber von der Komplexität der Einsatzumgebung ab.

Bei der Verwendung hinter einer Paketfilter-Firewall bieten sich die Optionen

query-source { address ( IP-Adresse | * ) port ( port | * ); };
notify-source { address ( IP-Adresse | * ) port ( port | * ); };
transfer-source { address ( IP-Adresse | * ) port ( port | * ); };

an um die Adressen und Ports für ausgehende Anfragen festzulegen. Bei stateful-Paketfiltern ist dies nicht notwendigerweise notwendig.

Für einen einfachen PC der gelegentlich mit dem Internet verbunden ist lohnt es sich in der Regel nicht einen eigenen Nameserver zu betreiben. Allerdings wird ein Nameserver benötigt der rekursiv befragt werden kann.

Da Cache-Poisoning ein ernstzunehmendes Problem ist sollte eingeschränkt werden wer derartige Anfragen stellen darf. Bei Nameservern von Providern ist dies in der Regel nicht machbar.

Von daher kann der Einsatz eines caching-only Nameservers, das ist ein Nameserver ohne eigene Zonen, durchaus einen Sinn ergeben.

Aber betrachten wir diverse Szenarios mit mehreren Systemen:

1. Eine Firewall schirmt ein kleines Netz ab

Hier ist es ratsam auf der Firewall einen Nameserver laufen zu 
lassen. Dieser kann mittels Views in einen öffentlichen und nicht 
öffentlichen Teil gesplittet werden. Rekursive Anfragen sollten 
nur von intern möglich sein, von außen sollten diese verboten sein.

Wird kein eigener Nameserver für das Internet benötigt sondern nur 
für das LAN, so kann man via ''listen on'' nur die interne Seite 
der Firewall für Anfragen öffnen.

2. Firewall und größeres LAN

Hier kann es sinnvoll sein einen internen Nameserver zu verwenden 
der hinter der Firewall, d.h. im LAN, steht um die internen Zonen 
verwalten zu können. Auf der Firewall selber kann dann dann ein 
offizieller Nameserver laufen der rekursive Anfragen nur vom
internen Nameserver annimmt

Der interne Nameserver sollte für seine Zonen antworten und für 
alle Anfragen diese an die Firewall weiterleiten. Durch festlegen 
der Source-Ports können die Firewallregeln gut festgelegt werden. 

Der interne Nameserver sollte die Firewall als ''forwarder''
eingetragen haben und ''forward only'' sein.

3. Firewall und sehr großes LAN

Hier gilt das Gleiche wie oben, jedoch kann es sein, dass das interne 
Netz mehrere Subdomains (z.B. verschiedene Abteilungen in einer Firma)
beherbergen. 

Da die Clients nur einen Nameserver befragen können  muss dieser 
die Anfrage auflösen können.  D.h. entweder der Nameserver sollte 
authoritive für die Zone sein oder die Anfrage an den Nameserver 
der Firewall weiterleiten.

Sollen nun die internen Domains delegiert werden damit z.B. die 
einzelnen Abteilungen diesen selber betreiben können, so müsste 
der zentrale interne Nameserver ein slave für alle Zonen sein. 
Sind die anderen Nameserver mit DHCP und dyn-DNS versehen, so 
können sich die Zonen schnell ändern und viele Zonentransfers 
zur  Folge haben.

Mit BIND Version 9 gibt es noch eine elegantere Lösung, hier kann 
anstelle eines slave einfach die delegierte Zone als Typ forward 
eingerichtet werden, z.B.:
     zone debian.lug-erding.de in 
       {
          type forward;
	  forwarders { 192.168.1.1; 192.168.1.5; };
       }
Auf diese Weise braucht man sich um die Pflege der Zone oder 
Zonentransfers keine Gedanken machen und kann dennoch das Prinzip 
von nur einem zentralen  Nameserver beibehalten.

Das waren jetzt nur ein paar Szenarien, im Einzelfall sollte vielleicht noch einmal etwas konkreter über die Umsetzung nachgedacht werden. Schließlich spielt die Art der Firewall durchaus auch eine Rolle.

Bei GeNUGates läuft z.B. pro Interface ein eigener Nameserver in einer echten chroot-Umgebung und verwendet den Nameserver vom externen Interface als forwarder.

whois

Dieses Programm ist sehr hilfreich um Informationen über eine Domain zu erhalten. Leider muss dazu der richtige whois-Server gefunden werden und fast jeder Toplevel-Domainverwalter betreibt seinen eigenen. Es ist wohl unnötig zu erwähnen, dass diese sich nicht abgleichen.

Glücklicherweise sind aktuelle whois-Implementationen meistens clever genug den richtigen Server zu finden. Der Dienst wird über TCP Port 43 realisiert.

Informationen die man dort findet sind:

Holder
Eigentümer einer Domain, kann auch eine Firma sein
Admin-C
vom Inhaber Bevollmächtigter Verwalter der Domain, bei Privatpersonen gewöhnlich gleich dem Owner. Er darf die Domain umziehen, schließen, verkaufen oder auch nur den Inhaber (Owner) ändern lassen. Bei .de-Domains muss der Admin-C eine natürliche Person mit gültiger Adresse in Deutschland sein.
Tech-C
technischer Ansprechpartner, hat keinerlei Rechte auf die Domain ist aber für die Server verantwortlich
Zone-C
Zonenverwalter, betreut die Nameserver der Domain. Wenn die Domain nicht delegiert ist, kann der Eintrag entfallen

Für die lug-erding.de ergibt sich:

Domain:      lug-erding.de
Domain-Ace:  lug-erding.de
Nserver:     ns1.partnerpanel.de
Nserver:     sns1.partnerpanel.de
Status:      connect
Changed:     2006-07-01T17:51:12+02:00

[Holder]
Type:         PERSON
Name:         Geschke Dirk
Address:      Plankensteinweg 61
Pcode:        85435
City:         Erding
Country:      DE
Changed:      2006-07-01T12:06:27+02:00

[Admin-C]
Type:         PERSON
Name:         Geschke Dirk
Address:      Plankensteinweg 61
Pcode:        85435
City:         Erding
Country:      DE
Changed:      2006-07-01T12:06:27+02:00

[Tech-C]
Type:         ROLE
Name:         of the day Hostmaster
Organisation: netclusive internet broadcasting GmbH
Address:      Robert-Bosch-Str. 10 - Haus I
Pcode:        56410
City:         Montabaur
Country:      DE
Phone:        +49 2602 947080
Fax:          +49 2602 94708299
Email:        hostmaster@netclusive.de
Changed:      2006-06-16T17:49:15+02:00

[Zone-C]
Type:         ROLE
Name:         of the day Hostmaster
Organisation: netclusive internet broadcasting GmbH
Address:      Robert-Bosch-Str. 10 - Haus I
Pcode:        56410
City:         Montabaur
Country:      DE
Phone:        +49 2602 947080
Fax:          +49 2602 94708299
Email:        hostmaster@netclusive.de
Changed:      2006-06-16T17:49:15+02:00

Wie leicht zu erkennen ist steht hier alles relevante über eine Domain, deren Besitzer und Verwalter.

Wichtig
Der Admin-C ist Herr über die Domain und nicht wie oft irrtümlich angenommen wird der Provider über den die Domain eingetragen wurde, dieser ist in der Regel nur der Tech-C. C steht übrigens für Contact, bezeichnet also einen Ansprechpartner.

nslookup

Dies ist das ältere Programm zur Befragung von Nameservern. Eine Besonderheit ist, dass nslookup eine eigene Resolver-Bibliothek verwendet und nicht die des Systems. Das kann manchmal einige Probleme verbergen.

Ferner kann nur ein Nameserver befragt werden. Dieser kann auf der Kommandozeile angegeben werden. Leider weigert sich nslookup diesen zu verwenden wenn dieser sich nicht reverse auflösen lässt.

Ein Vorteil ist, dass hiermit auch Zonentransfers durchgeführt werden können und fast alle Record-Typen abgefragt werden können.

Es gibt einen interaktiven Modus bei dem mit dem Programm kommuniziert wird und einen nicht-interaktiven Modus bei dem alle Optionen auf der Kommandozeile angegeben werden müssen.

Dies Optionen werden auf der Kommandozeile durch ein Minus-Zeichen angegeben oder im interaktiven Modus mit set gesetzt. Optionen können durch vorgestelltes no auch deaktiviert werden.

Optionen

all
zeigt alle Einstellungen an, sehr hilfreich bei der Fehlersuche
class=(IN | CH | HS | ANY)
setzt die Klasse
[no]debug
aktiviert das debugging
[no]d2
aktiviert erweitertes debugging
domain=name
setzt die Suchliste auf name
[no]search
wenn die Anfrage nicht auf einen Punkt endet, so hänge solange die Suchliste an bis eine Antwort erhalten wird
port=Zielport
ändert den Nameserverport
querytype=Record-Typ
type=Record-Typ
setzt den Frage-Record-Typ
[no]recurse
aktiviert rekursive Anfragen
retry=Zahl
setzt sie Zahl der Wiederholungsversuche
timeout=Sekunden
setzt das Timeout-Intervall
[no]vc
verwendet virtual circuit (TCP) für Anfragen

Beendet wird der interaktive Modus mit exit.

Mit all diesen Optionen können Nameserver sehr gut getestet werden. Es gibt aber auch ein paar Nachteile, insbesondere wird die Antwort des Servers nicht vollständig angezeigt.

nslookup ist auch in der Lage reverse Fragen automatisch korrekt zu erkennen, z.B.:

geschke@www:~$ nslookup 89.110.147.240   
Server:         89.110.128.128
Address:        89.110.128.128#53

Non-authoritative answer:
240.147.110.89.in-addr.arpa     name = mail.lug-erding.de.

Authoritative answers can be found from:
147.110.89.in-addr.arpa nameserver = ns5.netclusive.de.
147.110.89.in-addr.arpa nameserver = ns10.netclusive.de.
147.110.89.in-addr.arpa nameserver = sns5.netclusive.de.
ns5.netclusive.de       internet address = 89.110.128.10

Hier können gleich mehrere Aspekte beobachtet werden:

  1. Der Nameserver der befragt wird ist 89.110.128.128
  2. Die Antwort ist non-authoritive, d.h. eine rekursive Anfrage wurde von einem Server beantwortet, der nicht für die Domain zuständing ist
  3. Zuständige Nameserver sind ns5, ns10 und sns5.netclusive.de

Beispiel für einen interaktiven Modus:

geschke@www:~$ nslookup
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> set domain=lug-erding.de
> set search
> www
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   www.lug-erding.de
Address: 89.110.147.240
> set querytype=mx
> lug-erding.de
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
lug-erding.de   mail exchanger = 10 mail.lug-erding.de.

Authoritative answers can be found from:
lug-erding.de   nameserver = ns1.partnerpanel.de.
lug-erding.de   nameserver = sns1.partnerpanel.de.
mail.lug-erding.de      internet address = 89.110.147.240
> exit

Beide Varianten haben ihre Vor- und Nachteile.

dig

Dig ist relativ neu und ist eine Verbesserung von nslookup. Und wie es sich gehört ist es dann auch deutlich mächtiger. Der Name ist ein reverse-engineered Akronym:

Domain Information Groper

Das Programm soll nslookup ablösen und ist eigentlich einfacher zu bedienen. So erkennt dig den Record-Typ auf der Kommandozeile automatisch und kann ihn vom Domainnamen unterscheiden.

Die Reihenfolge von Optionen ist ebenfalls beliebig, dig besitzt keine automatische searchlist und zeigt per default alle Sektionen: Fage, Antwort, Authority, Additional

Soll z.B. der Nameserver auf localhost den zuständigen Nameserver für lug-erding.de finden, so geht dies mit:

geschke@www:~$ dig @localhost ns lug-erding.de

; <<>> DiG 9.3.2-P1 <<>> @localhost ns lug-erding.de
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64493
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;lug-erding.de.                 IN      NS

;; ANSWER SECTION:
lug-erding.de.          85858   IN      NS      sns1.partnerpanel.de.
lug-erding.de.          85858   IN      NS      ns1.partnerpanel.de.

;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Dec  5 23:24:57 2006
;; MSG SIZE  rcvd: 81

Die Antwort ist hier leider nicht so leicht zu erkennen wie bei nslookup. Dafür sind aber alle Sektionen aufgelistet, z.B. wird die TTL auch ausgegeben.

Die Flags des DNS-Headers werden ebenso aufgelistet wie eine Statistik am Ende

Die Optionen sind

@server
gibt den Nameserver an der befragt werden soll
-b Adresse
setzt die Absendeadresse (bind address) von dig
-c Klasse
gibt die Klasse an, default ist IN
-f Dateiname
batch-Modus, dig liest die Kommandos aus der angegebenen Datei
-k Dateiname
TSIG-Dateiname
-p port
frage den Server auf diesen port
-t type
setzt den Fragetyp, der default ist A, diese Option wird aber meist ohne -t erkannt
-x Adresse
wird für reverse DNS Anfragen benötigt!
-y Name:Key
verwende diesen TSIG-Key
-4
-6
aktiviert Frage nach IPv4 bzw. IPv6 Adresse
[name]
[type]
[class]
Diese 3 Werte erkennt dig automatisch

Es können noch mehrere Frageoptionen angegeben werden:

+[no]tcp
+[no]vc
verwende TCP für Anfragen, vc existier nur noch aus historischen Gründen
+[no]ignore
ignoriere ein gesetztes Truncation-Bit
+domain=Name
setze searchlist und aktiviere diese
+[no]search
benutze eine searchlist, per default deaktiviert
+[no]defname] veraltet, wird als Synonym von ''+[no
search'' verwendet
+[no]aaonly
setze das AA-Flag in der Frage
+[no]aaflag] Synonym für ''+[no
aaonly''.
+[no]adflag
setze das AD-Bit (authentic data) in der Frage. Das AD-Bit hat zur Zeit nur eine Bedeutung in Antworten, nicht in Fragen, die Fähigkeit das Bit in der Frage zu setzen dient nur der Vollständigkeit
+[no]cdflag
setze das CD-Bit (checking disabled) in der Frage, das verlangt vom Server keine DNSSec-Validierungen in Antworten vorzunehmen
+[no]cl
zeige die Klasse in der Ausgabe des Records

+[no]ttlid
zeige die TTL in der Ausgabe des Records
+[no]recurse
aktiviere rekursive Fragen, dies ist der default
+[no]nssearch
suche den authorativen Nameserver für die Zone die den Domainnamen enthält und zeige den SOA-Record
+[no]trace
verfolge die Delegationen vom Root Nameserver bis der Domainname aufgelöst wird, ist diese Option aktiviert werden iterative Fagen verwendet und es werden alle Antworten bis zum Ziel gezeigt
+[no]cmd
aktiviert die Ausgabe der dig-Version im Kommentarfeld am Anfang der Ausgabe
+[no]short
kurze Ausgabe, default ist die lange Form
+[no]identify
zeige die IP-Adresse und den Port der Antwort
+[no]comments
aktiviert die Ausgabe von Kommentaren am Anfang der Ausgabe
+[no]stats
Ausgabe von Statistik
+[no]qr
gib die Frage mit aus die gesendet wird, per default deaktiviert
+[no]question
gib die Frage als Kommentar aus wenn eine Antwort erhalten wird
+[no]answer
zeige die Answer-Sektion
+[no]authority
zeige die Authority-Sektion
+[no]additional
zeige die Additional-Sektion
+[no]all
setze alle Flags
+time=T
setze den timeout, default sind 5 Sekunden
+tries=T
setze Zahl der UDP-Versuche, default sind 3
+retry=T
setze Zahl der erneuten UDP-Versuche, default ist 2
+ndots=D
setzt die Zahl der Punkte die im Namen vorkommen müssen damit dieser als absoluter Name angesehen wird
+bufsize=B
setze UDP-Puffergröße die via EDNS0 angekündigt wird
+[no]multiline
gib längere Records über mehrere Zeilen aus
+[no]fail
befrage nicht den nächsten Server wenn ein SERVFAIL erhalten wird
+[no]besteffort
versuche den Inhalt von fehlerhaften Antworten
+[no]dnssec
fordere DNSSec Antworten an
+[no]sigchase
verfolge die DNSSec Signaturkette
+trusted-key=####
gibt die Datei mit trusted keys an
+[no]topdown
wenn die DNSSec Signaturkette verfolgt wird, so fange oben mit der Validierung an

Es können auch mehrere Fragen auf der Kommandozeile angegeben werden.

Wie leicht erkannt werden kann ist dig deutlich mächtiger als nslookup. Durch die Optionen kann auch ein ähnliches Verhalten erreicht werden. Das was ungewohnt ist sind die Voreinstellungen.

Fehlersuche

Das größte Problem bei der Fehlersuche ist, dass man erst einmal feststellen muss, dass es sich um ein DNS-Problem handelt. Das ist mitunter nicht trivial herauszufinden.

Wenn bei dem eigenen Nameserver ein Fehler vermutet wird, so sind folgende Optionen mitunter recht hilfreich:

-d <DebugLevel>
-g 

Diese schalten das Debugging ein und -g bewirkt, dass der named-Prozess; im Vordergrund bleibt und alle Fehler nach stderr ausgibt.

Fehler in der Syntax der Konfigurationsdatei oder auch innerhalb von Zonen werden hier schnell gefunden und meist wird die Datei nebst Zeilennummer ausgegeben in der ein Problem besteht.

Das ist aber nur zu empfehlen wenn sich ein Fehler beim Starten von named offenbart. Im laufenden Betrieb ist das nicht gerade zu gebrauchen, da ist oft zuviel Rauschen dabei und die Ausgabe auf dem Bildschirm bremst den named deutlich aus.

Ohne -g wechselt der named nach dem Starten in den Hintergrund und schreibt seine Meldungen mit der Facility daemon an den syslogd. Wo die Logeinträge dann auf dem System zu finden sind steht in der Dagtei /etc/syslog.conf.

Nun kann es aber passieren, dass der named beim Starten keine Probleme hat, diese erst nach längerer Laufzeit auftreten. Da ist es eher hinderlich derartig viel Debug-Ausgaben zu generieren. Zudem ist oft nicht klar, wie hoch der Debuglevel sein sollte.

Hier kommt dann rndc ins Spiel: Mit diesem Programm kann der Debuglevel (und damit das Debugging überhaupt) hochgedreht werden:

rndc trace <DebugLevel>

Ein Debuglevel von Null deaktiviert das Debugging wieder.

Gelegentlich wird der Inhalt der aktuellen Datenbank von named benötigt, dieser ist normalerweise in keiner Datei zu finden. Hier sind aber auch die gecacheten Werte enthalten und alles was der named ansonsten ausliefert bzw. ausliefern kann.

Diese Datenbank kann in eine Datei geschrieben werden:

rndc dumpdb -all

Dies gibt die komplette Datenbank aus, mit -cache kann nur der gecachete Anteil ausgegeben werden und mit -zone die Zonendaten für die der named zuständig ist.

Hier ist nun eine Liste der häufigeren Fehler:

Seriennummer

Manchmal werden Änderungen direkt in der Zonendatei vorgenommen, oft weil etwas entweder schnell geschehen soll, temporär ist oder einfach etwas getestet werden soll. Wird dann versucht die geänderte Zone zu laden und es wurde vergessen die Seriennummer zu erhöhen, so wird ein "reload" nichts bewirken.

Ein Neustart des named erzwingt natürlich ein Laden der Zone, allerdings leben dann die slave Nameserver noch immer mit den alten Daten und werden dieses Aufgrund der unveränderten Seriennummer nicht aktualisieren.

Ein Durchstarten des Nameservers verbietet sich aber auch bei einigen Systemen, insbesondere auf produktiven Systemen. Wenn zudem mehrere Domains verwaltet werden, so sollte dabei doppelte Vorsicht verwendet werden bevor der Nameserver durchgestartet wird.

reload vergessen

So trivial wie es klingt, es ist nicht ungewöhnlich, dass eine Zone abgeändert, die Seriennummer hochgezählt und schlichtweg vergessen wird dem Nameserver mitzuteilen, dass er die Zone neu laden soll.

fehlende hints-Datei

Dieses Problem existiert zum Glück mit BIND Version 9 nicht mehr, hier ist die hints-Datei eincompiliert.

Bei älteren Versionen kann es durchaus vorkommen, dass entweder die hints-Datei fehlt oder der Verweis darauf in der named.conf

Die Symptome sind dann

Im syslog findet sich dann auch der Eintrag:

       No root servers for class IN

Netzwerk unterbrochen

Das ist leicht zu entdecken:

request ... timed out

Dies kann leicht mit einem ping oder traceroute überprüft werden.

Wenn der Nameserver einen recht großen Cache hat, so kann dies auch schwer zu finden sein. Dann werden Adressanfragen mitunter aus dem Cache beantwortet.

Es kann auch sein, dass das Netzwerk nur zu bestimmten Adressen unterbrochen ist, in diesem Fall sollte ein traceroute einem helfen die Stelle zu finden wo es klemmt.

Bei einem Debuglevel von eins kann dies auch indirekt in den syslog-Meldungen gesehen werden: Es werden Anfragen generiert und versendet, es kommt aber keine Antwort zurück

fehlende Delegation

Der eigene Nameserver liefert die richtigen Antworten aus aber Systeme im Internet sind nicht in der Lage die Adressen zu bekommen, stattdessen gibt es den Fehler NXDOMAIN, also die Domain existiert nicht.

Hier fehlt dann vermutlich die Delegation in der übergeordneten Zone. Häufig werden erst die Nameserver aufgesetzt und getestet bevor die Delegation beauftragt wird. Da kann es manchmal etwas länger dauern bis das realisiert und verbreitet ist.

Bei manchem ISP muss auch häufiger der Auftrag für eine Delegation erteilt werden...

fehlerhafte Delegation

Was passiert, wenn eine Delegation stattfindet, der angegebene Nameserver sich aber nicht zuständig fühlt? Eventuell ist die Zone noch nicht eingerichtet, sie hat einen Fehler oder aber der Provider war zuständig hat aber die Domainverwaltung abgegeben: Es fand ein Domainumzug statt und die Änderung der Delegation wurde vergessen.

Derartige Server werden lame server genannt, d.h. der scheinbar zuständige (delegierte) Nameserver ist nicht zuständig. Von Zeit zu Zeit stehen solche Einträge in den Syslogmeldungen. Besonders häufig sind sie bei Delegationen von reverse-Zonen zu finden.

Vermutlich fand mit dem Umzug der Domain auch ein Providerwechsel statt und das Letzte woran man gedacht hatte war der PTR-Eintrag?

Fehler in resolv.conf

Bei Fehlern kann es sich um Syntax-Fehler handeln oder auch logische Fehler bzw. Tippfehler. Hier ist nslookup die erste Wahl, die Option set all sollte alle Einstellungen liefern und die können gut mit dem verglichen werden was da stehen sollte.

Z.B.:

majestix:~$ nslookup 
> set all
Default server: 127.0.0.1
Address: 127.0.0.1#53
Default server: 212.82.226.212
Address: 212.82.226.212#53

Set options:
  novc                  nodebug         nod2
  search                recurse
  timeout = 0           retry = 2       port = 53
  querytype = A         class = IN
  srchlist = 

Hier kann leicht erkannt werden, dass überhaupt keine Suchliste mit Domainnamen angegeben ist, d.h. es muss immer der vollständige Domainnamen angegeben werden.

Lokaler Domainname nicht gesetzt

Dieses Problem kann unter Linux nicht auftreten, der Resolver in der glibc ignoriert den Domainnamen grundsätzlich. Aber auf anderen Systemen wird, sofern kein search-Statement in /etc/resolv.conf steht der lokale Domainname angehängt.

Hier z.B. bei einem HP-UX System, das System gibt sogar eine Warnung aus:

dg6:/# hostname
dg6
dg6:/# nslookup   
*** Warning - the local domain is not set.
*** Either hostname should be a domain name,
*** the domain should be specified in /etc/resolv.conf,
*** or the shell variable LOCALDOMAIN should be set.

Default Name Server:  dns.home.de
Address:  10.0.1.4

> set all
Default Name Server:  dns.home.de
Address:  10.0.1.4

Set options:
  nod2            nodebug         defname         noignoretc      recurse
  search          noswtrace       novc            port=53
  querytype=A     class=IN        timeout=5       retry=4
  root=ns.nic.ddn.mil.
  domain=
  srchlist=

> dg7
Name Server:  dns.home.de
Address:  10.0.1.4

Trying DNS
*** dns.home.de can't find dg7: Non-existent domain

> exit
dg6:/# hostname dg6.home.de
dg6:/# nslookup dg7
Name Server:  dns.home.de
Address:  10.0.1.4

Trying DNS
Name:    dg7-tst.home.de
Address:  10.1.22.7
Aliases:  dg7.home.de

(Hier sieht man auch, dass der dg7 ein CNAME von dg7-tst ist.)

unerwartete Antwort

Diese Fehlermeldung heißt

Response from unexpected source ...

Eventuell versucht jemand den Cache zu vergiften (poisoning). Es kann aber auch eine viel einfachere Ursache haben.

Aktuelle BIND-Versionen merken sich an wen sie eine Anfrage gestellt haben und erwarten die Antwort auch just von dieser Adresse. BIND macht dies auch, allerdings sind nicht alle Nameserverimplementationen so clever.

Die IP-Adresse der Antwort kann sich dann ändern, wenn der befragte Nameserver auf einem System mit mehreren IP-Adressen und/oder Interfaces läuft.

Da kann es sein, dass die Antwort über ein anderes Interface erfolgt oder über das gleiche wie die eingehende Antwort jedoch mit der ersten gebundenen Adresse des Interfaces als Absender.

Es muss also nicht unbedingt eine böse Absicht dahinter stecken. Nun ja, zum Glück macht BIND das korrekt.

Die Verbreitung von Nameservern ist:

Anteile der Nameserver
Nameserver   Anteil
BIND 9.3, 9.2, 9.1   57%
BIND 8.3, 8.2, 8.1   20%
Windows 2000     6.5%
Windows 2003     3.5%
Other       13%

Es könnte nun der Eindruck gewonnen werden, dass BIND doch irgendwie zum Standard geworden ist, der Marktanteil ist sogar höher als der von Apache bei Webservern. Unter Other dürften sogar noch einige BIND 4 Versionen vertreten sein...

out-of-zone data

Dieses Problem tritt immer dann auf, wenn named in einer Zone Daten findet die hier nicht hineingehören. Dies kann oft vorkommen, wenn eine Subdomain delegiert wird und noch alte Einträge verbleiben oder es wurde versehentlich ein Punkt am Ende eines Domainnamengesetzt wo keiner hingehört.

Es gibt aber eine Möglichkeit bei der dies explizit erlaubt und auch notwendig ist: Wenn eine Delegation in eine Subdomain erfolgt und der zuständige Nameserver in der delegierten Zone liegt. Das ist das berühmte Henne-Ei Problem:

Wie soll man den Nameserver für eine Zone befragen wenn
dessen Adresse in dieser Zone ist?

Daher sind hier explizit Einträge erlaubt die eigentlich in die delegierte Zone gehören. Diese Einträge werden auch glue records genannt.

Fehlen diese, so gibt der named eine Fehlermeldung aus, dass diese glue records fehlen.

Zonentransfers mit WINS-Einträgen funktionieren nicht

Das ist ein interessantes Problem. Wenn der master einer Zone ein Microsoft DNS-Server ist so kann es Einträge geben wie:

  @   IN   WINS ...

Wenn es derartige Einträge gibt, so schlägt ein Zonentransfer zu einem BIND Nameserver fehlt. Der Grund ist dabei recht einfach: WINS ist kein erlaubter Record-Typ!

Eine Lösung zu diesem Problem gibt es auch: Beim DNS-Manager unter Windows muss bei WINS-Lookup der Haken bei ''Settings only affect local server'' gesetzt sein, dann werden keine WINS-Records in den Zonendateien verteilt.

Allerdings sehen dann Microsoft DNS-Server die als slave eingerichtet sind auch keine WINS-Records, diese könnten aber damit umgehen.

Nameserver ignorieren negative gecachete Einträge

Das ist auch ein interessantes Problem. Manche Nameserver ignorieren diese Aussage eines forwarders und versuchen selber iterative Anfragen zu stellen. Dies ist bei internen Nameservern ein großes Problem, da sie in der Regel nur über den forwarder eine Antwort bekommen können, d.h. die Firewall wird alle iterativen Anfragen des internen Nameservers blocken.

Da das UDP-Anfragen sind, gibt es auch kein RST-Pakete von der Firewall, hier könnten nur ICMP-Pakete helfen. Diese werden von den meisten Paketfilterfirewalls aber nicht versendet, d.h. der interne Nameserver läuft in Timeouts.

BIND kann mit der Option

auth-nxdomain yes;

gegen den Standard verstoßen und das AA-Flag (authoritive answer) in der Antwort setzen. Damit glaubt der interne Nameserver, dass der für die Zone zuständige Nameserver geantwortet hat und folglich ist eine iterative Anfrage nicht mehr notwendig.

Internet hat Hänger

Das ist ein vergleichsweise häufig anzutreffendes Problem, das Surfen funktioniert, Downloads sind normal schnell, es besteht nur das Gefühl, dass zwischendurch ein paar Sekunden alles steht.

Hier ist das häufigste Problem, dass der erste Nameserver in der Datei /etc/resolv.conf nicht funktioniert. Der Resolver wartet auf seinen Timeout von typischen 5 Sekunden bevor er den zweiten Nameserver befragt. Der liefert die korrekte Antwort. Diese 5 Sekunden werden als Hänger empfunden.

Bei manchen Webseiten sind noch diverse Links von anderen Servern eingebettet, so dass es zu durchaus mehreren Timeouts kommen kann bevor alles geladen werden kann.

Diese Art der Fehler sind leicht zu finden wenn dies hier bekannt ist, anderenfalls sind sie nahezu unmöglich zu finden. Mit einem geübten Auge kann in einem tcpdump gesehen werden, dass einige Antworten auf Nameserveranfragen unbeantwortet bleiben. Da aber in der Regel sehr viele Pakete über ein Netzwerk laufen gehen diese Pakete gewöhnlich bei einer normalen Durchsicht unter.

Eine Verschlimmerung dieses Problems kann durch Programme wie dem name service cache daemon, nscd, erfolgen. Dieser cachet zusätzlich zum Nameserver noch einmal Antworten. Das kann einem schon schnell einmal auf die falsche Fährte führen.

Mitunter liefert ein Nameserver die richtige Antwort aber der nscd noch die falsche...

Ein lokaler Nameserver mit mehreren forwardern erkennt hingegen wenn einer nicht antwortet und stellt sich automatisch auf den nächsten ein. Der Resolver ist leider nicht so elegant.

Jetzt folgen noch zwei relativ aktuelle Beispiele.

PAC-Dateien

Das Problem ähnelt dem letzten, ist aber noch etwas diffiziler.

PAC heißt Proxy AutoConfiguration und ist eine Erfindung von Netscape. Damit kann einem Browser über ein JavaScript mitgeteilt werden wann er welchen Proxy verwenden soll oder gar direkt die Seiten holen soll. Näheres ist hier beschrieben:

http://wp.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html

In größeren Firmen wird dies gerne eingesetzt, da hier leicht gesagt werden kann welcher Proxy für welche Dienste verwendet werden soll, eventuell ist der Server über ein VPN-Netz zu erreichen, ob eine Seite direkt geholt werden kann und soll weil es z.B. ein interner Server ist.

Die Entscheidung wird dabei häufig über die IP-Adresse getroffen, d.h. Wenn der Server in diesem Netz ist mache jenes.

Hier deutet sich das mögliche DNS-Problem an: Um den Proxy auswählen zu können muss erst der DNS-Name, gewöhnlich werden Namen im Browser verwendet, zu einer IP-Adresse aufgelöst werden. Erst wenn dies fehlschlägt, wird der default-Proxy angesprochen.

Hier können mehrere Ursachen vorhanden sein die alle das gleiche bewirken:

In beiden Fällen muss erst der Timeout abgewartet werden bevor es zu einer Entscheidung kommt die Anfrage einfach an den Proxy weiterzuleiten. Spaßig ist dies, wenn nur auf der Firewall der Fehler gesucht werden kann, der Kunde sagt Das Internet hat Hänger und im tcpdump sind erst keine Pakete zu sehen und dann funktioniert alles normal schnell.

In diesem konkreten Fall war es ad.doubleclick.com bei dem der Nameserver nicht funktioniert hatte. Da diese Adresse in sehr vielen Seiten verlinkt ist kam es zu der gehäuften Wahrnehmung von Hängern. Da zudem niemand den Inhalt von ad.doubleclick.com vermisst hatte war das Problem noch etwas schwieriger zu lokalisieren.

Sendmail

Dies ist auch ein interessantes Problem dem ich erst neulich begegnet bin. Dies ist in sofern interessant, da es eingehende E-Mails betraf die via Mailertable-Eintrag nach innen weitergeleitet werden sollten.

In einer Mailertable gibt es zwei Einträge, den Domainname des Empfängers und der Server an den diese E-Mails weitergeleitet werden sollen.

Nun sollte man meinen, sendmail braucht hierfür kein DNS, da in der Mailertable als Zielserver eine IP-Adresse eingetragen war. Diese war sogar in eckigen Klammern angegeben damit sendmail direkt an die IP-Adresse sendet und nicht erst einen MX-Record für die Adresse suchen muss.

Es gibt aber eine Eigenschaft vom sendmail die sich canonify nennt. Dabei versucht sendmail die Domain des Empfängers aufzulösen bevor er die Mailertable überprüft. Das interessante dabei: Existiert ein Mailertable-Eintrag, so ist es egal ob der Name auflösbar ist oder nicht, die E-Mail wird in beiden Fällen über den Eintrag weitergeleitet.

Jetzt ist es aber vorgekommen, dass die E-Mails nicht zugestellt wurden, sie blieben in der Queue liegen mit der Fehlermeldung, dass die Zustellung wegen Problemen mit der Namensauflösung verzögert wird.

Hmm, was war das? Wir brauchen den Namen doch garnicht...

Nun wird es interessant, es ist ein sehr seltsames Konstrukt:

Soweit ist das in Ordnung und funktioniert auch ohne Probleme.

Füllen wird das Problem mit einem Beispiel:

mglug.lug-erding.de   IN   NS  ns1.mglug.lug-erding.de

Was passiert nun? Ganz einfach, aufgrund seiner Zonendatei weiß der Nameserver, dass; ein anderer zuständig ist. Er darf diesen aber wenig der Einschränkung "forward only" nicht befragen. Also leitet er die Anfrage an seinen forwarder weiter, dieser ist der externe Nameserver mit den offiziellen, d.h. für das Internet bestimmten, Adressen.

Dieser externe Nameserver weiß aber nichts von der Delegation im internen Netz!

Was sendet er also als Antwort zurück?

Genau
Diese Adresse kenne ich nicht, authorative Antworten können vom Nameserver für die Domain lug-erding.de erhalten werden.

He? War nicht dieser Nameserver selber für diese Domain zuständig und stand da nicht, dass diese Domain delegiert ist. Warum sollte sie nun wieder nicht delegiert sein?

Bingo!
Der Nameserver liefert einen SERVERR zurück. Er sagt weder, was die IP-Adresse ist noch sagt er, dass es diese Domain nicht gibt, er sagt lediglich, dass es irgendwo einen Konfigurationsfehler gibt.

Sendmail reagiert hier wie es zu erwarten wäre:

''sendmail'' lässt die E-Mail einfach in der Queue liegen und versucht es später noch einmal!
Das ist wohl ein gutes Beispiel dafür, dass Probleme mit Nameservern sehr diffizil sein könnnen!

Abschluss

Ich vermute, dass die meisten es niemals vermutet hätten aber DNS ist doch deutlich umfangreicher als es den Anschein hat.

Nun könnte man fragen:

Warum wird im normalen Alltag diese Komplexittät nicht wahrgenommen?

Die Antwort lautet wohl:

Weil DNS meistens sehr gut funktioniert

Es gibt recht selten wirkliche Probleme die auch realisiert werden. Verstärkt wird dieser Eindruck noch dadurch, dass die DNS-Domains auf viele DNS-Server verteilt sind die meistens noch mehrere slave Nameserver haben. Fällt davon einer aus, dann hat das erst einmal keine Auswirkungen wenn ein slave antwortet.

Bei groben Fehlern kann es natürlich sein, dass ein paar DNS-Server komplett versagen. Aber angesichts der Vielzahl an existierenden Domains fällt es einem beim Surfen nicht weiter auf, dass vielleicht ein Icon gebrochen ist.

Bei viele Fehlern, ich denke das hat das letzte Kapitel gezeigt, kann durchaus ein DNS-Problem vorliegen, nur es wird nich als ein solches erkannt. Demzufolge wird auch nicht in dieser Richtung gesucht. Da ist es dann gut wenn über einen ISP geschimpft werden kann...

E-Mail ist der andere wichtige Zweig im Internet und wie das Beispiel mit sendmail gezeigt hat können gute Mailserver DNS-Probleme temporär aussitzen. Es sollte wohl unwahrscheinlich sein, dass ein Nameserver für mehrere Tage ausfällt.

Angesichts der Vielzahl an Konfigurationsmöglichkeiten von BIND, es gibt keine Nameserver-Implementierung die soviele RFC-Features besitzt, neigen viele dazu nach Alternativen zu suchen, ihnen erscheint BIND einfach zu komplex.

Wie schön einfach ist doch da ein Microsoft DNS-Server, mit nur wenigen Klicks hier und da kann eine Zone nebst DNS-Namen eingerichtet werden. Das ist schön einfach, es braucht noch nicht einmal großartig nachgedacht werden!

Stimmt, es hält einem aber auch nicht davon ab Blödsinn zu konfigurieren. Ein Wissen über die Funktionsweise von DNS ist immer angeraten. Ein anderer Punkt ist, dass viele Features die BIND bietet bei anderen Systemen nicht konfigurierbar sind oder es muss sogar in der Registry editiert werden, so z.B. für den Timeout des Resolvers.

Ist das dann ein Vorteil?

Sicherlich für Otto-Normalverbraucher, der nur sein Heimnetzwerk mit einer handvoll Computer administrieren will, wird das durchaus genügen. Leider besitzen viele Administratoren größerer Netze leider auch nicht merh Kenntnisse über DNS.

Aber wie sieht das mit diesen einfachen Lösungen aus, wenn es an die Fehlersuche geht? Müssen dann nicht zumindest soviel Kenntnisse vorhanden sein, dass bekannt ist wie eine Zone aufgebaut ist oder sein sollte?

Sind dig und nslookup nicht mächtige Werzeuge für die Analyse von DNS? Oder reicht es, wenn DNS-Namen mit ping aufgelöst werden können? Aber wie finde ich da MX-Records, Delegationen, TTLs, SOAs,...?

Ich denke es kann nicht schaden, wenn jeder das alles einmal gehört hat. Dabei ist ohne Bedeutung ob jemand selber eine Nameserver betreibt/betreiben möchte oder nicht. Man steht zumindest nicht ganz blöde dar, wenn man wirklich auf Probleme mit DNS stößt und kann sich z.B. durch Ändern des nameserver-Eintrages in der resolv.conf behelfen.

Und ein letzte Wort zur Komplexität von BIND:

Diese ist halb so schlimm, die Voreinstellungen sind exzellent, hier muss extrem selten etwas angepasst werden. D.h. direkt out of the box läuft der Server schon sehr gut. Es gibt aber die Möglichkeit durch ein paar kleine Änderungen sehr elegant das Verhalten zu ändern, z.B. einen forwarder und forward only einzutragen.

Das geht bei vielen anderen Nameservern nicht, sie kennen zwar forwarder aber nicht forward only, d.h. gefällt diesen die Antwort vom forwarder nicht, so starten sie selber iterative Anfragen. Das kann zu Verzögerungen im Minutenbereich kommen!

Von den Debug-Möglichkeiten habe ich hier noch garnicht gesprochen. Welcher Nameserver ist sonst so gut dokumentiert?

Ein exzellentes Buch zu diesem Thema ist

DNS and BIND
Cricket Liu & Paul Albitz
O'Reilly, 5. Auflage        
ISBN: 0-596-10057-4

Es ist kaum zu glauben, dass fast alles was in den letzten Tagen zum Thema DNS gemailt wurde an einem Abend durchgesprochen wurde!

Nun solltet Ihr alle beim Thema DNS topfit sein und Euch nicht so leicht von redefreudigen Beratern (neu-deutsch "Consultant") über den Tisch ziehen lassen.

In diesem Sinne

Dirk Geschke, dirk@lug-erding.de