ffpi-tools/ddns-update

160 lines
4.4 KiB
Bash
Executable File

#!/bin/bash
#
# Dieses Script befindet sich noch in der Entwicklung.
# siehe: https://www.computerclub-pinneberg.de/dyndns
#
# Voraussetzungen:
# - curl
# bei SSL wird ggf. CA-Zertifikat benötigt
# - nsupdate (dnsutils)
#
# DynDNS im Eigenbau
# http://feitel.indeedgeek.de/2012/8/dyndns_selbstgebacken/
#
# Cache analog zu ddclient
# Nach erfolgreichem Update wird mtime gesetzt
# TODO Wenn die Uhrzeiten der Server nicht synchron sind, kann
# das Update fehlschlagen.
# -> Die Fehlercodes des Updates müssen ausgewertet werden und
# zumindest ein Logeintrag geschrieben werden, damit die
# Fehlersituation durch den Admin erkannt wird.
# -> Timeout bei der Abfrage der IP-Adresse
. /etc/dyndns/ddns.conf
is_validip()
{
case "$*" in
""|*[!0-9.]*|*[!0-9]) return 1 ;;
esac
local IFS=. ## local is bash-specific
set -- $*
[ $# -eq 4 ] &&
[ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] &&
# [ ${3:-666} -le 255 ] && [ ${4:-666} -le 254 ]
# Versatel liefert auch Adressen mit .255 am Ende!
[ ${3:-666} -le 255 ] && [ ${4:-666} -le 255 ]
}
update_cache()
{
CACHE[ip]=$IPADDR
CACHE[mtime]=`date +%s`
if [ -t ] ; then
MODDATE=`date -d @${CACHE[mtime]} "+%a %b %d %T %Y"`
echo -e "\nNeuer Cache"
echo -e "-----------"
echo -e "HOST...: ${CACHE[host]}"
echo -e "IP.....: ${CACHE[ip]}"
echo -e "MTIME..: $MODDATE (${CACHE[mtime]})\n"
fi
# Alle Zeilen der alten Datei durchlaufen und nur
# diejenige mit unserem Hostnamen aktualisieren.
# Wenn unser Hostname nicht vorkam, dann eine Zeile
# anhängen
# Das ist noch nicht hübsch, funktioniert aber erstmal
# Besser: Nicht geänderte Werte aus dem alten Cache übernehmen
# Bei Neuanlage: Defaults definieren!
CACHELINE="atime=0,backupmx=0,custom=0,host=${CACHE[host]},ip=${CACHE[ip]},mtime=${CACHE[mtime]},mx=,static=0,status=good,warned-min-error-interval=0,warned-min-interval=0,wildcard=0,wtime=30 ${CACHE[host]}"
CACHEHIT=false
> $CACHEFILE.new
while read -r line
do
if [[ $line == *${CACHE[host]} ]]; then
echo $CACHELINE >> $CACHEFILE.new
CACHEHIT=true
else
echo $line >> $CACHEFILE.new
fi
done < "$CACHEFILE"
if ! $CACHEHIT ; then
echo $CACHELINE >> $CACHEFILE.new
fi
rm $CACHEFILE
mv $CACHEFILE.new $CACHEFILE
}
update_dns()
{
echo -e "
update delete $HOST.$ZONE A
update add $HOST.$ZONE $TIMEOUT A $IPADDR
show
send" | /usr/bin/nsupdate -k $KEYFILE
}
# Wenn keine gültige IP-Adresse gefunden wurde, dann mit Fehler beenden
# TODO
# Exitstatus von curl abfangen und auswerten
# - Wenn Internetverbindung fehlt, kann der Name $MYIPUL nicht aufgelöst werden
# es kommt Exit Code 6
# - Timeouts sing ggf. auch möglich
# - Parameter -m begrenzt die maximale Zeit
IPADDR=`curl -m 10 -s $MYIPURL | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"`
if ! is_validip "$IPADDR"
then
logger -t ddns-update[$$] No valid IP Address found $IPADDR
exit 1
fi
# Sicherstellen, daß die Cache-Datei existiert
if [ ! -f $CACHEFILE ]; then
CACHEDIR=${CACHEFILE%/*}
if [ ! -d $CACHEDIR ]; then
mkdir $CACHEDIR
echo "Created Cache-Dir $CACHEDIR"
fi
touch $CACHEFILE
echo "Created Cachefile ${CACHEFILE##*/}"
fi
# Cache-Datei auswerten
OPTIONS=`grep $HOST.$ZONE $CACHEFILE | cut -d' ' -f1 | tr ',', ' '`
declare -A CACHE
for O in ${OPTIONS[@]}; do
OPT=(${O//=/ })
CACHE[${OPT[0]}]=${OPT[1]}
done
if [[ $OPTIONS ]]; then
if [ -t ] ; then
MODDATE=`date -d @${CACHE[mtime]} "+%a %b %d %T %Y"`
echo -e "\nCache-Inhalt"
echo -e "------------"
echo -e "HOST...: ${CACHE[host]}"
echo -e "IP.....: ${CACHE[ip]}"
echo -e "MTIME..: $MODDATE (${CACHE[mtime]})\n"
fi
else
# Host existiert nicht im Cache, 'host'-Eintrag für
# neuen Datensatz vorbereiten
CACHE[host]=$HOST.$ZONE
fi
# Nur bei Adreßänderung updaten, spätestens jedoch nach einer
# festgelegten Zeit (MAXAGE)
if [[ "$IPADDR" != "${CACHE[ip]}" ]]; then
update_dns
logger -t ddns-update[$$] Dynamic DNS Record updated to $IPADDR
update_cache
else
DIFF=$((`date +%s` - ${CACHE[mtime]}))
if [[ $DIFF -gt $MAXAGE ]]; then
update_dns
logger -t ddns-update[$$] Dynamic DNS Record updated to $IPADDR because of age
update_cache
fi
fi
exit 0