Inkrementelles Backup über SSH mit zwei Skripten

Um ein Backup von einem Server „abzuholen“, eignet sich rsync, das eine genaue Synchronisation ermöglicht. Rsync kann angeleitet werden, inkrementelle Backups mit Hardlinks anzulegen, so dass mit wenig Speicherplatz alle Änderungen über einen festgelegten Zeitraum festzuhalten sind, ähnlich wie bei Apples „Time Machine“

Zur Härtung des externen Servers richte ich ein VPN ein und sperre den SSH Port in der Firewall. Ist das abgeschlossen, lässt sich der Backup Rechner über VPN und SSH mit zwei Zertifikaten passwortfrei verbinden und „nach Hause“ synchronisieren. Die Skripte können per Cron Job aufgerufen und so automatisiert ausgeführt werden.

Das erste Skript als Basis

Zuerst muss eine Basis angelegt werden, auf das das zweite Skript mit Hardlinks aufbaut. Zur Bereinigung wird das Basis-Skript alle paar Wochen einmal ausgeführt:

#!/bin/sh
# SELBSTLAUFCHECK: Wenn das Skript schon läuft, beendet es sich sofort selbst
echo start $$
trap 'echo exit $$' 0
exec 9<"$0"
flock -n 9 || exit 1

#=========================================================
# Eine Benachrichtigungs E-Mail vorbereiten
TIME="$(LC_ALL=en_EN.utf8 date +%Y_%m_%d-%H%M)"
HDDSPACE=$(df -h)
TO='To: root@domain.org'
SUB='Subject: FULL Backup am '
CONT="Content-Type: text/plain; charset="utf-8""
LOG="/root/scripts/log/$TIME-backup.log"
  echo $TO > $LOG
  echo $SUB$DWE >> $LOG
  echo $CONT >> $LOG
  echo -e "\n \n FULL Server Backup am $TIME \n der Wochentag ist $DWE" >> $LOG
  echo -e "\n SERVER HDDs: \n" >> $LOG
  echo "$HDDSPACE" >> $LOG

#=========================================================
# mögliche bestehende Tunnel abschalten
killall openvpn
#=========================================================
# prüfen, ob der Server erreichbar ist:
# das Skript bleibt jetzt so lange in der Schleife,
# bis der Server erreichbar ist

echo "Waiting to launch on 22..."
while ! nc -z 10.11.10.10 22; do
  sleep 0.2 # alle 2/10 Sekunde wird geprüft
done

echo "ssh verbunden - los gehts"
sleep 2
#=========================================================

rsync -azvP --delete --exclude-from=/root/scripts/exlist --rsync-path='rsync' -e 'ssh -i /root/.ssh/SSHCERT' root@10.11.10.10:/ /pfad/zum/back/up/FULL/
killall openvpn 2>/dev/null

exit 0

Zweites Skript für inkrementelles Backup

Das zweite Skript legt bei jedem Start ein Verzeichnis des Wochentags an, dessen Turnus willkürlich gewählt wird. Mit der Option –link-dest=../FULL/ werden Hardlinks angelegt, also nur tatsächlich geänderte Daten auf die Festplatte geschrieben.

#!/bin/sh
# SELBSTLAUFCHECK: Wenn das Skript schon läuft,
# beendet es sich sofort selbst
echo start $$
trap 'echo exit $$' 0
exec 9<"$0"
flock -n 9 || exit 1

#====================================================
# Datums / Wochentags Variablen setzen, um Verzeichnisse 
# für einen 2 Wochen Turnus anzulegen
TWO="$(LC_ALL=en_EN.utf8 date +%a)"
KWO=`date --date=-1week +%V`
# Entfernt führende NULL und setzt richtigen Wert falls KW=0
KWO="${KWO#"${KWO%%[!0]*}"}" && : "${KWO:=0}"
# Anzahl der Wochen -1, die gesichert werden sollen, also hier zwei
let KWR=$KWO%3
DWE=$KWR$TWO

#====================================================
# Mail vorbereiten
TIME="$(LC_ALL=en_EN.utf8 date +%Y_%m_%d-%H%M)"
HDDSPACE=$(df -h)
TO='To: user@domain'
SUB='Subject: inkr. Backup am '
CONT="Content-Type: text/plain; charset="utf-8""
LOG="/root/scripts/log/$TIME-backup.log"
  echo $TO > $LOG
  echo $SUB$DWE >> $LOG
  echo $CONT >> $LOG
  echo -e "\n \n Did inkr. Server Backup on $TIME \n der Wochentag ist $DWE" >> $LOG
  echo -e "\n Server HDDs: \n" >> $LOG
  echo "$HDDSPACE" >> $LOG

#====================================================
# mögliche bestehende Tunnel abschalten
killall openvpn 2>/dev/null

#Tunnel aufbauen
mkdir /run/openvpn-client 2>/dev/null
openvpn --config /etc/openvpn/erstesVPN.conf

#====================================================
# prüfen, ob der Server erreichbar ist:
# das Skript bleibt jetzt so lange in der Schleife,
# bis der Server erreichbar ist
echo "Waiting to launch on 22..."
while ! nc -z 10.11.10.10 22; do
  sleep 0.2
done
echo "launched ssh - los gehts"
sleep 2

#====================================================
rsync -azvP --delete --exclude-from=/root/scripts/exlist --link-dest=../FULL/ --rsync-path='rsync' -e 'ssh -i /root/.ssh/SSHCERT' root@10.11.10.10:/ /pfad/zum/back/up/$DWE/

killall openvpn 2>/dev/null

#====================================================
# Mail schicken
/usr/sbin/sendmail -bm user@domain < $LOG
exit 0

um das Backup wieder zum Server zurück zu kopieren, kann folgender Befehl genutzt werden. Hiermit wird das letzte Backup der Homepage zurück auf den Server synchronisiert – das defekte Verzeichnis sollte vorher gesichert o. umbenannt werden.

rsync -azvP /pfad/zum/back/up/speziell/ --rsync-path='rsync' -e 'ssh -i /root/.ssh/SSHCERT' root@V.P.N.ip:/pfad/wo/auch/immer/speziell/