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