Skripte/Backup mit RSYNC

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. Ein Terminal öffnen

  2. Einen Editor öffnen

  3. Rechte für Dateien und Ordner ändern

  4. Ein Paket installieren

  5. Ein Programm ohne Menüeintrag starten

  6. Root-Rechte

Inhaltsverzeichnis
    1. Funktion
    2. Pakete
    3. Überprüfen des Mountpoints
    4. Automatisches Löschen alter Backups
    5. Sichern über SSH
    6. Log-Datei per E-Mail versenden
    7. Aktuelle Paketliste erzeugen und sichern...
  1. Das Skript
    1. Beispiel tousbplatte.sh
    2. Beispiel tossh.sh
    3. Beispiel Minimal Variante
  2. Installation und Ausführung
    1. Optionen und Parameter
  3. Einschränkungen
  4. Externes Backup bei FAT-Partitionen
  5. Daten zurücksichern
  6. Links

Neben der üblichen, meist sehr aufwendigen und vor allem viel zu selten durchgeführten manuellen Sicherung auf externen Medien bietet sich eine automatische Lösung mit rsync an. Die Daten können etwa auf eine lokale Festplatte im selben Rechner, aber auch auf extern angeschlossene Festplatten (USB) oder per SSH über das Netzwerk gesichert werden. Das hier vorgestellte Backup-Skript ist automatisierbar und benötigt nur wenig Ausführungszeit, da es nur Änderungen neu sichert.

Eine Alternative zu diesem Skript sind rsnapshot und dirvish. Im Gegensatz zu diesem Skript bieten die genannten Programme eine Vielzahl von weiteren Konfigurationsmöglichkeiten. Die Vorteile dieses Backup-Skripts sind jedoch die Einfachheit und Übersichtlichkeit sowie der Verzicht auf weitere Paketinstallationen.

Funktion

Das Backup-Skript erstellt für die angegebenen Quellenverzeichnisse identische Kopien in einem Datumsordner im Zielverzeichnis. Als Basis für das inkrementelle Sichern wird die vorherige Sicherung automatisch ausgewählt. Bei mehrmaligen Ausführen am selben Tag wird das "Tagesbackup" aktualisiert. Somit bleibt für einen Tag die letzte Sicherung bestehen. Beliebige "Tagesbackups" können anschließend z.B. per TAR auf externen Medien gesichert werden.

Zu den technischen Details: Das Programm 'rsync' nutzt Hardlinks, wodurch der Eindruck entsteht, dass in jedem Tagesordner sämtliche Dateien abgelegt sind. Jedoch wird bei unveränderten Dateien nichts übertragen und auch nichts kopiert. Es wird einfach nur ein weiterer Hardlink auf die bereits gesicherte Datei angelegt. Das ganze wird über die --link-dest-Option von rsync gesteuert.

Pakete

Vom Skript benötigt wird das Paket[4]

Wiki/Vorlagen/Installbutton/button.png mit apturl

Paketliste zum Kopieren:

sudo apt-get install rsync 

sudo aptitude install rsync 

Folgendes Paket kann bei Bedarf installiert werden:

Wiki/Vorlagen/Installbutton/button.png mit apturl

Paketliste zum Kopieren:

sudo apt-get install openssh-server 

sudo aptitude install openssh-server 

Außerdem kann ggf. ein E-Mail-Programm (für die Benachrichtigung über E-Mail) installiert werden.

Überprüfen des Mountpoints

Über den Parameter MOUNTPOINT kann zur Laufzeit des Skripts geprüft werden, ob der Zielordner für die Datensicherung, z.B. eine USB-Platte oder ein NFS-Mount, eingebunden ist. Sollte es nicht eingebunden sein, so wird keine Datensicherung durchgeführt. Diese Überprüfung kann durch das Weglassen der Option übersprungen werden.

Automatisches Löschen alter Backups

Zur Minimierung der archivierten Datenmenge ist mit dem Parameter MONTHROTATE ein Rotieren von Backups möglich. Hierbei werden im Folgemonat alte Versionen ersetzt.

Sichern über SSH

Das Skript ermöglicht auch das Sichern von Daten von einem entfernten System (FROMSSH) bzw. zu einem entfernten Rechner (TOSSH) per SSH. Zur automatischen Sicherung ist der Austausch von SSH-Keys notwendig, da mehrmals SSH-Verbindungen aufgebaut werden.

Log-Datei per E-Mail versenden

Damit das Skript am Ende eine E-Mail mit angehängter Logdatei versendet, kann der Parameter MAILREC mit entsprechender E-Mail-Adresse verwendet werden. Dafür muss ein Mailprogramm installiert sein. Der E-Mail-Versand kann durch Weglassen der Option ausgeschaltet werden. Sollte bei der Erstellung ein Fehler aufgetreten sein, so wird im E-Mail-Betreff der Begriff "Error" aufgeführt.

Aktuelle Paketliste erzeugen und sichern

Die Liste der installierten Pakete wird durch das Setzen der Option PACKAGES der Logdatei und auch der E-Mail vorangestellt. Es wird empfohlen, den Ordner mit der Logdatei (z.B. /root) in den Sicherungsvorgang aufzunehmen. Bei der Option FROMSSH wird keine Paketliste erzeugt.

Das Skript

Einen Texteditor [2] öffnen und folgenden Text hinein kopieren:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/bin/bash
# Simple backup with rsync
# local-mode, tossh-mode, fromssh-mode

SOURCES=(/root /etc /home /boot )
TARGET="/media/backup"

# edit or comment with "#"
#LISTPACKAGES=listdebianpackages        # local-mode and tossh-mode
MONTHROTATE=monthrotate                 # use DD instead of YYMMDD

RSYNCCONF=(--delete)
#MOUNTPOINT="/media/daten"               # check local mountpoint
#MAILREC="user@domain"

#SSHUSER="sshuser"
#FROMSSH="fromssh-server"
#TOSSH="tossh-server"
SSHPORT=22

### do not edit ###

MOUNT="/bin/mount"; FGREP="/bin/fgrep"; SSH="/usr/bin/ssh"
LN="/bin/ln"; ECHO="/bin/echo"; DATE="/bin/date"; RM="/bin/rm"
DPKG="/usr/bin/dpkg"; AWK="/usr/bin/awk"; MAIL="/usr/bin/mail"
CUT="/usr/bin/cut"; TR="/usr/bin/tr"; RSYNC="/usr/bin/rsync"
LAST="last"; INC="--link-dest=$TARGET/$LAST"

LOG=$0.log
$DATE > $LOG

if [ "${TARGET:${#TARGET}-1:1}" != "/" ]; then
  TARGET=$TARGET/
fi

if [ "$LISTPACKAGES" ] && [ -z "$FROMSSH" ]; then
  $ECHO "$DPKG --get-selections | $AWK '!/deinstall|purge|hold/'|$CUT -f1 | $TR '\n' ' '" >> $LOG
  $DPKG --get-selections | $AWK '!/deinstall|purge|hold/'|$CUT -f1 |$TR '\n' ' '  >> $LOG  2>&1 
fi

if [ "$MOUNTPOINT" ]; then
  MOUNTED=$($MOUNT | $FGREP "$MOUNTPOINT");
fi

if [ -z "$MOUNTPOINT" ] || [ "$MOUNTED" ]; then
  if [ -z "$MONTHROTATE" ]; then
    TODAY=$($DATE +%y%m%d)
  else
    TODAY=$($DATE +%d)
  fi

  if [ "$SSHUSER" ] && [ "$SSHPORT" ]; then
    S="$SSH -p $SSHPORT -l $SSHUSER";
  fi

  for SOURCE in "${SOURCES[@]}"
    do
      if [ "$S" ] && [ "$FROMSSH" ] && [ -z "$TOSSH" ]; then
        $ECHO "$RSYNC -e \"$S\" -avR \"$FROMSSH:$SOURCE\" ${RSYNCCONF[@]} $TARGET$TODAY $INC"  >> $LOG 
        $RSYNC -e "$S" -avR "$FROMSSH:\"$SOURCE\"" "${RSYNCCONF[@]}" "$TARGET"$TODAY $INC >> $LOG 2>&1 
        if [ $? -ne 0 ]; then
          ERROR=1
        fi 
      fi 
      if [ "$S" ]  && [ "$TOSSH" ] && [ -z "$FROMSSH" ]; then
        $ECHO "$RSYNC -e \"$S\" -avR \"$SOURCE\" ${RSYNCCONF[@]} \"$TOSSH:$TARGET$TODAY\" $INC " >> $LOG
        $RSYNC -e "$S" -avR "$SOURCE" "${RSYNCCONF[@]}" "$TOSSH:\"$TARGET\"$TODAY" $INC >> $LOG 2>&1 
        if [ $? -ne 0 ]; then
          ERROR=1
        fi 
      fi
      if [ -z "$S" ]; then
        $ECHO "$RSYNC -avR \"$SOURCE\" ${RSYNCCONF[@]} $TARGET$TODAY $INC"  >> $LOG 
        $RSYNC -avR "$SOURCE" "${RSYNCCONF[@]}" "$TARGET"$TODAY $INC  >> $LOG 2>&1 
        if [ $? -ne 0 ]; then
          ERROR=1
        fi 
      fi
  done

  if [ "$S" ] && [ "$TOSSH" ] && [ -z "$FROMSSH" ]; then
    $ECHO "$SSH -p $SSHPORT -l $SSHUSER $TOSSH $LN -nsf $TARGET$TODAY $TARGET$LAST" >> $LOG  
    $SSH -p $SSHPORT -l $SSHUSER $TOSSH "$LN -nsf \"$TARGET\"$TODAY \"$TARGET\"$LAST" >> $LOG 2>&1
    if [ $? -ne 0 ]; then
      ERROR=1
    fi 
  fi 
  if ( [ "$S" ] && [ "$FROMSSH" ] && [ -z "$TOSSH" ] ) || ( [ -z "$S" ] );  then
    $ECHO "$LN -nsf $TARGET$TODAY $TARGET$LAST" >> $LOG
    $LN -nsf "$TARGET"$TODAY "$TARGET"$LAST  >> $LOG 2>&1 
    if [ $? -ne 0 ]; then
      ERROR=1
    fi 
  fi
else
  $ECHO "$MOUNTPOINT not mounted" >> $LOG
  ERROR=1
fi
$DATE >> $LOG
if [ -n "$MAILREC" ]; then
  if [ $ERROR ];then
    $MAIL -s "Error Backup $LOG" $MAILREC < $LOG
  else
    $MAIL -s "Backup $LOG" $MAILREC < $LOG
  fi
fi

Die Datei wird z.B. unter dem Namen /root/backup.sh gesichert. Da die Logdatei unter dem Namen mit selben Anhang und dem Anhang .log (z.B. /root/backup.sh.log) gesichert wird, empfiehlt es sich, eine sprechende Bezeichnung als Programmnamen zu vergeben.

Beispiel tousbplatte.sh

Sichern auf USB-Festplatte mit Überprüfung des "mount point",

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

SOURCES=(/root /etc /home /boot )
TARGET="/media/usb/zielverzeichnis"

# edit or comment with "#"
#LISTPACKAGES=listdebianpackages        # local-mode and tossh-mode
MONTHROTATE=monthrotate                 # use DD instead of YYMMDD

RSYNCCONF=(--delete)
#MOUNTPOINT="/media/daten"               # check local mountpoint
#MAILREC="user@domain"

#SSHUSER="sshuser"
#FROMSSH="fromssh-server"
#TOSSH="tossh-server"
SSHPORT=22

Beispiel tossh.sh

Sichern auf SSH-Server und E-Mail-Benachrichtigung.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

SOURCES=(/root /etc /home /boot )
TARGET="/pfad/auf/ssh-zielserver"

# edit or comment with "#"
LISTPACKAGES=listdebianpackages        # local-mode and tossh-mode
MONTHROTATE=monthrotate                 # use DD instead of YYMMDD

RSYNCCONF=(--delete)
#MOUNTPOINT="/media/daten"               # check local mountpoint
#MAILREC="user@domain"

SSHUSER="root"
#FROMSSH="fromssh-server"
TOSSH="192.168.1.100"
SSHPORT=22

Beispiel Minimal Variante

Wem das obige Beispiel zu überdimensioniert ist, dem wird hier die minimale Basisvariante vorgestellt:

Es soll das gesamte Home-Verzeichnis des Benutzers auf eine externen Festplatte (ext4 oder NTFS - siehe auch Einschraenkungen) gesichert werden. Auf der externen Festplatte wird vom Skript für jedes Sicherungs-Archiv automatisch ein Ordner mit Datum z.B. "2013-03-16" angelegt. Bei unveränderten Dateien sparen Hardlinks in das vorherige Archiv Speicherplatz und Kopierzeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh

quelle=/home/werner/
ziel=/media/backup_platte/
heute=$(date +%Y-%m-%d)

rsync -avR --delete "${quelle}"  "${ziel}${heute}/" --link-dest="${ziel}last/"
ln -nsf "${ziel}${heute}" "${ziel}last"

exit 0

Falls mit NTFS Datenträgern das Problem auftritt, dass immer alles neu kopiert wird und keine Hardlinks angelegt werden, liegt das vermutlich an den simulierten Dateirechten bei NTFS. Hier hilft es, folgende zusätzliche Optionen in der rsync-Zeile anzugeben

rsync ... --no-perms --no-owner --no-group ...

Beachte: Durch die Hardlinks liegen Dateien nur einmal auf dem Ziel-Datenträger. Bei sehr wichtigen Daten, oder auch von Zeit zu Zeit, ist es empfehlenswert, diese mit dem Original bitweise zu vergleichen, zusätzliche rsync Option -c:

rsync ... -c ...

Das ist sehr zeitintensiv, da alle Daten auf dem Ziel gelesen und mit dem Original verglichen werden, stellt aber sicher, dass die gesicherten Daten vollständig lesbar und korrekt sind.

Installation und Ausführung

Das Skript muss ausführbar[3] gemacht werden.

Optionen und Parameter

Das Skript erwartet genau einen Eintrag für das Backup-Ziel TARGET und einen bzw. mehrere Einträge für die Backup-Quellen SOURCES.

RSYNCCONF -Optionen:

Das Backup-Skript nutzt rsync für die Synchronisation der Verzeichnisse und Daten. Über die Variable RSYNCONF kann die Sicherung z.B. eingeschränkt werden.

--delete              gelöschte Dateien werden auch in der Sicherung gelöscht
                      (hat nur Auswirkungen bei mehreren Sicherungsläufen pro Tag)
--exclude=.*          sämtliche Punkt-Dateien und Punkt-Verzeichnisse werden nicht gesichert
--exclude=.mozilla    Anwendungsdaten von Mozilla/Firefox werden nicht gesichert (z.B. Browser-Cache)

In SOURCES TARGET und RSYNCCONF können Pfadangaben mit Leerzeichen genutzt werden. Hierfür sind bei SOURCES und RSYNCCONF die Pfade mit Anführungszeichen zu umschließen.

PACKAGES verwenden, um eine Liste aller installierten Pakete zu sichern. Die Liste kann benutzt werden, wenn man das System neu aufsetzen muss und den alten Zustand wiederherstellen will. Die Paketliste wird der E-Mail-Benachrichtung angehangen. Eine separate Speicherung findet nicht statt.

MAILREC verwenden, um das Logfile an eine E-Mail-Adresse zu versenden. Dafür muss ein E-Mail-Programm installiert sein. Wie bei MOUNTPOINT kann die Option durch Weglassen ausgeschaltet werden.

Soll das Skript automatisiert innerhalb bestimmter Zeitintervalle laufen, kann es z.B. in Cron-Abläufe eingebunden werden.

Hinweis:

Das Skript überprüft nicht, ob im Zielverzeichnis genügend freier Speicher vorhanden ist. Fehler bei den Eingabeparametern fängt das Skript nicht ab. Fehlerhafte Angaben können das System zerstören, da die Aktionen als root ausgeführt werden.

Einschränkungen

Das Skript wurde nur für unten gelisteten Dateisysteme getestet. Ein Einsatz von NTFS oder FAT als Zieldateisystem ist nur eingeschränkt möglich.

Getestete Dateisysteme
FS inkrementell Hinweise
ext2 Ja Praktisch alle UNIX-artigen Dateisysteme unterstützen Hardlinks. Im Zweifel hilft eine kurze Suche nach dem Dateisystem und dem Stichwort "hardlinks". Je nach der Implementation der Hardlinks verbrauchen einige Dateisysteme u.U. mehr Speicherplatz als andere.
ext3 Ja
ext4 Ja
xfs Ja
vzfs/unionfs Ja
HFS+ Ja Bei extern angeschlossenen Festplatten deaktiviert OS X standardmäßig die Benutzerrechteverwaltung, was inkrementelle Backups unmöglich macht. Diese kann man allerdings von Hand wieder aktivieren (sudo chflags nouchg /Volumes/your_disk).
FAT32 Nein Backups sind mit diesem Skript auch auf FAT32-Ziele möglich, jedoch nicht inkrementell.
NTFS (ntfs-3g) Ja NTFS unterstützt seit Windows 2000 Hardlinks und stellt die entspr. Funktionen per API zur Verfügung. Der ntfs-3g-Treiber unterstützt dies seit Jaunty. Startet man das Skript unter Windows aus Cygwin heraus, sind inkrementelle Backups ebenfalls möglich.
NTFS (Windows) Ja

Externes Backup bei FAT-Partitionen

Für eine Datensicherung auf einem externen Medium mit einem abweichenden Dateisystem kann ein beliebiges Tagesarchiv z.B. mit TAR leicht gesichert werden.

tar cvzf /media/extern/080122.tar.gz /media/backup/080122 

Dabei ist aber zu beachten, dass FAT-Dateisysteme nur Dateien bis zu einer Größe von 4 GB erlauben. Ansonsten müssen mehrere TARs erstellt oder ein einzelnes aufgespalten werden.

Daten zurücksichern

Die Daten können einfach mit Betriebssystemmitteln (cp, rsync) bei Bedarf zurückkopiert werden.

Beim monatlichen Rotieren ist das Ermitteln von alten Sicherungen evtl. schwieriger, da als Datum nur der Tag und nicht JJMMTT gewählt wird. Mit dem unten stehenden Befehl erhält man eine Zuordnung des Sicherungsordners (TT) zum wirklichen Sicherungsdatum (JJ-MM-TT). Bitte entsprechend auf das Backup anwenden. Gesucht wird nach dem jeweiligen Namen des Logdateien, hier "backup.sh.log". Der Rechenaufwand ist hierbei relativ hoch.

find . -name "backup.sh.log" |xargs -i ls -l --time-style=full-iso {}  |cut -d" " -f6,9 |sort 

Um alle Pakete zu installieren, sind aus der Logdatei bzw. der E-Mail die Pakete zu extrahieren und zu installieren.