DynDNS Service – Marke Eigenbau [Update]

Nachdem dyn.com den kostenlosen DynamicDNS-Service quasi eingestellt hat, kann ich momentan mein privates Netz von außen nicht mehr erreichen.

Um das zu ändern sehe ich 2 Möglichkeiten:

  1. Ich ziehe zu einem anderen Dynymic DNS Anbieter um, bspw. noip.com
  2. Ich mache mir mein eigenes DynDNS

Ich habe mich für Variante 2 entschieden. So laufe ich nicht Gefahr in wenigen Monaten schon wieder zu einem anderen Anbieter wechseln zu müssen. Zudem gestaltet sich das ganze recht simpel, da ich schon einen Server betreibe der hierfür verwendet werden kann.

Die Einrichtung eines dynamischen DNS teilt sich grob in die folgenden 4 Schritte:

  1. Subdomain für Dynamic DNS wählen 
  2. DNS Records der Hauptdomain anpassen
  3. eigenen Server als Nameserver konfigurieren
  4. Update-Script für DNS Updates erstellen.

1. Subdomain wählen:

Prinzipiell kann man hier jede beliebige SubDomain wählen. Man benötigt allerdings Zugriff auf die DNS-Zone der zugehörigen Hauptdomain. Für das Beispiel in dieser Anleitung werde ich mit folgenden Annahmen arbeiten:

Domain: domain.tld

SubDomain für DynamicDNS: dns.domain.tld

2. DNS Einträge der Hauptdomain anpassen:

Um unsere gewählte SubDomain (oder weitere SubDomains nach dem Schema host1.dns.domain.tld) als DynDNS-Adressen nutzen zu können, müssen wir dns.domain.tld zu einer neuen DNS-Zone machen. Wir sorgen also dafür, dass die DNS Auflösung für diese (Sub-)Domain (und alle darunter) über einen weiteren Nameserver (DNS-Server) erfolgen soll. Diese Aufgabe übernimmt dann unser eigener Server.

Hierfür ergänzen wir die DNS Zone der Hauptdomain (sollte ähnlich zu folgender sein) um die fett markierten Zeilen:

domain.tld 1800 IN NS   dns1.provider.tld
domain.tld 1800 IN NS   dns2.provider.tld
domain.tld 86400 IN MX 10 mail.domain.tld
domain.tld 86400 IN A   <IP>
mail.domain.tld 86400 IN A   <IP>
*.domain.tld 86400 IN A   <IP>
www.domain.tld 86400 IN A   <IP>
dns.domain.tld  1800  IN  NS    ns1.domain.tld
dns.domain.tld  1800  IN  NS    ns2.domain.tld

So werden DNS Clients angewiesen, für die DNS-Zone dns.domain.tld einen weiteren Nameserver für die IP-Zuordnung anzufragen. Diese Zuordnungen können wir dann Problemlos nach belieben ändern, da wir Zugang zu diesem Server haben.

3. Eigenen Server zum Nameserver für die Zone dns.domain.tld machen

Der vorletzte Schritt besteht darin, den Server hinter domain.tld zum Nameserver für die DNS-Zone dns.domain.tld zu machen. Auf meinem Server läuft für die komplette Verwaltung ISPConfig, sodass ich diesen Schritt per Wizard vornehmen konnte. Der fertige DNS-Zonen-Eintrag, womit man Ihn auch immer herstellt, sieht dann so aus:

dns.domain.tld 1800 IN NS ns1.domain.tld
dns.domain.tld 1800 IN NS ns2.domain.tld
dns.domain.tld 60 IN A <dynamische IP>
*.dns.domain.tld 60 IN A <dynamische IP>

Wichtig sind hierbei die letzten beiden Zeilen. Diese beiden Einträge weisen nun den SubDomains dns.domain.tld und *.dns.domain.tld eine IP zu. Diese IP soll unserer dynamischen IP entsprechen und durch das Script aus Schritt 4 regelmäßig aktualisiert werden. Um diese Aktualisierung vornehmen zu können, ist es wichtig eine möglichst kurze TTL (Time to live) zu wählen, hier 60 sek. Dies ist die Angabe darüber, wann ein Client den Namen dns.domain.tld neu zu einer evtl. geänderten IP auflöst, also die Zeit, wann die SubDomain auf eine neue IP verweist.

4. Updatescript für DNS-Updates erstellen

Als letzter Schritt muss nun noch ein Script erstellt werden, dass die zu verwendende IP-Adresse entgegen nimmt und in unserem DNS-Server einträgt. Das folgende Script funktioniert, falls der DNS-Server von ISPConfig verwltet wird. Wird ein anderes Config-Tool, oder direkt ein DNS Server verwendet, muss das Script entsprechend angepasst werden.

[Update 11.01.2015] – Zonenupdate hinzugefügt, ID’s werden aus DB gelesen.

<?php

require('soap_config.php');

$client = new SoapClient(null,
      array('location'   => $soap_location,
            'uri'        => $soap_uri,
            'trace'      => 1,
            'exceptions' => 1));

$con = mysqli_connect(<HOSTNAME>,<USER>,<PASS>,<DB>);

$url = $_REQUEST['domain'];

// Perform queries 
$sql = "SELECT id FROM dns_rr WHERE name = '$url.' AND type ='A'";
$res = mysqli_fetch_row(mysqli_query($con,$sql));
$id = $res[0];

$sql = "SELECT id FROM dns_rr WHERE name = '*.$url.' AND type ='A'";
$res = mysqli_fetch_row(mysqli_query($con,$sql));
$wild_id = $res[0];

$sql = "SELECT id FROM dns_soa WHERE origin = '$url.'";
$res = mysqli_fetch_row(mysqli_query($con,$sql));
$zone_id = $res[0];

mysqli_close($con);

try {
     
        $session_id = $client->login($_REQUEST['user'],$_REQUEST['pass']);
     
        //* Get the dns record
        $dns_record1 = $client->dns_a_get($session_id, $id);
        $dns_record2 = $client->dns_a_get($session_id, $wild_id);
     
        //* Enter IP
        $dns_record1['data'] = $_REQUEST['ip'];
        $dns_record2['data'] = $_REQUEST['ip'];
        $dns_record1['serial'] = $dns_record1['serial']+1;
        $dns_record2['serial'] = $dns_record2['serial']+1;
        $client->dns_a_update($session_id, null, $id, $dns_record1);
        $client->dns_a_update($session_id, null, $wild_id, $dns_record2);

        $zone = $client->dns_zone_get($session_id, $zone_id);
        $zone['serial'] = $zone['serial'] + 1;
        $client->dns_zone_update($session_id, 0, $zone_id, $zone);
     
        $client->logout($session_id);

} catch (SoapFault $e) {
	echo $client->__getLastResponse();
	die('SOAP Error: '.$e->getMessage());
}

?>

Hinweis: Dieses Script entspricht im Prinzip dem Example Script, dass ISPConfig mitliefert (/remoting_client/examples/dns_a_update.php). Dort findet sich auch die benötigte soap_config.php. Allerdings werden hier die Ids der A-Records und der Zone aus der DB gelesen.

Aufgerufen wird das Script nun über:

http://domain.tld/{PfadZumScript}/update.php?ip={IP}&user={USER}&pass={PASSWORD}&domain={DOMAIN}

IP: Die IP auf die der Eintrag verweisen soll.

USERNAME: Benutzer der berechtigt ist, DNS Einträge zu ändern.

PASSWORD: Das Passwort dieses Benutzers.

ID: Id des zu ändernden DNS-A Eintrags (kann über die ISPConfig Datenbank, Tabelle dns_rr, herausgefunden werden).

So lässt sich das Updatescript leicht, z.B. in Fritz!Box Router eintragen. Diese stellen hierfür die DynDNS-Anbieter Einstellung Benutzerdefiniert bereit. Die URL lautet dann:

http://domain.tld/{PfadZumScript}/update.php?ip=<ipaddr>&user=<username>&pass=<password>&domain=<domain>

markiert , , , , , , ,

22 Gedanken zu „DynDNS Service – Marke Eigenbau [Update]

  1. Peter sagt:

    Super, danke funktioniert.
    Hast Du das ganze nochmal gesondert abgesichert z.B. https?

    • Tim sagt:

      Du meinst sicher für das Updatescript.

      Nein, habe ich nicht. Für meine Zwecke reicht der Schutz über dass Passwort völlig aus, zumal ich ja der einzige bin, der im Falle eines Angriffes nicht mehr auf seinen Server geleitet wird, sondern auf einen anderen.

      Da hinter meinem Anschluss aber keine Sicherheitsrelevanten Dienste zu erreichen sind, deren Daten man durch einen solchen Angriff erlangen könnte, ist das Risiko eher gering.

  2. kay sagt:

    Also das klingt echt interessant. Ich suche gerade input, da auch ich gern von den dyndns Providern wegkommen möchte.
    Denkst du, das ließ sich auch auf einem vserver umsetzen?
    Ich übgerade, was man bei den NameServer des Providers eintragen müsste.
    Hintergrund ist ja dass Anbieter wie Server4you oder auch 1blu begrenzte Optionen für die Nameserver-Einträge zulassen.
    Diese müsste man dann ja auf den eigenen Nameserver des Vserver „biegen“,um dann weitere Einstellungen lokal vorzunehmen.
    Bin da noch nicht ganz schlüssig, wie dass speziell bei de Domains geht, die ja zwei sichere Nameserver verlangen.

    • Tim sagt:

      Hallo,

      prinzipiell funktioniert das natürlich auch auf vServern. Ob virtualisiert oder nciht spielt ja keine Rolle. Bei meinem Anbieter (übrigens auch ein vServer) habe ich vollen Zugriff auf die Nameserver-Zone für meine Domains. Damit lässt sich leicht die entsprechende Subdomain eintragen und auf einen auf dem vServer installierten DNS Dienst verweisen. Ob du entsprechende NS-Einträge

      dns.domain.tld 1800 IN NS ns1.domain.tld und
      dns.domain.tld 1800 IN NS ns2.domain.tld

      vornehmen kannst, weiß ich natürlich nicht. Umbiegen musst/solltest du hier aber ncihts, da deine alten Einstellungen ja alle erhalten bleiben. Die Einträge sind zusätzlich udn verlagern nur die auflösung weiterer „Subdomains“ an einen weiteren Nameserver.

      Die Anforderung 2er sicherer Nameserver ist mir jetzt ehrlich gesagt nicht bekannt, daher kann ich dazu auch nichts sagen.

  3. fireba11 sagt:

    *hüstel* input validieren *hüstel*

    • Tim sagt:

      Hallo,

      selbstverständlich muss der Input validiert werden. Ich wollte nur die allgemeine Funktion verdeutlichen, keine Kopiervorlage zur Verfügung stellen.

      Grüße

  4. Marc Heubes sagt:

    Hallo Tim!

    Vielen Dank für den tollen Einfall.
    Grundsätzlich funktioniert das schon.

    Praktisch habe ich aber ein Problem:
    Die „Serial“ der Zone wird durch das PHP-Skript nicht hochgesetzt. Dadurch funktioniert die Replikation zu meinem zweiten DNS nicht.

    Hast du oder jemand anderes hier dazu einen Einfall?

    Grüße,
    Marc.

    • Tim sagt:

      Hallo,

      leider nein. Ich verwende keine Replikation und mein Script „redet“ ja mit der Verwaltung von ISPConfig. Wie hiernach weiter verfahren wird, weiß ich leider nicht.

      Grüße

      • Marc Heubes sagt:

        Hey Tim,

        eigentlich muss die Serial auch erhöht werden, wenn keine Replikation verwendet wird. Sonst kann man nicht sicher sein, dass sich alle DNS-Server weltweit wirklich immer die neuste Zonen-Information holen.
        Bei Replikation auf einen secondary DNS geht ohne die aktualisiere Serial tatsächlich gar nichts.

        Da ISPCONFIG ein großartiges Projektist, hat Till mir direkt geholfen:
        http://www.howtoforge.de/forum/entwicklerforum-15/dyndns-mit-ispconfig-8089/#post40601

        Im Grunde müssen nur die drei Zeilen:
        $zone = $client->dns_zone_get($session_id, 666);
        $zone[’serial‘] = $zone[’serial‘] + 1;
        $affected_rows = $client->dns_zone_update($session_id, 0, $zone[‚id‘], $zone);

        in dein Skript ergänzt werden, um die Serial zu erhöhen.

        Die 666 muss gegen die ID der Zone aus der MySQL ersetzt werden.
        Rennt 1a.

        Ist damit 100 % konform und klappt auch bei Replikationsszenarien.

        Besten Dank für deinen Einfall – mit der Serial-Ergänzung für mich wirklich die perfekte Lösung!

        Grüße,
        Marc.

  5. Kai sagt:

    Danke Tim für diesen Artikel und Leitfaden.
    Ergänzt mit den 3 Zeilen von Marc fluppt das ganze.

    Ich habe mir noch ein kleines Shellskript gebastelt um jetzt endlich meine verteilten Kiosksysteme mit meinem eigenen Dyndns Dienst zu beliefern.
    *Thumbs up*

  6. Tom sagt:

    Hi Tim,

    ich habe da mal bitte 2 Fragen:

    Wo finde ich die soap_config.php? Hab mich schon wund gesucht
    Muss diese in das Verzeichnis kopiert werden wo die update.php liegt?

    Viele Grüße
    Tom

    • Tim sagt:

      Hallo Tom,

      die soap_config.php ist Teil von ISPConfig 3 (http://www.ispconfig.de/ispconfig-3/). Sie befindet sich bei den Beispielen für User-Scripts unter: remoting_client\examples.

      Entweder du kopierst das File in das gleiche Verzeichnis in das du die update.php legst oder du legst die update.php in das Verzeichnis der soap_config.php. Ich würde Variante 1 bevorzugen. Außerdem könntest du natürlich den Import so anpassen, dass sie aus den examples importiert wird.

      Bitte beachte aber, die update.php funktioniert zwar so wie sie ist, macht aber keinerlei Input Validierung.

      Außerdem musst du in ISPConfig einen Benutzer einrichten, der das Recht hat die DNS Werte zu ändern. Das geht unter: System/Remotebenutzer. Mindestens die Rechte „DNS Zone“ und „DNS a“ müssen für die beiliegende update.php gesetzt sein.

      PS: Sorry, dass es 3 Tage gedauert hat. War im Urlaub…

      Grüße
      Tim

  7. Tom sagt:

    Hi Tim,

    ok nun habe ich auch die soap_config.php gefunden, hatte sie die ganze Zeit in den Installationsdateien auf dem Server gesucht und nicht in der downloadbaren Version. Muss in dieser Datei bzw. in der update.php noch etwas angepasst werden? Vielen Dank noch mal für die Hilfe…ich hoffe der Urlaub war sonnig…

    Viele Grüsse
    Tom

    • Tim sagt:

      Hallo Tom,

      das kann ich dir Auswendig gerade nicht mehr sagen. Warum fragst du denn? Hast du ein spezielles Problem?

      Tim

      • Tom sagt:

        ja, dieses:

        SOAP Error: Could not connect to host

        • Tim sagt:

          Das klingt, als müsstest du die Adresse deines Servers noch eintragen. Wenn du in die soap_confi rein schaust, müsstestvdu das sehen können.

          ISPConfig läuft aber auf deinem Server? Oder?

          Der Artikel oben ist ab Schritt 4 auch nur noch eine grobe Richtlinie und nicht wirklich eine Schritt für Schritt Anleitung.

          Tim

  8. Martin sagt:

    Boah ey. Ich bekome zum verrecken die DNS-Konfig nicht gebacken. (ISP-Config)
    Kannst Du mir nen Tip geben?

  9. Stefan sagt:

    Moin,

    ich hoffe hier gibt es noch aktivität.

    Erstmal vielen Dank für deine Tuto.
    Bei mir klappt es soweit.

    Wenn ich im Browser zb.

    h**p://MYDOMAIN.de/dyn_update.php?ip=8.8.8.8&user=dyndns&pass=PASSWORD&domain=dyn.MYDOMAIN.de

    aufrufe. Habe ich im DNS wunderbar die IP hinterlegt. Das klappt.

    Aber leider nicht in meiner FB. Habe ein 6490 Cable und die sagt mir immer irgendwas mit Benutzername und Kennwort falsch oder Zeitüberschreibung. Zudem habe ich das gefühl, dass mein vServer das nicht mag 😀

    Hast du einen Tipp für mich?

    • Tim sagt:

      Spontan leider nicht, ohne die Fehlermeldung direkt zu sehen.

      Du könntest im Script Logausgaben schreiben, damit du siehst ob die FB alles korrekt übermittelt hat.
      Sind die Variablen in der Url korrekt? Die FB ersetzt folgende Platzhalter:
      <username> – Mit dem Benutzernamen
      <pass> – Mit dem Passwort
      <ipaddr> – Mit der IP-Adresse
      <domain> – Mit der Domain

      Die Spitzen Klammern, müssen ebenfalls angegeben werden. Bsp.:
      http://domain.de/dns/update.php?user=<username>&pass=<pass>&domain=<domain>&ip=<ipaddr>&ver=1

      Tim

      • Stefan sagt:

        Okay. Ich probiere es heute abend nochmal aus.
        Wie schalte ich Logging in dem Script ein?
        Die Fehler kann auch heute Nachmittag liefern.

        PS: Sorry hätte auf Antworten klicken sollen. Kannst den anderen Post löschen.

        • Tim sagt:

          Mein original Script hat keine Möglichkeit Logging „einzuschalten“. Was ich meinte, war: passe es an und baue logging Funktionen ein. Das sollten beides nur Anregungen zur Fehlersuche sein.

          Finden musst du deine Fehler aber leider selbst…

  10. Stefan sagt:

    Okay. Das mit dem Logging bekomme ich nicht hin.
    aktiviert, dyn.MYDOMAIN.de, IPv4-Status: Account temporär deaktiviert, IPv6-Status: unbekannt
    Das ist der Fehler. Vermutlich hängt das mit Kabel Deutschland und IPv6 zusammen…

Schreibe einen Kommentar

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