Bastelstunde: Der eigene DynDNS-Dienst

Seit, ich glaube 2007, war ich Nutzer des DynDNS-Dienstes des gleichnamigen Anbieters. Auf die Arbeitsweise von DynDNS will ich hier nicht genauer eingehen, da verweise ich lieber auf den entsprechenden Wikipedia-Eintrag: http://de.wikipedia.org/wiki/Dynamisches_DNS
In Kürze: wie bei statischem DNS wird hier ein Hostname einer IP zugeordnet, nur mit dem Unterschied, dass die IP dynamisch ist und sich jederzeit ändern kann.
Bis vor kurzem musste sich die IP-Adresse zu einem Hostnamen mindestens einmal im Monat ändern, damit der Eintrag aktiv blieb. Seit neustem reicht dies aber nicht mehr: Nun muss man sich mindestens einmal im Monat über die Webseite einloggen, sonst wird der komplette Account gelöscht. Alternativ hat man die Möglichkeit auf “Dyn Pro” umzusteigen, für 10 USD im ersten Jahr, danach 25 USD – für mich also keine wirkliche Option. Also mussten weitere Alternativen her.
Möglichkeit 1: no-ip.com – hier muss im Moment nur die IP mindestens 1x alle 30 Tage aktualisiert werden, aber wer weiß wann man auch hier sich 1x aktive einloggen muss.
Möglichkeit 2: Die Do-It-Yourself Methode. Etwas umständlich, aber dafür hat man den Kram komplett unter der eigenen Kontrolle.
Und um Möglichkeit 2 geht es jetzt hier.
Was man benötigt:
– Linux-Kenntnisse
– einen vServer/root-Server
– eine Domain
– einen Nameserver, dem man neue Tricks beibringen kann ;-)

Grundlage meiner Basteleien war folgende Anleitung, welche ich zum Teil abgewandelt habe: http://andrwe.org/linux/own-ddns.
Umgesetzt habe ich sie unter Debian 7 mit Bind9.
Zuerst habe ich den TSIG-Key über
dnssec-keygen -a hmac-sha256 -b 256 -n HOST dyndns.johnassel.de
generiert und unter /etc/bind abgelegt. Der wichtige Teil liegt in der erzeugten .private Datei: Über den dort hinterlegten Key wird es später möglich sein, die DNS-Einträge zu aktualisieren. Dafür habe ich in /etc/bind/named.conf.default-zones die folgenden beiden Einträge hinzugefügt:

key dyndns.johnassel.de. {
algorithm HMAC-SHA256;
secret "generierterganzgeheimerKey";
//Festlegung des Schlüssel, über welchen man sich authentifiziert um die Einträge für die Subdomain ändern zu können
};
zone "dyndns.johnassel.de" {
type master;
file "/var/cache/bind/zones/johnassel.de.zone"; //Definition der Zonen-Datei
allow-update {
key dyndns.johnassel.de.; //Verweis auf den Key
};
};

Jetzt weiß der Nameserver, dass er für die Zone “dyndns.johnassel.de” zuständig ist.
Damit Hostnamen auch IP-Adressen zugeordnet werden können, muss die oben definierte Zonendatei angelegt werden:

$ORIGIN .
$TTL 300 ; 5 minutes
dyndns.johnassel.de IN SOA ns.johnassel.de. root.johnassel.de. (
2013051307 ; serial
3600 ; refresh (1 hour)
1800 ; retry (30 minutes)
604800 ; expire (1 week)
1800 ; minimum (30 minutes)
)
NS ns.johnassel.de.
$ORIGIN dyndns.johnassel.de.

Da es sich hier um dynamische DNS-Einträge handeln wird, habe ich die TTL-auf 5 Minuten gesetzt. Bei den üblichen 24 Stunden müsste man im schlechtesten Fall einen Tag warten, bis IP-Änderungen der dynamischen Hosts wirksam werden – was doch sehr unpraktisch ist ;-)
Theoretisch wäre es möglich, die Zone-File schon mit Einträgen zu füllen. Allerdings wären diese dann statisch und würden bei einer Änderung der IP-Adresse des DynDNS-Clients ins Leer führen.
Also muss noch etwas Dynamik in die Sache gebracht werden.
Dafür kommt folgendes PHP-Script zum Einsatz:


<?php
$ip = $_SERVER['REMOTE_ADDR'];
shell_exec("/usr/bin/nsupdate -k /etc/bind/Kdyndns.johnassel.de.*.private <<EOF
server localhost
zone dyndns.johnassel.de
update delete home.dyndns.johnassel.de A
update add home.dyndns.johnassel.de 300 A $ip
send
EOF
");
shell_exec("/usr/sbin/rndc reload");
print("updated home.dyndns.johnassel.de to $ip" . PHP_EOL);
?>

Dieses wird irgendwo auf dem Webserver (welcher auf der gleichen Maschine laufen muss, auf welchem der DNS-Server läuft) abgelegt. Wird das Script nun abgerufen, so wird für den Eintrag “home.dyndns.johnassel.de” die aufrufende IP gesetzt. Damit der Vorgang auch automagisch abläuft, habe ich auf meinem Homeserver einen cronjob eingerichtet, welcher das Scipt jede Minute abruft.

*/1 * * * * wget --http-user="home" --http-passwd="geheimsageichnicht" http://url/zum/php/script > /dev/null

Damit nicht jeder die IP-Adresse ändern kann, empfiehlt es sich das Script per .htaccess und .htpasswd zu schützen, optimalerweise über eine SSL-gesicherte Verbindung, da sonst das Passwort im Klartext übertragen wird (unschön, macht man nicht ;-))

Jetzt fehlt nur noch eine Sache: Die Delegation der Namensauflösung der Subdomain auf den gerade konfigurierten DNS-Server.
Dies muss am Nameserver geschehen, der die Domain (in meinem Fall johnassel.de) verwaltet. Über die Einträge
dyndns 300 IN NS ns.johnassel.de.
und
ns A 46.38.242.191
wird die Delegation realisiert.
Anschließend sollten die DynDNS-Clients über ihre Adresse erreichbar sein.
Möchte man weitere Clients hinzufügen, so reicht es das obige PHP-Script zu kopieren und entsprechend anzupassen.
Im Prinzip ganz einfach, oder? ;-)

DD-WRT 19xxx+OpenVPN = Meeeeeeh!

Bis gestern lief DD-WRT auf dem Linksys E2000 noch auf Build 14929. Da diese schon etwas älter war (März 2011 oder so), ging es gestern ans Upgrade auf Version 19519.
Neuere DD-WRT Builds müssen nicht mehr speziell für den E2000 angepasst werden, die neuen -nv60k.bin Versionen funktionieren auch. Allerdings kann nicht einfach auf eine solche Version aktualisiert werden. Hier muss ein Umweg über eine E2000-Mini-Build gegangen werden. Erst dann lässt sich die Firmware auf nv60k flashen. Während frühere Big-Builds (die ich bis jetzt immer installiert hatte) noch gut mit dem E2000 zusammenspielten, sind jetzige Versionen wirklich “Big”, d.h. sie sind zu groß und passen nicht mehr in den Speicher des Routers (8MB) m(
Da für meine Zwecke die OpenVPN Version reicht (Alternativ funktioniert auch “Mega”) und diese klein genug ist, fiel meine Wahl auf diese (dd-wrt.v24-19519_NEWD-2_K2.6_openvpn-nv60k.bin). Nach der Installation musste nur noch die Konfiguration und Start-Scripte wiederhergestellt werden. Zuerst schien auch alles zu funktionieren, bis ich die OpenVPN Verbindung testete. Diese wollte gar nicht erst starten, sondern warf immer wieder Fehler wie “BIO read tls_read_plaintext error: error:1408F119:lib”. Nach kurzer Suche entpuppte sich dies als Bug in der Implementierung der TLS-Verschlüsselung, welcher schon seit einigen Versionen mitgeschleift wurde. Zum Glück gibt es einen Workaround, welcher OpenVPN wieder lauffähig macht. Dazu reichte es, die Verschlüsselungsmethode in der Konfigurationsdatei des Servers mit “tls-cipher DES-CBC3-SHA” festzulegen. Ein Übersicht, welche Algorithmen funktionieren und welche nicht, gibt es hier:
http://svn.dd-wrt.com:8000/ticket/2536#comment:27
Damit konnten auch die Androiden problemlos verbinden.