Wer im Jahre 2020 einen DynDNS - Anbieter finden möchte, der wird dem Abgrund des Wahnsinns sehr nahe kommen. Entweder wird viel Geld verlangt oder es ist so furchtbar umständlich gemacht, dass selbst die Anmeldung bei einem Anbieter die Lust auf das Thema verlieren lässt.

Aufgrund meiner "kann ja nicht so schwer sein"-Mentalität starte ich mein eigenen DynDNS-Dienst - nur für mich!

*record scratch* *freeze frame* Ihr fragt euch bestimmt, wie ich in dieser Situation gelandet bin. Yup, richtig geraten ich möchte ein VPN im Heimnetzwerk betreiben, sodass ich mich von unterwegs immer ins Heimnetzwerk verbinden kann. Meine IP zu Hause ist nicht statisch und wechselt, daher möchte ich es über einen dynamischen DNS machen.

Was wir brauchen?

  • Eine eigene Domain.
  • Irgendeinen Router, Server, PC, RapsberryPI oder ESP32 der aus dem Heimnetzwerk einen "ping" senden kann.
  • Kleinen virtuellen Server (VPS) mit fester IP.

Das klingt erstmal bisschen over-the-top, daher mal kleine Wirtschaftlichkeitsrechnung, um Gründe für das Projekt zu finden:

Domains gibt es häufig im Angebot bei z.B. INWX für ca. 2,50€ / Jahr oder weniger.
Ein VPS kostet bei z.B. Hetzner oder NetCup ca. 2,50€ / Monat.
Gesamtkosten für den Eigenbetrieb: 12*2,50€+2,50€ = 32.50€/Jahr.
Ein bekannter DynDNS Anbieter verlangt ca. 55$/Jahr = ca. 49,52 Euro/Jahr.
Neben dem Vorteil der vollen Kontrolle habe ich auch noch knapp 17,02€ im Jahr gesparrt.

Nach dem die Frage nach der Wirtschaftlichkeit ausreichend erläutert ist, können wir auch direkt loslegen. Wir basteln einen DynDNS-Server selber!


Die Theorie

Ich habe die Domain redto.dev erworben, welche ich als DynDNS-Adresse verwenden möchte. Sobald irgendwer/irgendwas meine Domain abfragt, soll der dort hinterlegte Nameserver meine IP-Adresse aus dem Heimnetzwerk bekanntgeben.

Dafür muss irgendwas aus meinem Heimnetzwerk dem Server bekanntgeben, welche IP gerade die aktuelle ist und der Server muss dann immer diese IP-Adresse bekannt geben, wenn er angefragt wird. Schwierigkeit also: Einen flexiblen Nameserver, welcher einen DNS-Request(?) verarbeiten kann.


Die Umsetzung

Voraussetzung: Auf meinem Server ist Node.js installiert und ich hab rudimentäre Grundkenntnisse.

Der Domain gebe ich eigene Nameserver, welche auf meinem Server zeigen. Sobald Jemand die Domain abfragt, erhält er eine Antwort von meinem Nameserver.

Zuerst aber erschaffen wir die  Schnittstelle, dass wir die IP aus dem Heimnetzwerk empfangen können.

Wir verwenden das HTTP-Protokoll, da das fast alle Clients unterstützen. Am einfachsten können wir die Umsetzung mit dem NPM-Paket express erreichen.

npm install express

Als nächstes legen wir unser Script an - server.js:

const express = require('express');
const app = express();
const fs = require('fs');

app.get('/update', function (req, res) {
console.log(req.connection.remoteAddress);
if(req.connection){
  let ip = req.connection.remoteAddress.match(/([0-9]+\.?){4}/g)[0];
  fs.writeFileSync(__dirname+"/homeip.txt", ip);
  console.log("Neue IP: "+ip);
}
res.send('OK');
})

app.listen(3000)

Wenn ich die server.js starte (node server.js) und in meinem Browser http://redto.dev:3000/update eintippe, dann sagt mir der Browser "OK" und der Server schreibt meine IP in die homeip.txt-Datei.

Bei mir kommt bei req.connection.remoteAdress die IPV6 Schreibweise raus "::ffff:127.0.0.1" - daher hab ich die den Regex noch gebraucht.

Die erste Hürde ist genommen - die Schnittstelle, um meine aktuelle IP zu speichern. Als nächstes bauen wir den DynDNS-Server ein.

Auch hier greifen wir auf eine fertige Lösung zurück über das NPM-Paket dnsd, welches das Protokoll vom DNS soweit abbildet.

npm install dnsd

Nach der Installation erweitern wir unsere server.js, damit diese auch die Rolle des DNS-Server übernimmt.

const express = require('express');
const app = express();
const fs = require('fs');
var dnsd = require('dnsd');

app.get('/update', function (req, res) {
console.log(req.connection.remoteAddress);
if(req.connection){
  let ip = req.connection.remoteAddress.match(/([0-9]+\.?){4}/g)[0];
  fs.writeFileSync(__dirname+"/homeip.txt", ip);
  console.log("Neue IP: "+ip);
}
res.send('OK');
})

app.listen(3000);
console.log("[✔] Web-Schnittstelle gestartet");

dnsd.createServer(function(req, res) {
        if(req.question[0].name == "home.redto.dev"){
           fs.readFile(__dirname+'/homeip.txt', function(err,data){
              console.log(data.toString());
              res.end(data.toString());
           });
        }else{
           res.end("127.0.0.1"); // fallback gibt 127.0.0.1 zurück
        }
}).listen(53, '<<MeineServerIp>>'); // 53 = Standard Nameserver Port
console.log("[✔] Nameserver-Schnittstelle gestartet");

Das war es schon was wir an Code brauchen, um einen eigenen DynDNS-Server zu betreiben. Rufe ich jetzt home.redto.dev liest der Nameserver nun aus der homeip.txt-Datei meine IP-Adresse und gibt diese als Antwort zurück.

Um die server.js-Datei dauerhaft überwacht laufen zu lassen, empfehle ich pm2: https://www.npmjs.com/package/pm2

Letzter Schritt ist dem Router oder wenn Ihr einen Raspberry laufen habt noch das regelmäßige Update beizubringen.  In meinem Fall nutze ich einfach meinen Speedport Smart 3. Unter Internet -> Dynamisches DNS kann ich folgende Einstellung treffen:

Mein Speedport-Router sorgt jetzt regelmäßig für das Update meiner IP-Adresse in dem er wie oben eingerichtet http://redto.dev:3000/update aufruft und damit die IP erneuert.

Falls ihr einen Raspberry laufen habt oder so reicht auch ein simpler curl Command als cronjob.

curl http://meineIPoderDomain:3000/update

Der Nameserver gibt somit immer meine aktuelle IP aus meinem Heimnetzwerk als home.redto.dev zurück.

Mein VPN-Connect läuft. Viel Spaß beim Nachbauen.

Cheers Jörg