Einführung
Mit Dynamischem DNS (DDNS) kann man DNS Einträge zur Laufzeit verändern. So kann
z. B. ein DHCP Server autoomatisch zu jedem DHCP Client ein DNS Eintrag
erstellen. Ein anderer Anwendungszweck ist das bereitstellen eines DNS-Eintrags
(z. B. A
oder AAAA
Records) für eine sich oft wechselnde IP-Adresse, damit
diese immer unter dem selben Namen erreichbar ist. Bekannte Anbieter solcher
Dynamischen DNS Services sind dyn.com
oder noip.com
. So einen Dienst kann
man aber auch selber betreiben.
Voraussetzungen
Als Voraussetzung für diese Anleitung braucht man einen konfigurierten Bind
Nameserver. In dieser Anleitung ist der DNS-Server zuständig für die Zone
example.org
. Bei mir läuft der Nameserver auf Debian 6.
Keys erstellen
Mit dnssec-keygen
kann man sich einen Schlüssel erstellen, welcher später dazu
dient, sich beim DNS Server zu authentifizieren:
$ /usr/sbin/dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST foobar.example.org
Kfoobar.example.org.+157+12900
Nach dem Generieren der Schlüssel hat man zwei neue Dateien:
$ ls -l *example.org*
-rw------- 1 root root 123 May 22 14:37 Kfoobar.example.org.+157+12900.key
-rw------- 1 root root 229 May 22 14:37 Kfoobar.example.org.+157+12900.private
Der Key ist symmetrisch und daher in beiden Dateien der gleiche. Er ist base64
kodiert und könnte so aussehen:
$ cat Kfoobar.example.org.+157+51053.private
Algorithm: 157 (HMAC-SHA512)
Key: GFzIGlzdCBkZXIgZ2VoZWltZSBTY2hsw7xzc2VsLgpEZW5rc3RlIGljaCBwdWJsaXppZXJlIGRlbiBPcmlnaW5hbGtleSBoaWVyPwpWaWVsIFNwYXNzCg==
Bits: AAA=
Created: 20130522130759
Publish: 20130522130759
Activate: 20130522130759
Nameserver konfigurieren
Der generierte Schlüssel muss dem Nameserver hinterlegt werden. Wir definieren einen neuen Key, welcher in der Datei /etc/bind/named.keys
abgelegt wird:
$ awk '/Key/{ print "key foobar.example.org {\n \
algorithm HMAC-SHA512;\n secret \"", $2, "\";\n};" }' \
Kfoobar.example.org.+157+12900.private | sudo tee -a /etc/bind/named.keys
Diese Datei darf natürlich nur vom User bind
gelesen werden. Zudem benötigt dieser User Schreibberechtigungen auf dem Verzeichnis /etc/bind
:
$ sudo chmod 600 /etc/bind/named.keys
$ sudo chown -R bind.bind /etc/bind
Die Datei /etc/bind/named.keys
sieht dann so aus:
$ sudo cat /etc/bind/named.keys
key foobar.example.org {
algorithm HMAC-SHA512;
secret "GFzIGlzdCBkZXIgZ2VoZWltZSBTY2hsw7xzc2VsLgpEZW5rc3RlIGljaCBwdWJsaXppZXJlIGRlbiBPcmlnaW5hbGtleSBoaWVyPwpWaWVsIFNwYXNzCg==";
};
In dieser Datei können mehrere Keys gespeichert werden.
Damit Bind von den Keys kennt, fügen wir folgende Zeile vor den Zonendefinitionen in der Datei /etc/bind/named.conf.local
ein:
include "/etc/bind/named.keys";
Berechtigungen für A Record
Damit jetzt dieser Key ein A Record verändern darf, fügt man die Option update-policy
in der Zonendefinition ein:
zone "example.org" {
type master;
file "/etc/bind/db.example.org";
update-policy {
grant foobar.example.org name foobar.example.org A;
};
};
Somit darf der Key foobar.example.org
den Eintrag A Record von
foobar.example.org
verändern.
Änderungen übernehmen
Zuletzt startet man den Nameserver neu und prüft das Logfile auf Fehlermeldungen:
$ sudo /etc/init.d/bind9 restart
$ sudo less /var/log/daemon.log
DNS Server dynamisch updaten
Das Keyfile mit der Endung .private
kopiert man auf den Client in z.B. das
/etc
Verzeichnis. Der Key sollte nur für den User lesbar sein, welcher das
Skript ausführt, damit nicht andere User auf dem System die DNS-Einträge ändern
können.
Mit nsupdate
kann man den DNS Server während der Laufzeit verändern. Die
Verbindung zum DNS-Server wird wie folgt hergestellt:
$ nsupdate -k /etc/Kfoobar.example.org.+157+51053.private
So ändert man einen Eintrag:
server ns.example.org
zone example.org
update delete foobar.example.org
update add foobar.example.org 60 A 10.23.5.42
send
Diese Befehle fügt dem Nameserver ns.example.org
in der Zone example.org
einen neuen A Record mit dem Namen foobar.example.org
hinzu. Die TTL ist 60
Minuten (1 Stunde) und die dazugehörige IP Adresse lautet 10.23.5.42
.
Das kann man mit einem Skript automatisieren:
#!/usr/bin/env bash
#
# ddns-updater - Update dynamic dns entries
#
CONF=”${1:-/etc/ddns-updater.conf}”
. $CONF
if [[ -z “$KEYFILE” || -z “$NAMESERVER” || -z “$ZONE” \
|| -z “$HOSTNAME” || -z “$TTL” ]]
then
echo “Error loading configuration file $CONF”
exit 1
fi
IPADDR=”${CUSTOMIP:-$(dig myip.opendns.com @resolver1.opendns.com +short)}”
IPADDROLD=”$(dig $HOSTNAME @$NAMESERVER +short)”
if [[ “$IPADDR” == “$IPADDROLD” ]]
then
exit
fi
(
echo "server $NAMESERVER"
echo "zone $ZONE"
echo "update delete $HOSTNAME"
echo "update add $HOSTNAME $TTL A $IPADDR"
echo "send"
) | nsupdate -v -k $KEYFILE
Die dazugehörige Konfigurationsdatei sieht so aus:
#
# ddns-updater.conf
#
KEYFILE="/etc/Kfoobar.example.org.+157+51053.private"
NAMESERVER="ns.example.org"
ZONE="example.org"
HOSTNAME="foobar.example.org"
TTL="60"
#CUSTOMIP="10.42.23.5"
Zuerst prüft das Skript, ob es mit einer mitgegebenen Konfigurationsdatei
aufgerufen wurde. Sonst wird die Standardkonfiguration aus
/etc/ddns-updater.conf
geladen. Danach wird die öffentliche IP-Adresse von
OpenDNS bezogen ( dig +short myip.opendns.com @resolver1.opendns.com
, thx
@Danilo). Falls sich die IP Adresse geändert hat, wird nsupdate
gestartet und
der A Record aktuallisiert. Dabei werden die in der Sektion Variables
verwendete Angaben verwendet. Um selbst eine IP Adresse zu definieren kann man
diese mit der Option CUSTOMIP
setzen.
Das Skript ist auch in meinem Scripts-Repository auf GitHub zu finden: ddns-updater.
Automatisiert updaten
Die Keys kann man z. B. unter /usr/local/etc
oder direkt unter /etc
speichern und das Skript unter /usr/local/bin
. Danach genügt folgender Crontab
Eintrag, welcher den A Record alle 60 Minuten (immer 5 nach) auf den neusten
Stand bringt:
5 * * * * /usr/local/bin/ddns-updater
Links und weitere Informationen
- Wikipedia: Dynamic DNS: http://en.wikipedia.org/wiki/Dynamic_DNS