DNS-Server · 8 min read · Oct 02, 2025

So setzen Sie einen dynamischen DNS-Server mit Docker auf Debian 10 ein

Dynamisches DNS ist ein Netzwerkdienst zum Zuordnen von Domainnamen zu dynamischen (temporären, häufig wechselnden) IP-Adressen. Es wird verwendet, um auf Computer zuzugreifen, die keine statische IP-Adresse haben, wie z. B. solche in SOHO (Small Office/Home Office) Netzwerken, und wird häufig in Kombination mit Portweiterleitung verwendet, um auf Systeme zuzugreifen, die hinter NAT-Firewalls stehen. Dieser Artikel führt Sie durch die vollständige Einrichtung eines dynamischen DNS-Servers in einem Docker-Container auf einem Debian 10-System, einschließlich der Einrichtung der erforderlichen DNS-Einträge, der Platzierung der Verwaltungs-API hinter einem Nginx HTTPS-Reverse-Proxy und der Automatisierung der clientseitigen DNS-Eintrag-Aktualisierungen.

Anforderungen

  • Ein einzelner Debian 10-Server, optional mit IPv6-Konnektivität. (192.0.2.2 und 2001:0db8::0db9 werden als Platzhalter für die IPv4- bzw. IPv6-Adresse des Servers verwendet.)
  • Zugriff auf den Root-Benutzer oder einen Benutzer mit Sudo-Rechten.
  • Die Ports tcp/53 und udp/53 müssen auf dem Host verfügbar sein.
  • Ein registrierter Domainname und Zugriff auf dessen Nameserver/Zonendatei. Erstellen Sie DNS-Einträge für diese Domain, wie im nächsten Abschnitt gezeigt.
  • Die Umgebungsvariable $EDITOR muss gesetzt sein.
  • Optional: Ein beliebiges Linux/Unix-Client-System zur Einrichtung automatischer DNS-Eintrag-Aktualisierungen.

Erstellen von DNS-Einträgen.

Sie müssen mindestens 2 DNS-Einträge erstellen, damit Ihr dynamischer DNS-Server funktioniert. Wählen Sie zunächst eine Subdomain wie ns1.your_domain, die auf die IPv4-Adresse Ihres Servers verweist. Wählen Sie zweitens eine Subdomain wie ddns.your_domain, die an ns1.your_domain delegiert wird.

Ihr dynamischer DNS-Server verwaltet alle Einträge unter ddns.your_domain. Der dritte Eintrag vom Typ AAAA ist optional. Die entsprechenden Einträge sehen wie folgt aus:

s1.your_domain A 192.0.2.2
ddns.your_domain NS ns1.your_domain
s1.your_domain AAAA 2001:0db8::0db9 (optional)

Beispiel für DNS-Einträge

Sie sollten diese Einträge im Kontrollpanel Ihres Domain-Registrars erstellen. Bitte beachten Sie, dass es bis zu 24 Stunden dauern kann, bis diese Einträge gut propagiert werden, aber in der Regel dauert es nur Minuten.

Installation

Wenn Sie nicht den Root-Benutzer verwenden, empfehlen wir, eine temporäre Root-Shell zu starten, da die meisten in diesem Leitfaden gezeigten Befehle erhöhte Berechtigungen erfordern. Um eine Root-Shell zu starten, verwenden Sie einen der folgenden Befehle:

sudo su - root
sudo -s

Schritt 1: Aktualisieren und Installieren von Abhängigkeiten.

Es ist immer eine gute Praxis, Ihr System zuerst zu aktualisieren:

apt update
apt upgrade -y
reboot

Nach dem Neustart installieren Sie die Softwarepakete, die für diese Einrichtung erforderlich sind:

  • certbot wird verwendet, um SSL/TLS-Zertifikate zu erhalten.
  • make wird benötigt, um das Docker-Image zu erstellen, in dem der DDNS-Server ausgeführt wird.
  • apt-transport-https, ca-certificates, curl, gnupg2 und software-properties-common sind erforderlich, um das Docker-Repository und den entsprechenden GPG-Schlüssel zu installieren.
  • dnsutils stellt dig bereit, das für Tests verwendet wird.
apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

Schritt 2: Installieren von Docker CE.

Fügen Sie den GPG-Schlüssel von Docker hinzu:

curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

Installieren Sie das Docker-Repository:

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"

Aktualisieren Sie den Repository-Cache von Debian und installieren Sie Docker und seine Abhängigkeiten:

apt update
apt install -y docker-ce docker-ce-cli containerd.io

Sobald die Installation abgeschlossen ist, stellen Sie sicher, dass der Docker-Dienst aktiviert und wie folgt ausgeführt wird:

systemctl enable --now docker.service

Schritt 3: Herunterladen und Erstellen von docker-ddns

Unser dynamischer DNS-Server wird von einem Docker-Container betrieben, der Bind als DNS-Server und eine in Go geschriebene Verwaltungs-API verwendet. Zuerst klonen Sie das Github-Repository und erstellen das Container-Image mit den folgenden Befehlen:

git clone https://github.com/dprandzioch/docker-ddns.git
cd docker-ddns
make image

Warten Sie, bis der Prozess abgeschlossen ist, was eine Weile dauern kann, und öffnen Sie dann die Datei envfile mit einem Texteditor:

$EDITOR envfile

Und geben Sie Folgendes ein:

SHARED_SECRET=your_secret   
ZONE=ddns.your_domain   
RECORD_TTL=60

Das gemeinsame Geheimnis ist ein Passwort, das zur Authentifizierung bei der Verwaltungs-API verwendet wird. ZONE gibt an, für welche DNS-Zone Ihr Server verantwortlich ist, und die TTL des Eintrags gibt an, wie lange DNS-Einträge zwischengespeichert werden können. Eine TTL von 60 Sekunden wird für häufig wechselnde dynamische IPs empfohlen.

Falls erforderlich, können Sie mit dem folgenden Befehl eine zufällige 40-Zeichen-Zeichenfolge für das Geheimnis generieren:

cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 40 | head -1

Jetzt können wir den Container erstellen:

docker create -it -p 127.0.0.1:8080:8080 -p 53:53 -p 53:53/udp --env-file envfile -v /mnt/ddns-data:/var/cache/bind --name ddns-server davd/docker-ddns

Dieser Befehl erstellt einen Container mit dem Namen ddns-server aus dem zuvor erstellten Image und mappt die Ports 8080/tcp, 53/tcp und 53/udp vom Host auf den Container. Es wird auch das Verzeichnis /mnt/ddns-data vom Host auf /var/cache/bind im Dateisystem des Containers gemountet. Dies wird verwendet, um DNS-Daten über die Container-Neuerstellung hinweg zu speichern.

Überprüfen Sie, ob der Container mit dem Befehl erstellt wurde:

docker container ls -a

Ein einzelner Eintrag sollte mit dem Namen ddns-server ausgegeben werden.

Schritt 4: Systemd-Dienst (optional)

Dieser Schritt dient einer einfacheren Verwaltung, ist jedoch nicht unbedingt erforderlich. Wenn Sie sich entscheiden, keinen systemd-Dienst zu verwenden, müssen Sie den Container manuell verwalten oder eine andere Verwaltungslösung verwenden. Bitte beachten Sie, dass für größere, komplexere Containerbereitstellungen eine Orchestrierungslösung wie Kubernetes oder Docker Swarm empfohlen wird. In diesem Fall ist ein systemd-Dienst perfekt geeignet, da wir nur einen einzigen Container ausführen.

Um diesen Container als Systemdienst verwalten zu können, werden wir ihn in eine systemd-Einheit einwickeln. Erstellen Sie die Datei /etc/systemd/system/ddns-server-ct.service mit Ihrem Texteditor:

$EDITOR /etc/systemd/system/ddns-server-ct.service

Und fügen Sie Folgendes hinzu:

[Unit]  
Description=DDNS Server Docker Container  
After=docker.service  
Requires=docker.service  
Requires=network.target  
[Service]  
Type=oneshot  
TimeoutStartSec=240  
Restart=no  
RemainAfterExit=yes  
ExecStart=/usr/bin/docker start ddns-server  
ExecStop=/usr/bin/docker stop ddns-server  
[Install]  
WantedBy=multi-user.target

Speichern und beenden Sie, und setzen Sie dann die richtigen Berechtigungen für diese Einheitendatei:

chmod 664 /etc/systemd/system/ddns-server-ct.service

Laden Sie die neue Dienstdatei mit dem folgenden Befehl:

systemctl daemon-reload

Sie sollten jetzt in der Lage sein, diesen Container mit systemctl wie jeden anderen Systemdienst zu starten und zu stoppen.

Wenn Sie möchten, dass der DDNS-Server beim Systemstart automatisch startet, führen Sie Folgendes aus:

systemctl enable ddns-server-ct.service

Schritt 5: Testen Ihres Servers

Bevor Sie mit der Einrichtung fortfahren, testen wir die Verwaltungs-API lokal. Starten Sie den Container:

systemctl start ddns-server-ct.service

Senden Sie eine GET-Anfrage an die API, um einen neuen Eintrag zu erstellen:

HINWEIS: Die API ist derzeit nur lokal (d. h. von localhost) zugänglich.

curl "http://127.0.0.1:8080/update?secret=your_secret&domain=test1&addr=1.1.1.1"

Curl sollte die folgende Antwort zurückgeben:

{"Success":true,"Message":"Updated A record for test1 to IP address 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}

HINWEIS: Die Domain test1 bezieht sich auf test1.ddns.your_domain, da der Server die Zone ddns.your_domain. verwaltet.

Führen Sie eine DNS-Abfrage durch, um zu überprüfen, ob der Eintrag tatsächlich erstellt wurde und um die DNS-Auflösung zu testen:

dig +short -t A test1.ddns.your_domain @127.0.0.1

Die Ausgabe sollte 1.1.1.1 sein.

Schritt 6: Reverse-Proxy

Da die API über HTTP funktioniert, kann Ihr Authentifizierungsgeheimnis potenziell abgehört werden, wann immer Sie eine Anfrage über das Netzwerk senden. Ein Angreifer könnte dann Ihre DNS-Einträge mit Ihrem Geheimnis manipulieren. Wir werden einen Reverse-Proxy mit Nginx einrichten und ihn mit HTTPS sichern. Zuerst erhalten Sie ein SSL-Zertifikat von Let’s Encrypt mit certbot:

certbot certonly --standalone --agree-tos -m [email protected] -d ns1.your_domain

Das Eigentum an Ihrer Domain wird überprüft und ein Zertifikat ausgestellt. Installieren Sie dann Nginx und stellen Sie sicher, dass es aktiviert und ausgeführt wird:

apt install -y nginx systemctl enable --now nginx.service

Deaktivieren Sie dann die Standard-Serverblockdatei, da sie nicht benötigt wird:

unlink /etc/nginx/sites-enabled/default

Wir werden jetzt eine neue Konfigurationsdatei für den Reverse-Proxy erstellen, zum Beispiel:

$EDITOR /etc/nginx/sites-available/ddns-api-proxy.conf

Und fügen Sie Folgendes ein, wobei Sie sicherstellen, dass Sie die IP-Adressen und Domainnamen durch Ihre eigenen ersetzen:

server {  
listen 192.0.2.2:8080;  
server_name ns1.your_domain;  
ssl on;  
ssl_certificate /etc/letsencrypt/live/ns1.your_domain/fullchain.pem;  
ssl_certificate_key /etc/letsencrypt/live/ns1.your_domain/privkey.pem;  
  
location /update {  
proxy_pass http://127.0.0.1:8080;  
}  
location / {  
return 404;  
}  
access_log /var/log/nginx/ddns-api-access.log;  
error_log /var/log/nginx/ddns-api-error.log;  
}

Optional: Wenn Sie möchten, dass die API über IPv6 zugänglich ist, fügen Sie die folgende Zeile nach der vorhandenen Listen-Direktive hinzu:

listen [2001:0db8::0db9]:8080;

Aktivieren Sie diese Konfiguration und wenden Sie die Änderungen an, indem Sie Nginx neu laden:

ln -s /etc/nginx/sites-available/ddns-api-proxy.conf /etc/nginx/sites-enabled/
systemctl reload nginx.service

Die API sollte jetzt über das Internet zugänglich sein und nur HTTPS-Verbindungen akzeptieren. Um dies zu testen, geben Sie den Befehl ein:

curl "https://ns1.your_domain:8080/update?secret=your_secret&domain=test2&addr=1.1.1.2"

Es sollte Folgendes zurückgegeben werden:

{"Success":true,"Message":"Updated A record for test2 to IP address 1.1.1.2","Domain":"test2","Domains":["test2"],"Address":"1.1.1.2","AddrType":"A"}

Schritt 7: Client-Konfiguration

Sie können automatische Eintrag-Aktualisierungen auf jedem Router einrichten, der benutzerdefinierte dynamische DNS-Anbieter unterstützt, wie z. B. Pfsense. Sie können sie auch auf den meisten anderen Geräten in Ihrem Büro- oder Heimnetzwerk einrichten. Um einen Eintrag zu aktualisieren oder zu erstellen, sollte eine GET-Anfrage an den folgenden Endpunkt gesendet werden:

https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address

Sie können auch die Einträge mehrerer Subdomains mit einer einzigen Anfrage aktualisieren. Um beispielsweise Einträge für sub1.ddns.your_domain und sub2.ddns.your_domain mit der IP-Adresse 198.51.100.100 zu erstellen/aktualisieren, senden Sie eine GET-Anfrage an diese URL:

https://ns1.your_domain:8080/update?secret=your_secret&domain=sub1,sub2&addr=198.51.100.100

Der addr-Parameter kann auch eine IPv6-Adresse enthalten, um AAAA-DNS-Einträge zu erstellen/aktualisieren, zum Beispiel:

https://ns1.your_domain:8080/update?secret=your_secret&domain=cheese&addr=2001:0db8:aaaa::

Um diese Aktualisierungen auf einem Linux-Client zu automatisieren, speichern Sie das folgende Bash-Skript als /opt/ddns-update.sh:

#!/bin/bash  
  
while [ -z $CURRENTIP ]
do  
CURRENTIP=`dig -r +short myip.opendns.com @resolver1.opendns.com 2>/dev/null`  
sleep 1  
done  
curl -s "https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=${CURRENTIP}"

Dieses Skript verwendet eine While-Schleife, die um einen Dig-Befehl gewickelt ist, der die öffentliche IP-Adresse des Clients abruft und in einer Variablen speichert. Die Schleife stellt sicher, dass die öffentliche IP korrekt abgerufen wird. Dann wird cURL verwendet, um eine API-Anfrage zu senden, um den DNS-Eintrag mit dieser neu abgerufenen IP zu aktualisieren. Stellen Sie sicher, dass Sie die Werte für your_secret und your_subdomain ersetzen.

Als Nächstes machen Sie dieses Skript ausführbar:

chmod +x /opt/ddns-update.sh

Starten Sie dann den Crontab-Editor:

crontab -e

Fügen Sie die folgende Zeile am Ende Ihres Crontabs hinzu:

*/2 * * * * /opt/ddns-update.sh

Speichern und beenden Sie. Das Skript wird nun alle zwei Minuten ausgeführt und hält Ihren dynamischen DNS-Eintrag mit der neuesten öffentlichen IP-Adresse des Clients auf dem neuesten Stand.

Weiterführende Literatur

  • Dynamisches DNS Wikipedia-Artikel
  • docker-ddns auf Github
Share: X/Twitter LinkedIn

Erhalte neue Beiträge in deinem Posteingang.

Kein Spam. Jederzeit abmelden.