Bind9

Inhaltsverzeichnis

Einleitung

Bind9 ist ein Server, mit dem man IP-Adressen <==> Hostadressen auflösen kann, deren Authority man hat.

Warum

Ich verwende Bind9, um IP-Adressen (z.B. 192.168.1.1) in meinem internen LAN mit Hostadressen zu belegen und umgekehrt. Zudem belege ich IPv6-Adressen, die mir via einem Tunnelbroker gehören und deren Authority ich habe, mit Hostadressen.

Funktionsweise

Bind9 läuft als Deamon im Hintergrund auf Port 53 (UDP und TCP) und lauscht auf Auflösungsanfragen.

Installation

Linux (Debian)

Die Installation erfolgt wie üblich mit:

apt-get install bind9

Konfiguration

Theorie

Ganz wichtig ist, diese Absätze genau durchzulesen, damit man weiß, was man überhaupt macht bzw. warum wie was passiert!!

Zum geschichtlichen Hintergrund: Als das Internet in den 60ern/70ern mit ein paar Rechnern startete, war es "in", in der Datei /etc/hosts, die es übrigens heute noch gibt, jeden Rechner mit IP-Adresse und Hostnamen einzutragen. Bei jeder Änderung eines Rechners mußten jedoch sämtliche Hosts-Dateien geändert werden, was einen überproportionalen Aufwand darstellte, je mehr Rechner ins Netz kamen. Deshalb kam man auf die Idee, dezentrale Dienste zu entwickeln: Der DNS (Domain Name System)-Standard war geboren.

Vereinfacht gesagt wird bei bestimmten Registrierungsstellen (für .de-Domains die DENIC) hinterlassen, welche Nameserver für die Auflösung von Domains und Subdomains zuständig sind. Aus Gründen der Stabilität müssen für .de-Domains zwei DNS-Server, die auf zwei unterschiedlichen, aber festen IPs liegen, festgelegt werden, wobei einer als Master und der andere als Slave fungiert. Ähnlich verhält es sich, wenn man IPs registriert, daß der Registrar/Owner der IP-Adressen den/die DNS-Server festlegt, die für die Rückwärtsauflösung verantwortlich sind - aber dazu später mehr.

Problembeispiel: Wenn man im Browser die Webseite http://www.lug-wr.de aufrufen würde, würde der PC zunächst hilflos dreinschauen, weil er die Adresse dazu nicht kennt. Also fragt er nach dem in der Datei /etc/resolv.conf angegebenen DNS-Server nach dem A- bzw. CNAME-Record für www.lug-wr.de. Dieser weiß entweder die Antwort oder fragt sich weiter durch...das kann im Extremfall bis hoch zu den 13 DNS-Rootservern im Internet gehen. Anschließend wird die Antwort (in dem Fall die entsprechende IP-Adresse 217.160.202.102) an den fragenden PC zurückgeschickt, der nun den Server und damit die Webseiten anfragen kann.

vorbereitende Maßnahmen

Prüfen Sie zunächst, ob die folgenden Dateien mind. folgende Zeilen beinhalten:

/etc/nsswitch.conf:

hosts: files dns

Dies sorgt dafür, daß Programme zunächst /etc/hosts befragen, danach der in /etc/resolv.conf angegebene DNS-Server.

/etc/host.conf:

order hosts,bind

Dies bewirkt, daß Routinen beim Aufschlüsseln des Computernamens zunächst /etc/hosts befragen, danach den beim in /etc/resolv.conf angegebenen DNS-Server.

Last, but not least... /etc/resolv.conf:

search irgendne.domain.ltd
nameserver 127.0.0.1

Was bedeuten nun diese Zeilen?
search gibt die Suchreihenfolge von Domains an. Wenn man nun nach einem PC brabbel sucht, wird zunächst brabbel.irgendne.domain.ltd versucht, anschließend brabbel. Deshalb sollte man nicht allzuviele Suchdomains eintragen, da sonst das Durchsuchen aller ineffektiv ist.
nameserver gibt den zu befragenden DNS-Server für IP-/Domainauflösungen an. 127.0.0.1 bedeutet "localhost" und kennzeichnet den eigenen PC, da wir ja einen eigenen DNS-Server einrichten wollen.

zunächst nur einen "Caching-only"-Nameserver

Ein Caching-only-Nameserver ist, wie der Name schon sagt, ein DNS-Server, der auf Namensanfragen antwortet und sich bei der nächsten Anfrage an die alte Antwort erinnert. Dieses Vorgehen verkürzt vor allem die Wartezeit bei jeder weiteren Anfrage - besonders, wenn man nur eine langsame Verbindung hat.

Bei der apt-Debianinstallation braucht man dazu nicht mehr viel zu tun. Man muß die Datei /etc/bind/named.conf.options bearbeiten und die auskommentierte Stelle bei dem "forwarders" ändern, so daß es so aussieht:

forwarders {
    DNS-IP1; DNS-IP2; ... ; DNS-IPn;
};

Hierbei handelt es sich um IPs von DNS-Servern, an denen der DNS-Aufruf weitergeleitet wird, wenn unser eigener DNS-Server diesen nicht auflösen kann. Hierbei sollten die des eigenen Providers angegeben werden, da dies in der Regel am schnellsten ist, der Traffic im eigenen Netz verbleibt und fremde DNS so eingestellt sein könnten, daß sie nur Verbindungen vom eigenen Anbieter erlauben.

Die Adressen erhält man entweder vom eigenen Provider oder man macht, wenn man sich ganz normal ins Netz eingewählt hat, mal ein cat /etc/resolv.conf; in den nameserver-Zeilen stehen die benötigten IPs.

Danach natürlich den DNS neu starten:

/etc/init.d/bind9 restart

eine eigene Domain verwalten

Theorie

Bevor wir damit anfangen, müssen wir uns erstmal tiefer mit der DNS-Materie beschäftigen!

Der DNS ist hierarchisch aufgebaut, wobei die Wurzel mit einem Punkt (.) bezeichnet wird. Darunter befinden sich die Top-Level-Domains, wie .com .org .edu .info und vor allem unsere bekannten .de-Domains. Natürlich gibt es noch etliche mehr. An diesen schließen sich dann die Domains und noch weiter darunter also die Subdomains. Das bedeutet also, daß hierarchisch von rechts nach links gelesen werden muß und dies wiederum, daß unserem Server zunächst bekannt sein muß, wer z.B. für die .de-Domains zuständig ist. Wenn er also keinen entsprechenden Forwarder zum Befragen hat (siehe 5.3) oder dieser den dafür zuständigen Server nicht kennt, fragt unser DNS-Server einen Root-Server an, die sich bei bind9 in der /etc/bind/db.root befinden.
Beispielsweise www.heise.de: Wird also von rechts also erstmal der Server für .de gesucht, dann nach links heise und am Schluß www. Was viele kaum wissen und wahrnehmen, weil es der "Quasi-Standard" im Webseitenbereich ist, ist also, daß www auch nur eine Subdomain ist wie jede andere auch.

Eine andere Domain, die fast keinem so bekannt ist, aber bei DNS-Servern fast genauso wichtig sind, ist "in-addr.arpa". Sie ist so wichtig wie eine normale Domain und dient dazu, zu einer bekannten IP-Adresse den entsprechenden Host zu finden. Wichtig ist hierbei, daß die IP rückwärts angegeben werden muß. Wenn man also zur IP 10.20.30.40 den vollen Host finden möchte, muß man sich 40.30.20.10.in-addr.arpa denken!
Wozu ist das so wichtig, wird man sich denken? Schließlich will man in der Regel einfach einen Alias (Host) für sein Ziel haben, um sich die IP nicht merken zu müssen. Und wenn man die IP schon kennt, ist es ja eh egal... Nun gibt es aber Dienste, die anhand der Hin- und (!) Rückwärtsauflösung entscheiden, ob sie mit einem "reden" wollen oder nicht. Denn man geht davon aus, stimmen sowohl der A- (Domain->IP) als auch der PTR-Record (IP->Domain), ist man wirklich Herr über seine Domain.
So bekommt man im IRC nur dann die gewünschte vHost, wenn beide Einträge bei den entsprechenden DNS-Servern übereinstimmen, oder Mailserver/Spammailsniffer entscheiden darüber mit, ob es eine echte Mail ist. Manche MTAs verweigern auch Mails mit unterschiedlicher Domain und IP.

Endlich - eine eigene Domain ;-)

In diesen Beispielen wird die Domain "test" verwendet und der Rechnername ist "linux", da diese nicht vergeben ist und somit niemand anderen stört. Wichtig ist noch: Für Domains kann man nur Buchstaben (a-z), Zahlen (0-9) und den Bindestich (-) benutzen. Mehr nicht!!! Groß- und Kleinschreibung ist egal, so ist für den DNS-Server alpha.linux.test das selbe wie alpha.Linux.TEST usw.

Vorweg, unsere Zonenbekanntmachungs-Änderungen werden in der /etc/bind/named.conf.local gemacht. Diese Datei ist wie geschaffen für uns, da sie für lokale Veränderungen gedacht ist (die named.conf bitte noch nicht anrühren!) - also ein idealer Platz zum austoben :-)
Außerdem hat sie noch den Vorteil, sollte mal vom apt ein Update des Bind kommen, so bleibt diese Datei unangerührt, die eigenen Änderungen also erhalten.

Aber nun zum Ernst des Lebens *lol*: Legen wir eine Datei db.test an mit folgendem Inhalt (um sich die Arbeit zu erleichtern, kann man sich eine Kopie der Datei db.local anlegen, mit "cp db.local db.linux.test", und dann halt abändern):

;
; BIND data file for test domain
;
$TTL    604800
@               IN      SOA     ns.linux.test. hostmaster.linux.test. (
                             1         ; Serial
                        604800         ; Refresh
                         86400         ; Retry
                       2419200         ; Expire
                        604800 )       ; Negative Cache TTL
;
                        NS      ns
                        MX  10  mail1.linux.test.
                        MX  20  mail2.linux.test.
ns              IN      A       192.168.196.10
mail1           IN      A       192.168.196.14
mail2           IN      A       192.168.196.15

Ohje, ziemlich viel, was? Was bedeutet das alles nun?

In jeder (!) Zonendatei gibt es den SOA-Eintrag (Start of Authority). Dieser gibt an, welches die Ursprungszone ist (hier linux.test) und mailtechnisch den Verantwortlichen dieser Zone. Dabei wird immer der erste Punkt als "at" (@) gelesen, was also bedeutet, daß diese Mailadresse sich aus hostmaster@linux.test zusammensetzt.
ACHTUNG: Der SOA-Eintrag (ns.linux.test) muß (!) ein gültiger A-Record sein, kein CNAME-Eintrag (zu denen unten später mehr).

Der einleitende alleinstehende Klammeraffe kennzeichnet hier substituierend die Domain (also linux.test). Außerdem kann man sich nachfolgende "IN"s sparen. Die NS-Zeile hätte man also auch so schreiben können:

linux.test.   IN   NS   ns.linux.test.

Wie auch immer, jedenfalls kennzeichnet NS den zuständigen Nameserver für die Domain linux.test.

WICHTIG: Es ist kein Schreibfehler, daß oben der abschließende Punkt fehlt, unten jedoch nicht. Denn der DNS-Server setzt bei fehlendem Punkt immer die Domain hinten dran. Bei vorhandenem Punkt jedoch nicht! Also immer drauf achten.

Weiter geht's...der MX-Eintrag (Mail eXchanger) gibt anderen Mailservern die Adresse zurück, an die Mails an irgendwen@linux.test geschickt werden sollen. Die Zahl dahinter ist die Priorität, je kleiner, desto wichtiger. Hier würde ein Mailserver also zunächst versuchen, Mails an den mit Prio10 zu schicken. Schlägt dies fehl, versucht er den Prio20-Server.
WICHTIG: MX-Einträge dürfen keine (!) IP-Adressen, sondern müssen Hostnamen sein!

Die A-Records schließlich kennzeichnen die IP, nach denen der entsprechende Hostname aufgelöst werden soll.


Jetzt müssen wir dem Nameserver natürlich noch bekanntmachen, daß er diese Zonendatei auch verwenden soll. Hierzu rühren wir unsere named.conf.local an, in der wir nun folgendes hinzufügen:

zone "linux.test" {
        type master;
        file "db.linux.test";
};

ACHTUNG: Hier wird bei zone am Ende kein (!) abschließender Punkt gesetzt!

Und neustarten:

/etc/init.d/bind9 restart


Jetzt testen wir erstmal unsere Konfiguration aus:

nslookup ns.linux.test
nslookup mail1.linux.test
nslookup mail2.linux.test

Geht? Na wunderbar - erstmal n Kaffee trinken *g*

Ergänzungen unseres ersten Domainservers

Wer meint, damit wär das alles, was bind9 kann, hat sich getäuscht ^^

Ergänzen wir doch unsere db.linux.test um folgendes:

gw     IN    A          192.168.196.1
                 HINFO   "Athlon XP+" "Linux 2.6.12"
                 TXT        "Der Router ins Internet"

www  IN   CNAME   ns

Hier gib's zwei Neuigkeiten:
Der HINFO-Record (Host Information). Dieser besteht aus zwei Parametern, der erste aus dem Prozessor/Architektur, der zweite aus Betriebssystem.
Der CNAME-Record (Canonical Name) erlaubt einem, einen Rechner mehrere Namen zuzuweisen. www ist hier also ein Alias für ns.

Wichtig für die Verwendung sind hierbei die Goldenen Regeln: SOA-, MX- und CNAME-Einträge dürfen niemals (!) auf CNAME-Einträge zeigen, sondern nur auf A-Records!

Deshalb ist verboten:

alter   IN    CNAME   www

aber erlaubt:

alter   IN    CNAME   ns


Probieren wir's also aus:

/etc/init.d/bind9 restart
nslookup www.linux.test

Geht? - Ausgezeichnet, jetzt haben Sie sich aber ein Essen verdient! :-)

Die Rückwärtsauflösung

Soweit so gut, wir sind nun in der Lage, Domains und Hosts aufzulösen. Nun fehlt uns aber noch der Part für die IP-Adressen, um diese wiederum in Hosts auflösen zu können.

Legen wir eine Datei db.192.168.196 an mit folgendem Inhalt (um sich die Arbeit zu erleichtern, kann man sich eine Kopie der Datei db.127 anlegen, mit "cp db.127 db.192.168.196", und dann halt abändern):

;
; BIND reverse data file for 196.168.192.in-addr.arpa
;
$TTL    604800
@       IN      SOA     ns.linux.test. hostmaster.linux.test. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns.linux.test.

1       IN      PTR     gw.linux.test.
10     IN      PTR     ns.linux.test.
14     IN      PTR     mail1.linux.test.
15     IN      PTR     mail2.linux.test.

Die Zahlen geben hier die letzte Stelle der IP-Adresse an. Die "1" also 192.168.196.1.

PTR kennzeichnet hier also, nach welchem Namen die IP aufgelöst wird. Man hätte hier auch wieder wie üblich gw, ns usw. schreiben können.

Nun müssen wir dem Bind9 diese neue Zonendatenbank wieder mitteilen, also ab in die named.conf.local und ergänzen:

zone "196.168.192.in-addr.arpa" {
        type master;
        file "db.192.168.196";
};

Zu beachten ist, würden hier nur zwei oder gar eine IP-Stelle stehen, müßte man den Rest in der Zonendatei ergänzen, ebenfalls in der umgekehrten Reihenfolge! D.h. einmal zone "198.192.in-addr.arpa" und in der db-Datei dann 10.100, wenn man nach 192.168.100.10 sucht.

Nun also neustarten...

/etc/init.d/bind9 restart

...testen...

nslookup 192.168.196.1
nslookup 192.168.196.10

...usw.


Bevor wir das Thema schließen, noch eine kurze Erklärung, was die Flags Serial, Refresh usw. bedeuten:
Serial gibt hier eine Art Seriennummer an. Eingebürgert hat sich das Formal YYYYMMDDNN, wobei Y das Jahr, M der Monat, D der Tag und N eine zweistellige Nummer ist, die sich erhöht, wenn man am selben Tag eine weitere Änderung gemacht hat. Die erste Änderung vom achten Mai 2005 wäre also 2005050801. Diese Angabe ist wichtig, damit andere Nameserver im Internet erkennen können, daß man seinen Nameserver geupdated hat und evtl. neue Angaben verfügbar sind, ansonsten benutzen sie weiter ihre gecachten Werte.
Refresh gibt in Sekunden an, wie oft Slaves nachfragen, ob sich etwas geändert hat.
Retry gibt in Sekunden an, wann der Slave erneut anfragt, wenn der Master nicht geantwortet hat.
Expire gibt in Sekunden an, wann der Slave die Zone deaktiviert, wenn der Master auf einen Zonetransfer-Request nicht reagiert.
Negative Caching TTL gibt in Sekunden an, wie lange dieser Record in einem Cache gültig sein darf.

Diese Geschichte ist relevant für Master-Slave-Server, die im folgenden behandelt werden.


Soweit erstmal alles funktionierend und zufrieden? Fein - dann feiern Sie mal eine Party ;-))

Master-Slave-Server verwalten

Soweit, sogut. Der eigene DNS-Server funktioniert nun komplett.
Nun wollen wir noch ein Master-Slave-DNS aufbauen, d.h. sowohl der Master als auch der Slave kennen unsere Einstellungen, Zonen und Authoritys.

Voraussetzung für die Einrichtung eines solchen Systems ist selbstverständlich eine fehlerfreie Einrichtung bis hierhin sowie die Grundinstallation eines zweiten DNS, der den Slave spielen soll. Der bisher eingerichtete mit den Domains ist der Master.

Nach deren Einrichtung muß man nicht mehr viel tun. Auf dem Master muß man in der named.conf.local in der entsprechenden Zone folgendes einstellen:

zone "linux.test" {
        type master;
        file "db.linux.test";
        allow-transfer {
                Slave-IP;
        };
};

Auf dem Slave wiederum muß diese Zone in der named.conf.local hinzugefügt werden, und zwar in dieser Art und Weise:

zone "linux.test" {
        type slave;
        masters { Master-IP; };
};

Analoges muß man natürlich auch noch für die Reverse-Zonen machen. Für Master- und Slave-IP muß man natürlich die entsprechenden IP-Adressen der DNS-Server einsetzen.


Einen dicken Vorteil hat das ganze: Weil auf beiden Rechnern nun die Zonen verfügbar sind, kann man - etwa bei VPN-Netzwerken - auf beiden Seiten direkt die Hostnamen nutzen und muß nicht mit IPs arbeiten. Dabei hat jede Seite Einfluß auf ihren DNS und muß daher nicht immer mit dem anderen abstimmen, daß man nun was ändern will, weil Änderungen unmittelbar auf die anderen geslavten DNS-Server durchschlagen.

eine eigene Domain verwalten mit IPv6

Hierbei gehe ich davon aus, daß man sich bereits mit den grundlegenden Dingen eines Nameservers auskennt, also etwa was ein A-Record ist oder eine Rückwärtsauflösung. Gegebenenfalls ist der Punkt 5.4 zumindest gedanklich mal durchzuarbeiten :-)

Was sind eigentlich IPv6-Adressen?

Diese sind 128bittig im Gegensatz zu den herkömmlichen 32bittigen IP-Adressen (auch IPv4 genannt) und bestehen aus acht 16-bittigen Tupeln im hexadezimalem Format. So wäre z.B. FE80:2945:2550:FADC:2881:1800:4239:AFB7 eine solche Adresse. Adreßteile mit ausschließlich Nullen können abgekürzt werden mit :: also z.B. FE80::AFB7, wenn die Zwischenteile nur Nullen enthalten. Die Abkürzung mittels Doppel-Doppelpunkt darf man nur einmal nutzen.

Bei solchen Auswüchsen an Ziffern sieht man ganz deutlich die umso größere Notwendigkeit eines Domain-Name-Server-Systems, deshalb hat man gottseidank in Bind Version 9 diese Unterstützung hinzugefügt.

Um IPv6 nutzen zu können, benötigt man entweder einen IPv6-fähigen Kernel (ab 2.4) oder IPv6-Modul, sowie einen Tunnelbroker, sofern man keine IPv6-Adresse vom Provider mitkriegt (heute noch der Normalfall).

Vorbereiten von Bind9 für IPv6

Um Bind9 für IPv6-Anfragen fit zu machen, muß man in der Datei /etc/bind/named.conf.options folgenden Eintrag hinzufügen:

options {
    ...
    listen-on-v6 { any; };
};

Dies macht dem Bind9 klar, daß er doch bitteschön (auch) auf vorhandenen IPv6-Adressen lauschen soll.

HINWEIS: Bei aktuellen bind9-Versionen bei debian testing ist diese Option bereits vorhanden.

Einrichtung von A- und PTR-Records mit IPv6

Nehmen wir die db.linux.test. IPv6-Adressen löst man nicht mit A auf, sondern AAAA, so daß die Stelle in dieser Datei heißen muß:

test6     IN      AAAA      FE80:2222:3333:4444:5555:6666:7777:8888
www6   IN      AAAA      FE80:2222:3333:4444:5555:7777:8888:9999

In der named.conf.local muß nichts gesondert geändert werden, da nach wie vor nach der Domain gesucht wird und sich an deren Suchalgorithmus nichts geändert hat.


Schwieriger wird es bei der Reverse-DNS-Auflösung, und das hat u.a. mit der Historie von IPv6 zu tun:

IP-Anfragen wurden früher mit *.ip6.arpa aufgelöst. Neuer und heute üblich ist die *.ip6.int, jedoch benutzen noch weitaus nicht alle IPv6-Server, die einen Hostnamen anfragen, diese Methode. Dies hat zur Folge, daß man zwei Einträge in der named.conf.local hinterlassen muß, um ganz sicherzugehen.

Auch das wird schwerer, denn der arpa-Eintrag setzt sich aus Einzeltupel zusammen, die durch einen Punkt getrennt sind. Nehmen wir mal an, wir hätten vom Tunnelbrokeranbieter ein FE80:2222:3333:4444::/64-Netz gekriegt, dann müßten wir die Einträge in der named.conf.local so tätigen:

zone "4.4.4.4.3.3.3.3.2.2.2.2.0.8.E.F.ip6.arpa" {
        type master;
        file "db.F.E.8.0.2.2.2.2.3.3.3.3.4.4.4.4";
};

zone "4.4.4.4.3.3.3.3.2.2.2.2.0.8.E.F.ip6.int" {
        type master;
        file "db.F.E.8.0.2.2.2.2.3.3.3.3.4.4.4.4";
};

Die dazu gehörende Datei db.F.E.8.0.2.2.2.2.3.3.3.3.4.4.4.4 sieht ähnlich aus wie die db.192.168.196, allerdings enthält sie keinerlei IPv4-Auflösungen, da sie ja von ip6.arpa/int aufgerufen wird.

Das Dateifragment sieht damit analog zur Hinauflösung so aus:

8.8.8.8.7.7.7.7.6.6.6.6.5.5.5.5    IN    PTR    test6.linux.test.
9.9.9.9.8.8.8.8.7.7.7.7.5.5.5.5    IN    PTR    www6.linux.test.

Von "http://www.lug-wr.de/wiki/index.php/Bind9"

Diese Seite wurde bisher 27190 mal abgerufen. Diese Seite wurde zuletzt geändert um 04:35, 20. Nov 2006. Inhalt ist verfügbar unter der GNU Free Documentation License 1.2.