Dynamisches DNS mit BIND selbst machen
Der Artikel befasst sich mit der Einrichtung von dynamischem DNS auf einer eigenen DNS-Infrastruktur mit BIND ohne externe Anbieter.
Allgemeines
Der Platzhirsch unter den DNS-Servern ist sicherlich der von dem Internet Systems Consortium (ISC) entwickelte Berkeley Internet Name Domain Server (BIND). Ich nutze üblicherweise lieber leichtgewichtigere Programme wie den für fast alle Zwecke ausreichenden dnsmasq, aber es gibt gewisse Konfigurationen, bei denen ein Weg an der großen, aber eben auch mächtigen Software nicht vorbei führt. Eine solche liegt etwa dann vor, wenn man dynamisches DNS einrichten möchte.
Als dynamisches DNS bezeichnet man eigentlich lediglich eine besondere
Art der Konfiguration eines DNS-Servers. Dem Grunde nach unterscheiden
sich dynamisch erzeugte Domains nicht von regulären; genauso wie bei
einer „gewöhnlichen“ Domain wird einem DNS-Eintrag (Domain) eine
IP-Adresse zugeordet, z.B. example.com 93.184.216.34 (IPv4) oder
2606:2800:220:1:248:1893:25c8:1946 (IPv6). Diese Zuordnung wird wie im
DNS üblich mithilfe der A- und AAA-Records realisiert.
example.com. 85092 IN A 93.184.216.34
example.com. 85352 IN AAAA 2606:2800:220:1:248:1893:25c8:1946
Was dynamisches DNS von regulärem DNS unterscheidet ist die Art und Weise, wie der A/AAAA-Record erstellt wird. Während man im klassischen DNS-Gebrauch eine feste IP-Adresse permanent für die gewünschte Domain hinterlegt, wird bei dynamischem DNS diese Zuordnung sehr häufig geändert. Dies ist für gewöhnliche Server nicht erforderlich, betreibt man jedoch seinen eigenen Server zuhause, dann ist man oft Opfer der dynamischen Adressvergabe der großen Internet Service Providers (ISPs). Der DNS-Eintrag veraltet, d. h. zeigt auf eine falsche IP-Adresse (die jetzt womöglich ein anderer Kunde innehat) und die Nutzung ist unmöglich. Mithilfe von dynamischem DNS wird durch häufige, automatische Änderung des A/AAAA-Records sichergestellt, dass er aktuell bleibt. Tatsächlich ist die Relevanz von dynamischem DNS bei AAAA-Records, also im IPv6-Universum, eigentlich nicht vorhanden. Dynamische IP-Adressvergabe hat seine Ursache in der Knappheit der freien IPv4-Adressen und dient dazu, dass Provider mehr Kunden bedienen können, als sie eigentlich Adressen haben. Mit IPv6 stehen wieder mehr als genügend Adressen zur Verfügung (sollte man jedenfalls meinen), sodass jedermann eine ordnungsgemäße statische IPv6-Adresse erhalten sollte (tatsächlich ist die Vorstellung, man solle direkt ein /64-Netz erhalten), die ohne weiteres in einen AAAA-Record eingetragen werden kann und es so jedem (wieder) ermöglicht, daheim seine Serverdienste selbst zu betreiben. Ich konzentriere mich in diesem Artikel daher ausschließlich auf die IPv4-Umsetzung, sprich auf dynamische A-Records.
Dynamisches DNS wird heutzutage von einigen mehr oder minder seriösen Anbietern kostenlos oder gegen Bezahlung zur Verfügung gestellt. Wer sie nutzt, begibt sich damit wissentlich in die Gesellschaft von weniger ehrlichen Individuen, die dynamisches DNS als Tarninstrument für Malware-Verteilung oder illegales Fileshring ansehen; zwar ist wohl davon auszugehen, dass sich die kriminelle Nutzung dieser Dienste als Minderheit darstellt, dennoch ist es genug, um die Aufmerksamkeit gewisser Stellen auf dieselben zu lenken, wie die unrühmliche temporäre Abschaltung des Dienstes no-ip.com auf Betreiben von Microsoft zeigt. Macht man sich von einem solchen Anbieter abhängig, kann man schnell das Nachsehen haben.
Es ist aber auf erstaunlich einfache Weise möglich, dynamisches DNS selbst zu betreiben. Der Haken an der Sache: Man muss über einen öffentlich zugänglichen Server mit fester IP-Adresse disponieren können oder zumindest Beziehungen zu einem Admin eines solchen haben. Dennoch gibt es Konstellationen, in denen dynamisches DNS auch dann noch Sinn macht: etwa, wenn man private Daten lieber am langsamen Internetanschluss zuhause hostet, öffentliche Daten dagegen auf dem schnellen Webserver mit fester IP-Adresse hat. In einem solchen Fall kann man auf dem ohnehin öffentlich erreichbaren Server BIND installieren und so dynamisches DNS für den privaten Server zuhause umsetzen.
Anpassung des DNS
Damit dynamisches DNS überhaupt möglich ist, muss man über eine
beliebige Domain verfügen, etwa example.com. Ich habe die Erfahrung
gemacht, dass es zwar möglich ist, dynamisches DNS unmittelbar auf der
2nd-level-Domain zu betreiben, das aber mit unverhältnismäßigen Kosten
verbunden ist, weil typische Domain Reseller üblicherweise wenigstens
zwei unabhängige DNS-Server mit eigenen IPv4-Adressen fordern. Es ist
daher sinnvoll, dynamisches DNS nur auf einer Subdomain einzusetzen,
etwa dynamic.example.com, welches im Folgenden so eingestellt werden
soll, dass es stets zur IPv4-Adresse des heimischen Netzwerkes
auflöst.
Zunächst erschafft man eine neue DNS-Zone durch Erstellen eines NS-Records im Kontrollzentrum des eigenen DNS-Anbieters und erstellt zusätzlich feste A/AAAA-Records für den Nameserver selbst, auf dem später BIND laufen wird. Das kann etwa so aussehen (Domainnamen und IP-Adressen beispielhaft):
ns.example.com. 10000 IN A 10.10.10.1
ns.example.com. 10000 IN AAAA fe80::2
dynamic.example.com. 10000 IN NS ns.example.com
Damit weiß die DNS-Welt darüber Bescheid, dass alle Anfragen, die die
Auflösung von dynamic.example.com (oder noch tieferen Domains, etwa
a.b.c.dynamic.example.com) betreffen, an den Nameserver
ns.example.com zu richten sind, welcher wiederum unter den
angegebenen IP-Adressen erreichbar ist.
Installation von BIND
Die Installation von BIND erfolgt mit den üblichen Methoden des lokalen Paketmanagers.
Erzeugen der Updateschlüssel
Dynamisches DNS erfolgt in einem nach RFC2136 standardisierten
Verfahren, bei dem ein besonderer DNS-Befehl (UPDATE) zusammen mit
einer kryptographischen Signatur an den DNS-Server (also BIND)
übermittelt wird. Sowohl Server als auch Client sind im Besitz eines
kryptographischen Schlüssels (sog. „shared secret“), anhand dessen sie
sie Signaturen des jeweils anderen überprüfen können. Das ist zwar
nicht so so sicher wie ein echtes asymmetrisches Verfahren mit
öffentlichem und privaten Schlüssel, ist aber besser als nichts. Es
wäre doch sehr misslich, wenn jedermann die DNS-Records neu setzen
könnte und nicht bloß der Inhaber.
Das erforderliche Schlüsselpaar erzeugt man mithilfe des mit BIND
mitgelieferten Programms dnssec-keygen:
$ dnssec-keygen -a hmac-sha256 -b 256 \
-n HOST dynamic.example.com.
Kdynamic.example.com.+123+45678
Den Aufruf habe ich Abschnitt 4.5.1.1 des Benutzerhandbuchs entnommen;
die Manpage lehrt, dass -a den Algorithmus festlegt, -b die Anzahl
Bits des Schlüssels ist (das Benutzerhandbuch sagt, dass maximal 256
möglich sind, also habe ich das gewählt) und dass -n den
Schlüsseltyp festlegt, bei dem HOST erforderlich ist, weil ja ein
Schlüssel für einen bestimmten Host erzeugt werden soll und nicht
etwa, wie in DNSSEC üblich, eine ganze Zone signiert werden soll. Man
beachte im Übrigen den für DNS-Einträge üblichen abschließenden
Punkt.
Die Datei Kdynamic.example.com.+123+45678.private enthält nunmehr
den privaten Schlüssel im Feld Key:, aus dem er leicht extrahiert
werden kann:
...
Key: ganzvielunleserlicherbase64kram==
...
Dieser Schlüssel wird als beiden Seiten bekanntes Geheimnis genutzt.
Konfiguration von BIND
Die Konfiguration von BIND ist einfacher, als das 224 Seiten starke und typografisch monströse (Zeilenlängen?!) Benutzerhandbuch vermuten lässt. Ich gehe hier daher davon aus, dass die grundlegende Konfiguration dem Leser bekannt ist und hebe nur diejenigen Stellen hervor, die im Rahmen der Einrichtung eines Dienstes für dynamisches DNS besonderer Würdigung bedürfen.
Die für dynamisches DNS relevante Dokumentation befindet sich in
Abschnitt 4.2 des Benutzerhandbuchs für Version 9.10 von BIND. Die
Datei /etc/named.conf (unter Debian /etc/bind/named.conf) wird um
folgenden Inhalt ergänzt:
key dynamic.example.com. {
algorithm "HMAC-SHA256";
secret: "ganzvielunleserlicherbase64kram==";
};
zone dynamic.example.com. {
type master;
file "dynamic.example.com.zone";
allow-update { key dynamic.example.com.; };
};
Damit wird BIND zunächst ein neuer kryptographischer Schlüssel
hinzugefügt (key), bei dem als Algorithmus anzugeben ist, was zur
Erzeugung an dnssec-keygen übergeben wurde. secret ist der oben
erwähnte Inhalt des Feldes Key: aus der erzeugten
Schlüsseldatei. Danach folgt die Zonenkonfiguration, die BIND über die
neue DNS-Zone unterrichtet und es dem Inhaber des Schlüssels
ermöglicht, den DNS-Befehl UPDATE auszuführen. Bei allen Namen ist
darauf zu achten, dass sie einschließlich dem finalen Punkt mit dem
Namen übereinstimmen, der dnssec-keygen übergeben wurde.
Schließlich ist noch eine Zonendatei für die neue Zone anzulegen, etwa
/var/named/dynamic.example.com.zone:
$ORIGIN .
$TTL 200
dynamic.example.com IN SOA ns.example.com john.example.org. (
1
500
500
86400
500
)
NS ns.example.com.
A 1.2.3.4
Die Zeitintervalle mag jeder nach seinem Geschmack bemessen, aber für dynamisches DNS sind kurze Intervalle empfehlenswert, da sich ja die dynamische IP jederzeit ändern kann und diese Änderung möglichst schnell im DNS propagieren sollte. Die IP-Adresse für den A-Record kann hier noch beliebig sein; sie wird ja später eh durch das dynamische Update geändert.
Ein besondere Hinweis noch. Diese Zonendatei darf, nachdem sie einmal
angelegt wurde, nicht mehr editiert werden. BIND erstellt automatisch
eine Datei mit der Endung .jnl im selben Verzeichnis wie die
Zonendatei (Schreibzugriff auf Verzeichnis erforderlich!), in welche
die Änderungen aufgenommen werden. Wenn Korrekturen an der Zonendatei
vorgenommen werden sollen, ist es äußerst ratsam, BIND vorher zu
stoppen, damit der Inhalt der .jnl-Datei in die Zonendatei
übernommen wird. BIND loggt Fehlermeldungen und verweigert die
Auslieferung der Zone, wenn es feststellt, dass die Zonendatei nicht
zur .jnl-Datei passt.
Neustart von BIND nicht vergessen.
Automatisches Aktualisieren des A-Records
Der erzeugte Schlüssel gewährt Zugriff auf die Konfiguration der
gesamten Zone dynamic.example.com, effektiv benutzt wird er aber
nur, um einen einzelnen A-Record für diese Domain zu setzen. Dazu
dient das Tool nsupdate, das ebenfalls Teil von BIND ist. Ein Aufruf
sieht so aus:
$ nsupdate -k Kdynamic.example.com.+123+45678.private <<EOF
server 10.10.10.1
update delete dynamic.example.com A
update add dynamic.example.com 200 A 1.2.3.4
send
EOF
Die Datei Kdynamic.example.com.+123+45678 ist jene, die weiter oben
bereits erzeugt wurde; sie enthält das shared secret, das zu
denjenigen auf dem DNS-Server passt und den Zugriff auf die
Konfiguration gewährt. Die auf die Standardeingabe von nsupdate
geschriebenen Befehle bewirken folgendes:
-
Verbinde mit dem DNS-Server 10.10.10.1. Die IP ist beispielhaft; es muss sich um die IP des DNS-Servers handeln, auf dem der BIND läuft, der für die Zone
dynamic.example.comzuständig ist. Wer aufgepasst hat, stellt fest, dass dies logischerweise der Server sein muss, der im dazugehörigen NS-Record angegeben ist. Um Problemen bei der DNS-Auflösung zuvorzukommen, kann man auch gleich die IP angeben, der Zielserver muss ja eh eine feste Adresse haben. -
Entferne den bisherigen A-Record für
dynamic.example.com. Sonst werden immer mehr A-Records angesammelt, was nicht Ziel der Übung ist. -
Erstelle einen neuen A-Record für
dynamic.example.commit Ziel 1.2.3.4. Diese IP-Adresse muss natürlich für jeden Aufruf vonnsupdateermittelt werden.
Mit diesen Informationen lässt sich leicht ein Shellskript basteln,
das den A-Record für dynamic.example.com aktuell hält. Die aktuelle
eigene IP-Adresse kann man programmatisch etwa mithilfe des Befehls
$ curl http://ifconfig.me/ip
herausfinden, oder man schreibt einen entsprechenden eigenen Dienst auf dem öffentlich erreichbaren Webserver.
Ende
Der Artikel gab eine Übersicht darüber, wie man sein eigenes
dynamisches DNS betreibt. Neben den bereits erwähnten Quellen sei noch
dieser Blogpost erwähnt, der insbesondere die Nutzung von
nsupdate erklärt, die im BIND-Benutzerhandbuch doch irgendwie zu
kurz kommt.
Valete.