DynDNS Dienst mit Bind9, nsupdate und PHP

fehlt wasgeht sogutsehr guthat geholfen (No Ratings Yet)
Loading ... Loading ...
Werbung




dyndns_mit_bind9

Wer zuhause einen eigenen PC stehen hat, möchte diesen evtl. direkt über einen Domain-Namen erreichbar machen. Bind9 ermöglicht es, innerhalb 60 Sekunden einen neuen Domainnamen mit einer IP in Verbindung zu bringen, wenn sich diese geändert hat. Wie man einen eingenen DynDNS Dienst in PHP mit Bind9 und nsupdate unter Verwendung von DNSSec konfiguriert.

Bind9 auf dem Server im Internet installieren und konfigurieren

Hierzu gibt es bereits eine Anleitung, nach der der DNS Server installiert werden kann. Aber es müssen noch Anpassungen vorgenommen werden.

Das Übermitteln einer neuen IP erfolgt direkt com Client per “nsupdate” und einem Key. Dieser muss zunächst generiert werden. Hierzu ist das Programm “dnssec-keygen” erforderlich.
Es müssen also zunächst die Schlüssel erzeugt werden:

dnssec-keygen -a HMAC-MD5 -b256 -n HOST domain.tld

Dieser Befehl erzeugt nun einen 256 Bit langen Key, was für den privaten Gebrauch durchaus ausreichend ist. Die Erzeugung kann einige Zeit in Anspruch  nehmen.

Die Ausgabe dieses Befehles sind 2 Dateien:
Kdomain.tld.+157+00000.key
Kdomain.tld.+157+00000.private

Diese beiden Dateien stellen die Schlüssel-Dateien dar und müssen in das Bind-Konfigurationsverzeichnis kopiert werden:

# cp K* /etc/bind/

DNSsec auf dem bind9 Server konfigurieren

Zunächst muss der Key in der Bind9 Konfiguration der Domain “domain.tld” zugewiesen werden.
Der dazu benötigte Key befindet sich in der Kdomain.tld.+157+00000.key Datei:

domain.tld. IN KEY 512 3 157 RxBmZ5dD9ohHmxElislyMeI+zru0npfHCePPZGR8CWQ=

in diesem Fall beginnt ist der Key:

RxBmZ5dD9ohHmxElislyMeI+zru0npfHCePPZGR8CWQ=

Dieser muss nun als DNSsec in die Bind9-Konfiguration
/etc/bind/named.conf.local

key domain.tld. {
     algorithm HMAC-MD5;
     secret "RxBmZ5dD9ohHmxElislyMeI+zru0npfHCePPZGR8CWQ=";
};

In der selben Datei muss dann auch definiert werden, dass die Key-Datei benutzt werden soll.

zone "domain.tld" {
type master;
file "/var/cache/bind/domain.tld";
allow-update {
key domain.tld.;
};
};

Somit ist bind9 der Gebrauch von DNSsec für die Zone “domain.tld” konfiguriert worden.

Nun muss der DNS-Server neu gestartet werden und die Logs geprüft werden

# /etc/init.d/bind9 restart

Es sollten keine Fehlermeldungen in den Logs auftreten. Falls doch, könnte der Key defekt sein.

Client-IP per PHP und nsupdate am DNS-Server updaten

Der Client benötigt einen IP-Dienst, der ihm seine aktuelle IP verrät. Hierzu bietet sich jeder Webserver an, der PHP unterstützt, man könnte hier beispielsweise auch den Server im Internet nehmen, auf dem bind9 läuft. Auf einem einfachen Webspace, beispielsweise “ip.domain.tld” muss nur eine Datei liegen:
index.php

<?  echo $_SERVER['REMOTE_ADDR']; ?>

Positiver Nebeneffekt ist, wenn der DNS Update mal aus irgendwelchen Gründen nicht funktioniert, stehen die IPs in den Logs.

Auf den Client-PC muss PHP laufen und ein Script per Cron aufgerufen werden können.

Auf dem Client sollte der DNS Dienst in einem separaten Verzeichnis laufen, beispielsweise /srv/dns.
Hier müssen auch die .key und .private Dateien hinein kopiert werden.

Hier kommt nun auch die Datei ins Spiel, in der steht der “private”-Key

Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: RxBmZ5dD9ohHmxElislyMeI+zru0npfHCePPZGR8CWQ=
Bits: AAA=
Created: 20120322073655
Publish: 20120322073655
Activate: 20120322073655

Der Key lautet hier:

RxBmZ5dD9ohHmxElislyMeI+zru0npfHCePPZGR8CWQ=

und wird für die Variable $secret im PHP Skript weiter unten verwendet.

Danach installieren wir eine PHP Datei, beispielsweise
/srv/dns/DNSupdate.php

<?

$hostname    =    'myHostName';
$pingserver  =    'http://ip.domain.tld/';
$root        =    dirname(__FILE__);
$ttl         =    60;

$key         =    'domain.tld';
$secret      =    'SecretKeyAusK*.private';

$zones        =    array(
   'domain.tld'    =>    array(
     'pc1',
     'pc2',
     'webcam1',
     'webcam2'
)
);

$nameservers    =    array(
'ns1.domain.tld'
);

function getIP($link, $key) {
  $session = curl_init($link);
  curl_setopt($session, CURLOPT_HEADER, false);
  curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($session, CURLOPT_USERAGENT, 'DNS Ping '.$key.'/'.time());
  $response = curl_exec($session);
  curl_close($session);
  return $response;
}

$current_ip = getIP($pingserver, $hostname);

if (file_exists($root."/ip.tmp")) $old_ip = implode("", file($root."/ip.tmp")); else $old_ip = '0';

if ($current_ip != $old_ip) {
  echo "IP Change (old: ".$old_ip." / new: ".$current_ip.")\n";
  $nsupdate = popen("/usr/bin/nsupdate -y ".$key.":".$secret, "w");
  foreach($nameservers as $ns) {
    echo "contact ".$ns." ...\n";
    fwrite($nsupdate, "server ".$ns."\n");
    foreach($zones as $zone => $hosts) {
      echo "set zone ".$zone." ...\n";
      fwrite($nsupdate, "zone ".$zone."\n");
      foreach($hosts as $host) {
        echo "update host ".$host.".".$zone." to ".$current_ip." TTL ".$ttl." ...\n";
        fwrite($nsupdate, "update delete ".$host.".".$zone.". A\n");
        fwrite($nsupdate, "update add ".$host.".".$zone.". 60 A ".$current_ip."\n");
      }
      fwrite($nsupdate, "send\n");
    }
  }
  fwrite($nsupdate, "quit");
  echo "update done.\n";
  pclose($nsupdate);
  $fp = fopen($root."/ip.tmp", "w+");
  fwrite($fp, $current_ip);
  fclose($fp);
}

?>

Diese Datei gibt es auch hier nochmal zum Download.

Folgende Anpassungen müssen noch gemacht werden:

  • $hostname – mit diesem Namen identifiziert sich das Script, steht im Web-Access-Log
  • $pingserver – ist der Server, von dem das Script die IP des Clients beziehen kann
  • $key – ist der Zonen-Name, hier im Beispiel “domain.tld”
  • $secret – ist der Secret Key aus Kdomain.tld.+157+00000.private
  • $zones – ist ein Array mit den Sub-Domains, beispielsweise pc1.domain.tld, pc2.domain.tld usw
  • $nameservers – ist der Name des Master DNS Servers, beispielsweise ns1.domain.tld

Nach Abspeichern des Skriptes kann ein erster Versuch unternommen werden

# php -f DNSupdate.php

Das Skript sollte die aktuelle heimische IP ermitteln und den DNS Server updaten.

Genauer läuft es so ab, dass alte DNS Einträge gelöscht werden (delete) und die neuen (aus dem Array) hinzugefügt werden (add), wobei die TTL (Time to Life) 60 Sekunden beträgt.
Die TTL macht einen DynDNS Server aus, hier muss auf kurze Lebenszeit der IPs gesetzt werden, da sie sich häufiger ändern. So ist eine IP zu einem Domainnamen nur 60 Sekunden im Cache gültig und wird danach erneut vom Server abgefragt.

Es sollte bedacht werden, dass die auch ein erhöhrtes Traffic-Aufkommen nach sich ziehen kann, wenn viel mit Rechnern zuhause gearbeitet wird.

Das Skript legt eine temporäre Datei “ip.tmp” an, in der die aktuelle IP gespeichert wird.
Beim nächsten Aufruf prüft das Skript, ob sich die IP geändert hat und führt erst dann einen nsupdate aus, wenn dies auch der Fall ist. Somit sind unnötige Änderungen am DNS-Server ausgeschlossen.

Als letztes kann das Skript noch per Cron aufgerufen werden

*/5 * * * * /usr/bin/php -f /srv/dns/DNSupdate.php >>/srv/dns/update.log 2>>/srv/dns/update.log

führt das Skript alle 5 Minuten aus.
Bei Notwendigkeit kann dies auch bis zu einer Minute herunter gesetzt werden, so dass auch wirklich alle 60 Sekunden geprüft wird, ob die IP noch stimmt.



Werbung


Hinterlasse eine Antwort

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


*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>