Der eigene, selbstgehostete dynamische DNS-Service

Es gibt viele kostenlose dynamische DNS-Dienste im Internet. Seien es DynDNS, No-IP, AnyDNS oder Selfhost. Im Prinzip gewährleisten all jene Dienste eine ähnliche grundlegende Funktion: sie ermöglichen es, dass eine dynamisch vergebene IP-Adresse (wie bei den meisten Internetanschl?ssen die Regel) unter einem fest vergebenen Domainnamen erreichbar ist. Somit ist zum Beispiel einfach möglich, auf Anwendungen, Geräte und Dienste im eigenen privaten Netzwerk zuzugreifen, da unter dem fest vergebenen Domainnamen die jeweils aktuelle öffentliche IP-Adresse des Routers zu finden ist.

Ich möchte gern an dieser Stelle den von mir genutzten und eingerichteten DynDNS-Service vorstellen und eine grobe Anleitung geben, wie man diesen einrichtet und dann verwenden kann. Es wird zudem kein MySQL benötigt. Die folgende Auflistung ist mit Sicherheit nicht vollständig, sollte aber meines Erachtens als Anlaufstelle und Input ausreichen.

Vorbedingungen:

  • es wird ein eigener Root-Server inkl. Zugriff benötigt
  • bind wird als DNS-Server genutzt, die Domains nebst Subdomains werden auf dem Server verwaltet

F?r meinen eigenen DynDNS-Service nutze ich eine Subdomain auf einer meiner Domains. Exemplarisch sei diese Subdomain dyn.example.com genannt. Ich selbst nutze Debian – nur um vorab darzustellen, dass meine Pfade mitunter anders sind, als bei anderen Linux-Distributionen.

Zuerst erstelle ich die initiale Datei f?r die Zone dyn.example.com – die Datei nenne ich dyn.example.com.hosts und lege sie mit folgendem Inhalt unter /var/lib/bind ab.

Die Updates auf die Zone wird mittels nsupdate durch die später genutzte PHP-Webanwendung durchgef?hrt. Damit dies ordentlich gewährleistet werden kann, muss ein DNS-Key erzeugt werden. Mit Hilfe dessen kann das PHP-Skript authorisiert Änderungen an der Zone durchf?hren.

In der Konsole des Root-Servers wird mittels folgendem Kommando ein Key inkl. weitergehender Informationen erzeugt. Dazu wird auch angezeigt, wie und wo man diese Daten hinterlegen muss.

Der Output sieht zum Beispiel wie folgt aus:

Mit dem Editor der Wahl, erstellt man unter /etc/bind eine Datei, in der der Key hinterlegt wird. Im Beispiel nenne ich diese ddns-key.dyn.example.com – dies sieht wie folgt dann aus:

In der Datei named.conf.local wird der Verweis auf die Zone dyn.example.com hinterlegt und zudem, wie diese aktualisiert werden kann.

Man kann gut erkennen, was dieser Eintrag bewirkt. Die am Anfang erstellte Datei dyn.example.com.hosts wird eingebunden. F?r die Zone ist der Root-Server als Master verantwortlich. Änderungen an der Zone werden f?r Einträge von Subdomains mittels des Keys in der von uns erstellten Datei freigegeben.

Damit wäre der erste Teil der Vorbereitung erledigt. Damit man dies nutzen kann, muss noch sichergestellt werden, dass bind selbst auf die von uns unter /var/lib/bind erstellte Datei lesend/schreibend zugreifen kann, denn dort werden dann die Einträge mit den sich jeweils ändernden IP-Adressen aktualisiert.

Als „Frontend“ nutze ich aktuell eine funktionierende Variante, gefunden auf Github – mit leichten Modifikationen (die ich hier im Nachgang noch einbringen möchte). Die ZIP-Datei wird einfach heruntergeladen und am gew?nschten Zielort entpackt. Danach wird mittels Composer installiert:

Im src Verzeichnis wird daraufhin eine index.php Datei erstellt mit folgendem Inhalt:

Dieser Inhalt kann auch in der heruntergeladenen ZIP-Datei unter examples gefunden werden. Als nächstes wird die Konfiguration in der index.php angepasst. Angelehnt an den hier gewählten Dateien, sieht es dann wie folgt aus:

Dem aufmerksamen Leser wird nicht verborgen geblieben sein, dass noch eine Datei benötigt wird, auf die in der index.php verwiesen wird – die ddns-key.dyn.example.com. Man kopiert jetzt einfach die vorher erstellte Datei unter /etc/bind in das Verzeichnis conf.

Fast zum Schluss muss dem Ganzen noch „gesagt“ werden, wer etwas aktualisieren darf und was. Im Verzeichnis conf befinden sich 2 Dateien. Diese beinhalten die jeweiligen Informationen, wer sich anmelden (dyndns.user) und was geändert werden darf (dyndns.hosts). Um Benutzer anzulegen, wird folgender Befehl in der Konsole im Verzeichnis conf eingegeben:

Daraufhin wird das zu verwendende Passwort gefragt und als MD5 Hash analog einer .htpasswd Datei gespeichert. Man kann mehrere User anlegen. In der dyndns.hosts werden die gew?nschten Subdomains f?r die jeweiligen User hinterlegt. Exemplarisch:

Damit wäre das Ganze fast beendet – es fehlt lediglich die Konfiguration des Web-Dienstes. Ich nutze hier Apache. Bei mir läuft dieser auf example.com in der Standardkonfiguration. Einzige Änderung ist, dass der Eintrag DocumentRoot des Apache

sowie der Directory-Eintrag angepasst wird auf das src Verzeichnis gesetzt wird.

Zur Absicherung habe ich noch eine .htaccess-Datei im src-Verzeichnisses erstellt:

Als krönender Abschluss nun noch meine Änderung. Da die erlaubten Logins mittels htpasswd erstellt werden, kommt die PHP-Anwendung leider nicht so recht mit der Überpr?fung klar. Ich habe an zwei Stellen Änderungen vorgenommen, sodass dies dann funktionieren sollte – so zumindest bei mir.

Im Verzeichnis Dyndns befindet sich die Helper.php. In dieser wird folgende Funktion eingef?gt:

In der Users.php wird in der Funktion checkCredentials folgende Zeile ersetzt:

Das wars – somit sollte der eigene, selbstgehostete dynamische DNS-Service laufen. 🙂

Zu guter letzt: wie das Ganze benutzen?

Ich selbst benutze es zum Einen in meiner Fritzbox und auf meinem NAS, um die wechselnde IP zu aktualisieren. Die Update-URL lautet laut Github

Speziell f?r die Fritzbox wird unter Dynamic DNS ein benutzerspezifizierter Dienst ausgewählt. Als Update-URL wird
dyndns-fritzbox

eingegeben. Das <domain> ist bei der Fritzbox ein Platzhalter f?r eines der folgenden Eingabefelder. Unter Domainname wird der selbst vergebene Domainname, der aktualisiert werden soll, hinterlegt. In meinem hier verwendeten Beispiel ist dies meinrouter.dyn.example.com. Im Feld Benutzername wird MyUserName eingetragen und respektive im Feld Passwort das gewählte Passwort.

Danach sollte die Fritzbox selbstständig die IP-Adresse f?r meinrouter.dyn.example.com bei Neuverbindung aktualiseren. 😀

Das könnte Dich auch interessieren...

7 Antworten

  1. Johannes Graute sagt:

    Hi Michael, ich habe mal Versucht deinen dyndns Server nachzubauen, leider scheitert es jedoch an der benutzer und passwortabfrage. Habe alle Pfade und Dateien wie von dir Beschrieben geändert. Er findet auch die dyndns.user Datei, jedoch scheint es Probleme beim Abgleich des Passworthashes zu geben. Es gibt immer ein badauth zurück. Einzige Änderung zu deinem Skript ist die Verwendung eines Ubuntu LTS 12.04 Servers. Irgendwie scheint der MD5 Hash nicht zu stimmen, welcher mit dem htpasswd tool erstellt wird, habe schon verschiedene Funktionen getestet, leider jedoch erfolglos. Hast du vielleicht eine Lösung parat? Finde deine dyndns Methode eigentlich sehr attraktiv. Vielen Dank

  2. FireFox sagt:

    @Johannes: schau bitte mal, ob der Hash richtig erzeugt wurde in der dyndns.user. Der Anfang sollte ungefähr so aussehen:

    username:$apr1$xxxxxxx$yyyyyyyyy

    Im Prinzip wird lediglich das eingegebene Passwort gehasht und dann mit dem jeweiligen Eintrag in der dyndns.user abgeglichen. Wenn, dann denke ich, dass das Problem beim Erstellen des Hashes mittels htpasswd liegt.

  3. Johannes sagt:

    hmm habe ich gerade nochmal überprüft…
    meine Datei sieht quasi mit Hash so aus:
    ……raute:$apr1$cZA0chT3$Ovv ……
    im Logfile wird auch der user korrekt erkannt, jedoch mit Dyndns: Wrong password for user: zurückgegeben. Ich musste die Pfade umbiegen, da auf meinem Webserver noch eine Webseite läuft. daher habe ich ein Unterverzeichnis mit dem namen ddns angelegt. Da der Username richtig erkannt wird vermute ich das es nicht an den Pfaden liegt. habe in allen php Dateien die Pfade bereits korrigiert. Eine Möglichkeit sehe ich vielleicht an der Helper.php. wo wird da die Funktion eingefügt?
    bei mir sieht es so aus:

    <?php

    namespace Dyndns;

    /**
    * Helper functions.
    */
    class Helper
    {
    /**
    * Check valid IP address
    *
    * @param string IP address
    * @return boolean True if IP is valid
    */
    public static function crypt_apr1_md5($plainpasswd, $salt = '' )
    {
    $translateTo = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    if ( $salt == '' ) { $salt = substr(str_shuffle($translateTo), 0, 8); }
    $tmp = '';
    $len = strlen($plainpasswd);
    $text = $plainpasswd.'$apr1$'.$salt;
    .
    .
    .oder ist es besser das Skript woanders einzufügen? Vielen Dank schon mal für die Hilfe…

  4. FireFox sagt:

    Also ich hab die Funktion public static function crypt_apr1_md5($plainpasswd, $salt = “ ) in der Helper.php zu liegen. In der Users.php sieht die checkCredentials wie folgt aus, denn sonst wird die neue Funktion in Helpers.php nicht aufgerufen korrekt (bzw. nicht):

    public function checkCredentials($user, $password)
    {
    $lines = @file($this->userFile);

    if (is_array($lines)) {
    foreach ($lines as $line) {
    if (preg_match(„/^(.*?):(.*)/“, $line, $matches)) {
    if (strtolower($matches[1]) == strtolower($user)) {
    $salt = substr($matches[2], 6, 8);
    if (Helper::crypt_apr1_md5($password,$salt) === $matches[2]) {
    $this->debug(‚Login successful for user ‚ . $user);
    return true;
    } else {
    $this->debug(‚Wrong password for user: ‚ . $user);
    return false;
    }
    }
    }
    }
    } else {
    $this->debug(‚Empty user file: „‚ . $this->userFile . ‚“‚);
    }

    $this->debug(‚Unknown user: ‚ . $user);
    return false;
    }

  5. Johannes sagt:

    Hallo Firefox, habe jetzt mal testweise deine erweiterungen weg gelassen und die passwortdatenbank mittels ‚htpasswd -d ‚ erstellt und damit die normale cryptdateiversion. Unter Ubuntu 12.04 klappt es damit einwandfrei, gut die Passwörter sind nicht zu stark verschlüsselt aber es läuft. Wäre ja mal interessant herauszufinden in wieweit sich debian und ubuntu doch voneinander diesbezüglich unterscheiden, denn die htpasswd sieht bei mir genauso aus wie du beschrieben hast, nur dass er nie das passwort akzeptiert. als tipp nebenbei auch wenn nur eine kleinigkeit:
    nsupdate legt im Verzeichnis der Zonendatei noch eine jtn datei an, diese ist per standart nur von bind beschreibbar. (trotz zuvor chown -R auf das verzeichnis) kam bei mir immer ein Access denied fehlermeldung beim Versuch des Updates. Nachdemi ich dieser datei dann auch die userrechte auf bind:www-data und die dateirechte auf 664 per chmod gesetzt habe läuft es jetzt. Vielen Dank für die schöne Anleitung…

  6. Daniel sagt:

    Hi,
    toller Artikel. Was mir nicht ganz klar ist: Kann ich denn den nach diesem Tutorial gebauten DynDNS auch für mehrere Domains verwenden? Könnte ich also beliebige Domains und Subdomains nehmen, so dass ich auch für Freunde eine eigene DynDNS Domain (nicht nur Subdomain) einrichten kann ?

    Weiter frage ich mich, ob man nicht ISPConfig3 oder ein ähnliches CP für das Anlegen der Domains/Subdomains verwenden kann. Was meinst du dazu ? Macht das einem die Arbeit nicht einfacher die Domains zu verwalten? Oder würde das nicht funktionieren?

    Vielen Dank bereits im Vorfeld für die Antwort
    Danny

    • FireFox sagt:

      Hallo Daniel,

      danke für das Feedback. Ich versuche mal deine Fragen zu beantworten.
      Ich selbst nutze eine einzige „Instanz“ und somit lediglich auf einer Domain. ABER (!!!) was hindert dich zB. daran eine Subdomain einer anderen auf die DDNS-Adresse zu lenken? 🙂

      Beispiel:
      DDNS wäre zu-hause.dyn.example.net
      Du möchtest gern eine Subdomain einer anderen Domain auf den eigenen DDNS Eintrag lenken, so brauchst du lediglich einen CNAME Eintrag anlegen. Angenommen, die andere Domain heißt domain.net und die Subdomain, die auf den DDNS verweisen soll lautet home.domain.net, dann wäre der DNS Eintrag in der Domain domain.net wie folgt:
      home.domain.net. 1200s IN CNAME zu-hause.dyn.example.net.

      Für die DDNS Domain kannst du mMn kein ISPConfig & Co nutzen – aber für die anderen Domains, die dann auf die DDNS Einträge verweisen 🙂

      Hoffe, ich konnte helfen.

Schreibe einen Kommentar zu FireFox Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.