Kategorien
Blog

Einen eigenen DynDNS-Service betreiben

DynDNS ist eine praktische Sache: der heimischen Internetverbindung wird ein Name zugewiesen, und wenn die IP-Adresse wechselt, dann kann der automatisch aktualisiert werden. Die meisten handelsüblichen Router können das — aber nicht allein, sondern es wird immer ein spezieller DNS-Server benötigt.

Da gab es mit dyndns.org lange Zeit einen gut funktionierenden kostenlosen Dienst, aber der nennt sich inzwischen dyn.com und will verhältnismäßig viel Geld haben (es gibt zwar immernoch eine kostenlose Variante, aber die muss regelmäßig per Klick auf bunt blinkende Mails wieder freigeschaltet werden). Der Wechsel zu irgendeinem der Konkurrenten verbessert die Lage mutmaßlich immer nur vorübergehend. Außerdem möchte zumindest ich meine Infrastruktur so viel wie möglich selbst betreiben.

Die Aufgabe ist also, einen Eintrag im DNS zu ändern. Eigentlich gibt es einen Prima Standard um DNS-Zonen zu aktualisieren, nämlich das Dynamic DNS Update Protocol, wie es in RFC 2136 und RFC 2137 beschrieben ist. Das können die aktuellen DNS-Server ohne zusätzliche Software, und es ist auch schön kryptographisch abgesichert, aber keiner der handelsüblichen Router kann das (diesem Muster werden wir später nochmal begegnen).

Da muss es doch was von GNU geben. Und tatsächlich: genau diese Aufgabe übernimmt GnuDIP. Das wird zwar seit mehr als 10 Jahren nicht mehr weiterentwickelt, funktioniert aber stabil (Ok, die Webseite sieht sehr altbacken aus und möchte gern ein Java-Applet zur Bestimmung der IP-Adresse verwenden — und was ich davon halte ist ja bekannt).

Im Folgenden richten wir unter der Beispieldomain steinhobelgruen.de eine dynamische Domain dyn.steinhobelgruen.de ein.

Installation

Als Basis nehmen wir einen Debian GNU/Linux-Server mit bind9 als DNS-Server und MySQL als Datenbakserver und gehen (zumindest für den mittleren Teil) grob nach dieser Anleitung vor. Leider hat Debian das gnudip-Paket irgendwann aus der Distribution entfernt, wir machen also eine richtig klassische /usr/local-Installation.

Wir laden das Paket runter, entpacken es und „installieren“ die Software:

wget http://gnudip2.sourceforge.net/gnudip-www/src/gnudip-2.3.5.tar.gz
tar zxvf gnudip-2.3.5.tar.gz
mv gnudip-2.3.5/gnudip /usr/local

Dann legen wir die Datenbank an, dazu passen wir in der Datei gnudip-2.3.5/gnudip.mysql eventuell noch Datenbankname und Passwort an und rufen dann MySQL auf:

mysql -uroot -p  < gnudip-2.3.5/gnudip.mysql

In der GnuDIP-Konfiguration unter /usr/local/gnudip/etc/gnudip.conf müssen wir dasselbe Datenbankpasswort  konfigurieren.

Die mitgelieferten cgi-Skripten konfigurieren wir auf dem Webserver; dazu fügen wir die folgenden Zeilen in der Konfiguration des Webservers ein (eventuell in einem bestimmten Virtual Host):

[...]
Alias /gnudip/html/ /usr/local/gnudip/html/

<Location /gnudip/html/>
Options Indexes
ReadmeName .README
HeaderName .HEADER
RemoveHandler .pl
RemoveType .pl
AddType text/plain .pl
</Location>
ScriptAlias /gnudip/cgi-bin/ /usr/local/gnudip/cgi-bin/

DNS Server konfigurieren

Erstmal richten wir einen Schlüssel für DNS-Updates ein. Dazu brauchen wir das dnssec-keygen-Tool aus dem Debian-Paket dnsutils.

dnssec-keygen -a hmac-sha512 -b 512 -n HOST gnudip

Der Aufruf erzeugt zwei Dateien, die zum Beispiel Kgnudip.+165+23314.key und Kgnudip.+165+23314.private heißen.

Wenn der DNS-Server eine Domain dynamisch aktualisieren soll, dann braucht er ein Verzeichnis, in dem er Schreibrechte hat. Wir legen also eins an:

mkdir /etc/bind/dyndns
chown bind:bind /etc/bind/dyndns

In das neue Verzeichnis legen wir eine fast leere DNS-Zonendatei dyn.steinhobelgruen.de:

$ORIGIN dyn.steinhobelgruen.de.
$TTL 86400
@ IN SOA nyx.wazong.de. hostmaster (
      0 ; Serial
   3600 ; Refresh
   1800 ; Retry
 604800 ; Expire
  600 ) ; Negative Cache TTL
@ IN NS nyx.wazong.de.
@ IN MX 0 nyx.wazong.de.
@ IN A 188.40.53.18

Die neue Zone deligieren wir in der Zone steinhobelgruen.de an unseren Nameserver:

$ORIGIN steinhobelgruen.de.
[...]
dyn IN NS nyx.wazong.de.

Den vorhin erzeugten Schlüssel aus der …private-Datei kopieren wir folgendermaßen in die named-Konfiguration  aufgenommen (in einer neuen Datei /etc/bind/gnudip.key ) …

key gnudip-key {
 algorithm hmac-sha512;
 // the TSIG key
 secret "u+/X3NGp1aQxvJedO/8j2xHDxtNgBaSOMgAYMo/OtpbUJXh02Fwfi8+u+yNq/zkIp36m2vY85pw8pgKMk5XSAw==";
 };

… und in der /etc/bind/named.conf.local legen wir die dynamische Zone an und erlauben die Aktualisierung mit dem Schlüssel:

[...]
// include definition of GnuDIP update key
 include "/etc/bind/gnudip.key";
// define GnuDIP dynamic DNS zone
 zone "dyn.steinhobelgruen.de" in {
 type master;
 file "/etc/bind/dyndns/dyn.steinhobelgruen.de";
 allow-query { any; };
 update-policy { grant gnudip-key subdomain dyn.steinhobelgruen.de; };
 };

Wenn alles passt können wir Bind neu starten (bzw. die Konfiguration neu laden).

/etc/init.d/bind9 reload

Die Teile Verbinden

Der Private Schlüssel kommt zur GnuDIP-Installation nach /usr/local/gnudip/etc/ und wird in /usr/local/gnudip/etc/gnudip.conf eingetragen:

[...]
nsupdate = -k /usr/local/gnudip/etc/Kgnudip.+165+23314.private
[...]

Nach dieser Einrichtung sollten wir direkt auf dem Webinterface einen Admin-Benutzer und die Domain anlegen. Danach können wir weitere Benutzer anlegen oder sogar Selbstregistrierung einschalten.

GnuDIP Web Interface

Router anbinden

An dieser Stelle ist GnuDIP jetzt zu sicher um praktisch zu sein: es definiert nämlich ein eigenes Protokoll für die Aktualisierung der Einträge über HTTP, in der das Passwort zusammen mit einem Salt und einem Zeitstempel in einem MD5-Hash und base64-codiert übertragen wird. Genau so sollte so etwas eigentlich auch gemacht werden, aber keiner der handelsüblichen Router kann das.

Grrrrr! Was können die denn überhaupt?

Nun ja, das ist unterschiedlich. Da ich so eine gerade hier habe, werden wir als Beispiel eine Fritz!Box anbinden. Die unterstützt als DynDNS-Anbieter „Benutzerdefiniert“ und kann dann eine selbstgewählte Update-URL eintragen. Was sie dabei übertragen kann steht in dieser Dokumentation bei AVM. Also habe ich in GnuDIP eine zusätzliche und vereinfachte Update-URL eingebaut, die dazu passt.

Um die bei Euch zu installieren, müsst Ihr dieses Archiv mit zwei Dateien herunterladen, sie auspacken und zu Eurer GnuDIP-Installation dazu kopieren.

Damit ergibt sich als neue Update-URL:

https://steinhobelgruen.de/gnudip/cgi-bin/simpleupdt.cgi?user=<username>&pass=<pass>&domn=<domain>&addr=<ipaddr>&reqc=0 (und zwar genau so mit allen Platzhaltern). Die restlichen Parameter werden wie gewohnt konfiguriert (Achtung! Die Domain muss mit dem Benutzernamen anfangen!)

Benutzerdefinierter Service

Durch die Änderung werden jetzt Benutzername und Passwort im Klartext über’s Netz geschickt. Das gleiche Problem hat aber auch die Benutzeroberfläche, so dass auf dem Server vielleicht sowieso besser TLS (https) benutzt werden sollte.

Und siehe da: es funktioniert:

dentaku@nyx:~$ host dentaku.dyn.steinhobelgruen.de
dentaku.dyn.steinhobelgruen.de has address 78.42.203.144
dentaku@nyx:~$

(P.S.: gebt Euch keine Mühe, die Beispieldomain gibt es wirklich, aber die Schlüssel hier im Blogbeitrag sind natürlich nicht die echten — ach ja, und alle Domain- und Hostnamen werden bei Euch andere sein, wenn Ihr der Anleitung folgt)