DynDNS für PowerDNS

Durch meinen Umzug habe ich wieder das gute alte Problem: einen Telekom Anschluss mit einer dynamischen IP. Auf die Hosts dahinter würde gerne von überall unterwegs mittels VPN/IPSec zugreifen. Problem ist natürlich die eventuell wechselnde IP des Anschlusses selbst.
Stichwort DDNS. Lange Zeit hatte ich das mit no-ip.com realisiert. Da ich für linux-dev.de mittlerweile aber sowieso eigene DNS-Server betreibe, kann ich nun mit „hauseigenen“ Mitteln lösen.

Anbei ein kleines PHP-Script mit dem ich mir meinen eigenen kleinen DynDNS-Service auf PowerDNS-Basis hoste. Ratsam ist natürlich TTL für den betreffenden Record extrem niedrig zu setzen.

<?php
/**
 * DynDNS-Service für PowerDNS
  *
 * @author Simon "cmon2k" Lauger <simon@lauger.name
 * @date   06.09.2012
 */


$dsn     = 'mysql:dbname=pdns;host=127.0.0.1'; // Datenbank DSN
$user    = 'pdns'; // Name der Datenbank
$pass    = 'password'; // Datenbank Passwort

// Auth-String der als GET-Parameter übermittelt werden muss
$auth    = 'hiddenstring'; 

// Für alle im Array enthaltenen Records dürfen Updates gefahren werden
$allowed = array('somehost.linux-dev.de'); 

$domain = (isset($_GET['domain'])) ? $_GET['domain'] : null;
$ip     = (isset($_GET['ipaddr'])) ? $_GET['ipaddr'] : null;

if ((empty($domain) || is_null($domain)) || (empty($ip) || is_null($ip))) {
        die('missing parameter');
        exit;
}

if (!in_array($domain, $allowed)) {
        die('forbidden domain name');
        exit;
}

if (!isset($_GET['passwd']) || $_GET['passwd'] != $auth) {
        die('authentification failed');
        exit;
}

try {
    $dbh = new PDO($dsn, $user, $pass);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

$check = $dbh->prepare('SELECT id FROM records WHERE name = :name AND type = :type');
$check->bindParam(':name', $domain);
$check->bindValue(':type', 'A');
$check->execute();
$result = $check->fetch(PDO::FETCH_ASSOC);

if (empty($result)) {
        die('record not found');
        exit;
} else {
        $update = $dbh->prepare('UPDATE records SET content = :content WHERE id = :id LIMIT 1');
        $update->bindParam(':content', $ip);
        $update->bindParam(':id',      $result['id']);
        if ($update->execute()) {
                die('update successful (' . htmlentities($ip, ENT_QUOTES) . ')');
                exit;
        }
        die('update returned false');
        exit;
}

?>

Bleibt noch die Konfiguration des DynDNS-Clients in der Fritzbox (in meinem Fall eine 7390). Diese sieht in meinem Fall so aus:

  • Dynamic-DNS-Anbieter: Benutzerdefiniert
  • Update-URL: http://foo.linux-dev.de/update.php?domain=<domain>&ipaddr=<ipaddr>&passwd=<pass>
  • Domainname: somehost.linux-dev.de
  • Benutzername: beliebig (in diesem Script nicht benutzt)
  • Kennwort: hiddenstring

Und schon funktioniert das ganze – vollkommen unabhängig von Diensten wie DynDNS.com oder No-IP.com.

Einen Kommentar hinterlassen

Dein Kommentar