DNS
Aus Freifunk Franken
Synchronisationsscript für DNS-Zones
Dies ist notwendig um die Dezentralität zu wahren.
#!/bin/bash
#Server die abgefragt werden sollen (Alle DNS Peers)
DnsPeers=( 10.50.252.15 10.50.252.39 10.50.252.27 )
#Name der Zone die verteilt werden soll
DomainZone="fff.community"
#Position und Name des Zone Files
OwnZoneFile="/etc/bind/db.fff.community"
#Temporäres Verzeichnis - muss pro Zone exclusiv sein!
TempDir="/tmp/fff-dns"
#Backup Verzeichnis
BackupDir="/home/freifunk/DNS-Backup"
#Wie viele Backups sollen aufgehoben werden? Nur Integer Werte!
BackupsToStore=20
echo $(date) "Script started"
function backup
{
datetime=$(date +"%Y-%m-%d_%H-%M-%S")
mkdir -p $1/$datetime
cp $OwnZoneFile $1/$datetime/.
BackupFiles=( $(ls -t $1) )
if [ -n ${BackupFiles[0]} ] && [ ${#BackupFiles[@]} -gt 20 ]
then
rm -rf $1/${BackupFiles[$BackupsToStore]}
fi
}
function exit_script
{
rm -rf $TempDir
echo $(date) "Script ended"
exit $1
}
mkdir -p $TempDir
cd $TempDir
OwnSerial=$(grep SOA $OwnZoneFile |awk 'NR==1{print $7}')
HighestSerialSoFar=0
for peer in "${DnsPeers[@]}"
do
echo $(date) "process DNS-Peer"
#Zone File von Peering DNS Servern herunterladen
dig @$peer $DomainZone axfr |grep -v ";"> $peer
#Seriennummer des Zone Files einlesen
PeerSerial=$(grep SOA $peer |awk 'NR==1{print $7}')
#Falls keine Seriennummer vorhanden, ist das File invalid oder die Verbindung zum Peer ist nicht in Ordnung
if [ -z $PeerSerial ]
then
rm -f $peer
continue
PeerSerial=1
fi
#Falls eigenes Zone File keine Seriennummer enthält und somit invalid ist, automatisch erstbestes valides nutzen
if [ -z $OwnSerial ]
then
named-checkzone $DomainZone $peer
if [ $? -eq 0 ]
then
cp $peer $OwnZoneFile
fi
exit 0
fi
#Nur die Zone-Files mit dem höchsten Serial behalten - wenn dieser höher ist als der bereits vorhandene
if [ $OwnSerial -ge $PeerSerial ]
then
rm -f $peer
continue
elif [ ${HighestSerialSoFar[0]} -gt $PeerSerial ]
then
rm -f $peer
continue
else
HighestSerialSoFar=( $PeerSerial $peer )
fi
done
#Anzahl der verbliebenen Zone Files ermitteln
PeerZoneFileCount=$(ls -l|wc -l)
#Im Falle von einem Update vorher ein Backup machen
if [ $PeerZoneFileCount -gt 1 ]
then
backup $BackupDir $BackupsToStore
else
exit_script 0
fi
#Falls nur ein Zone File verblieben ist, direkt einspielen und neustarten
if [ $PeerZoneFileCount -eq 2 ]
then
echo $(date) "Check Zonefile1"
named-checkzone $DomainZone ${HighestSerialSoFar[1]}
if [ $? -eq 0 ]
then
echo $(date) "Copy Zonefile1"
cp ${HighestSerialSoFar[1]} $OwnZoneFile
fi
/etc/init.d/bind9 restart
exit_script 0
#Im Fall von mehreren Zone Files, prüfen ob alle identisch sind. Falls nicht Abbruch. Ansonsten einspielen und neustart
else
md5=$(md5sum ${HighestSerialSoFar[1]} |awk '{print $1}')
for ZoneFile in *
do
loopmd5=$(md5sum $ZoneFile |awk '{print $1}')
if [ $md5 != $loopmd5 ]
then
echo $(date) $md5 $loopmd5
exit_script 1
fi
done
echo $(date) "Check Zonefile2"
named-checkzone $DomainZone ${HighestSerialSoFar[1]}
if [ $? -eq 0 ]
then
echo $(date) "Copy Zonefile2"
cp ${HighestSerialSoFar[1]} $OwnZoneFile
fi
/etc/init.d/bind9 restart
exit_script 0
fi