Homeserver: Backupstrategie #2

Im vorigen Beitrag habe ich meine Idee für ein Backup meiner Daten vorgestellt. Im Folgenden möchte ich die Shell-Skripte vorstellen, die die eigentliche Arbeit machen.

Insgesamt nutze ich vier Shell-Skripte:

  1. backup-rsync.sh
  2. backup-rotate-server.sh
  3. backup-rotate-client.sh
  4. backup-now.sh

Skript 1 wird mit der IP-Adresse meines Servers, dem über FreeNAS auf dem Server angelegtem RSync-Modul sowie dem Pfad auf meinem Macbook, der gesichert werden soll, aufgerufen. Die wichtigsten Zeilen in diesem Skript beziehen sich auf den Aufruf von RSync. Ich nutze RSync von den MacPorts. Diese Version ist neuer und soll mehr Features besitzen als die von Apple gelieferte.

$RSYNC -az --numeric-ids --delete --delete-excluded
      	     --exclude-from="$EXCLUDES" $EXTRAOPT	        
      	     $BACKUP_PATH $SERVER::$MODULE

RSync wird mit den obigen Zeilen mit den Optionen az (archive, compress) aufgerufen. Mit diesen Optionen wird RSync angewiesen möglichst alle Dateiattribute, wie Benutzer und Gruppe, sowie Links zu konservieren. Weiterhin soll der zu sichernde Ordner rekursiv verarbeitet und die Daten während der Übertragung komprimiert werden. Außerdem sollen irrelevante Dateien sowie auszuschließende Dateien (delete, delete-excluded) gelöscht werden. Mittels der Option exclude-from kann eine Datei angegeben werden, die eine Liste von Mustern auszuschließender Dateien und Ordnern enthält. So kann beispielsweise die allseits beliebte .DS_STORE Datei umgangen werden, die Mac OS X so gerne anlegt. Schließlich wird mit der Variable BACKUP_PATH das zu sichernde Verzeichnis und mit SERVER:MODULE der RSync-Server sowie das dort angelegte Modul übergeben.

Für meine Uni-Daten habe ich auf meinem Server mit ZFS ein File System angelegt. Das vereinfacht das sichern der Daten mit ZFS Bordmitteln (Stichwort: Snapshots). Skript 2 wird auf dem Server ausgeführt. Zunächst wird geprüft ob der höchste Snapshot existiert. Dazu nutze ich den Befehl zfs list -t snapshot. Falls er vorhanden ist, wird er gelöscht, denn ich möchte nur eine gewisse Anzahl von Backups halten. Das Löschen wird mit dem Befehl zfs destroy eingeleitet.

SNAP_REG="#$FILE_SYSTEM@weekly.3#!d"
CHECK_SNAP=`zfs list -t snapshot | sed -e "$SNAP_REG"`

if [ "$CHECK_SNAP" ] ; then
  zfs destroy $FILE_SYSTEM@weekly.3
fi

Anschließend werden alle anderen Snapshots um eine Nummer „nach oben geschoben“. Dazu werden sie mit dem Befehl zfs rename umbenannt.

for OLD in 2 1 0 ; do
  SNAP_REG="#$FILE_SYSTEM@weekly.$OLD#!d"
  CHECK_SNAP=`zfs list -t snapshot | sed -e "$SNAP_REG"`

  if [ "$CHECK_SNAP" ] ; then
    NEW=$[ $OLD + 1 ]
    zfs rename $FILE_SYSTEM@weekly.$OLD @weekly.$NEW
  fi
done

Schließlich wird ein aktueller Snapshot angelegt:

SNAP_REG="#$FILE_SYSTEM@weekly.0#!d"
CHECK_SNAP=`zfs list -t snapshot | sed -e "$SNAP_REG"`

if [ -z "$CHECK_SNAP" ] ; then
  zfs snapshot $FILE_SYSTEM@weekly.0
fi

Skript 3 dient dazu Skript 2 auf dem Server über SSH aufzurufen. Dazu werden dem Skript der Benutzer zum Einloggen sowie die IP-Adresse des Servers und das zu sichernde ZFS File System übergeben. Der Rest funktioniert wie auf der Konsole:

SSH_CMD="~/script/backup/backup-rotate-server.sh $ZFS_FILE_SYSTEM"

ssh $SSH_USER@$SSH_HOST "$SSH_CMD"

Den Kennern ist sicherlich aufgefallen, dass ich kein Passwort benötige um den Befehl auf dem Server auszuführen. Darauf gehe ich in einem weiteren Artikel ein.

Skript 4 schließlich ist der Einstiegspunkt für das Backup. In diesem Skript wird zunächst mit dem Befehl ping geprüft ob der Server erreichbar ist. Falls nicht wird sofort abgebrochen. Ansonsten werden nacheinander Skript 3 und Skript 1 aufgerufen.

Sicherlich gibt es an einigen Stellen (wie immer) Verbesserungsbedarf. Trotzdem bin ich mit der jetzigen Lösung zufrieden, lasse mich aber gerne belehren. :)
Für diejenigen, die Interesse haben, sind im Anschluss die Skripte verlinkt.