Dynamisches DNS (DDNS)

Aus CyberWiki
Version vom 3. Februar 2023, 18:54 Uhr von Geli (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Für Zugriffe aus dem externen Internet wird, sofern man über keine statische IP-Adresse verfügt, DDNS verwendet. Für diesen Dienst gibt es verschiedene Anbieter. Ein relativ bekannter Provider ist DtDNS.com (https://dtdns.com), der als zuverlässig gilt und zudem kostenlos ist.

Für die Übertragung der jeweils aktuellen (externen) IP-Adresse kann zwar das Modem entsprechend konfiguriert werden, die Übermittlung funktioniert aber erfahrungsgemäß nicht ausreichend zuverlässig. Man muss diese Aufgabe aber nicht dem Modem überlassen, sondern kann sie auch auf den Server, der von extern angesprochen wird, verlagern.

Dazu verwendet man am einfachsten ein Bash-Skript, welches man periodisch über einen cronjob startet.

Spezifikationen

Die Spezifikationen für Update Clients findet man hier: https://www.dtdns.com/dtsite/updatespec
Beispiele für Clients findet man hier https://www.dtdns.com/dtsite/updateclients
Diese sind aber nicht unmittelbar ohne Modifikationen verwendbar.

Bash Skript

Zuerst wird die eigene IP-Adresse ermittelt - unter Inanspruchnahme externer Dienste. Danach wird die IP-Adresse festgestellt, die der eigenen Domain zugeordnet ist. Falls nslookup nicht installiert ist, muss dnsutils installiert werden.

sudo apt-get update
sudo apt-get install dnsutils

Damit können wir mit unserem Skript beginnen (die Befehle können auch in der Shell eingegeben werden).

#!/bin/bash
IPADDR="$(wget -qO- eth0.me)"
IPADDR="$(wget -qO- ident.me)"
IPADDR="$(wget -qO- icanhazip.com)"
LASTIP=`nslookup mydomain.dtdns.net | grep -A1 mydomain | grep Address | awk '{ print $2 }'`

Die Dienste eth0.me, ident.me und icanhazip.com können so auch in der Adresszeile eines Browsers eingegeben werden. Das fertige Skript sieht dann so aus:

#!/bin/bash
LOG_FILE=/tmp/ddnsupdate.log
RET=1
COUNTER=0
until [ ${RET} -eq 0 ] && [ $COUNTER -lt 5 ]; do 
	RET=0
	exec > >(tee -a ${LOG_FILE})
	exec 2> >(tee -a ${LOG_FILE} >&2)
	IPADDR="$(wget -qO- eth0.me)"
	if [ -z $IPADDR ]; then
		IPADDR="$(wget -qO- ident.me)"
		if [ -z $IPADDR ]; then
			IPADDR="$(wget -qO- icanhazip.com)"
			if [ -z $IPADDR ]; then
				echo -n "`date` - "
				echo "IPADDR is empty!"
				exit -1
			fi
		fi
	fi

	LASTIP=`nslookup arglist.dtdns.net | grep -A1 arglist | grep Address | awk '{ print $2 }'`
	if [ -z $LASTIP ]; then
		echo -n "`date` - "
		echo "LASTIP is empty!"
		exit -1
	fi

	if [ "$IPADDR" != "$LASTIP" ]; then
		echo -e "GET /api/autodns.cfm?id=arglist&pw=password&client=BSD
		HTTP/1.1\nHost: www.dtdns.com\nUser-Agent: bash\n\n" | \
				nc www.dtdns.com 80
		RET=$?
		if [ ${RET} -eq 0 ]; then
			echo -n "`date` - "
			echo "IP change from $LASTIP to $IPADDR"
		else
			sleep 5m
			let COUNTER=COUNTER+1
		fi
	fi
done
# End of ddnsupdate ------------------------------------------------

Damit muss nur noch ein cronjob eingerichtet werden. Wenn ein Updateversuch schiefgeht (RET <> 0), wird 5 Minuten gewartet und der Versuch 5 mal wiederholt (COUNTER von 0 bis 4). D.h. in dieser Ausprägung sollte der cronjob nicht öfter, als alle 30 Minuten starten.