[[Vorlage(Getestet, general)]] {{{#!vorlage Wissen [:Terminal: Ein Terminal öffnen] [:Editor: Einen Editor öffnen] [:Rechte: Rechte für Dateien und Ordner ändern] [:Paketinstallation_DEB: Ein Paket installieren] [:Programme starten: Ein Programm ohne Menüeintrag starten] [:sudo: Root-Rechte] }}} [[Inhaltsverzeichnis()]] 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 [:ln#Hardlinks: 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] {{{#!vorlage Paketinstallation rsync }}} Folgendes Paket kann bei Bedarf installiert werden: {{{#!vorlage Paketinstallation openssh-server, optional, für das Sichern von einer Quelle über [:SSH:] }}} Außerdem kann ggf. ein [:Internetanwendungen#E-Mail: 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: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#Authentifizierung-ueber-Public-Keys: 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: {{{#!code bash #!/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", {{{#!code bash 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. {{{#!code bash 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 [:Skripte/Backup mit RSYNC#Einschraenkungen: 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. {{{#!code bash #!/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. {{{#!vorlage 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. ||<-3 rowclass="titel"> Getestete Dateisysteme || || FS || inkrementell || Hinweise || || ext2 || Ja ||<|5> Praktisch alle UNIX-artigen Dateisysteme unterstützen [wikipedia:Hardlink: 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 ||<|2> 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 [wikipedia: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. {{{#!vorlage Befehl 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 ([:Shell/cp: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. {{{#!vorlage Befehl 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. = Links = * [:Datensicherung:] {Übersicht} Übersicht, wichtige Verzeichnisse * [http://www.321tux.de/2011/01/komfortables-backup-skript-rsync/ Komfortables Backup-Skript] {de} * [http://blog.pointsoftware.ch/index.php/howto-local-and-remote-snapshot-backup-using-rsync-with-hard-links/ rsync-snapshot.sh] {en} Ein rsync Shell-Skript mit intelligenter Rotation (nicht lineare Distribution) von Backups. Integritätsschutz, Quotas, Regeln und viele Features. # tag: Shell, Sicherheit, Backup