Backup - Script #

Immer wieder kommt es vor, daß ich bestimmte Bereiche auf fernen Rechnern sichern will. Natürlich gibt es dazu ganz ausgefeilte Spezial-Programme. Meistens müssen diese aber erstmal installiert und konfiguriert werden, teilweise wird zum Sichern ein von anderen Tools nicht lesbares Format benutzt usw. Alles was ich will, ist hingegen, ein *.tgz-Archiv, wenn sich im Zielverzeichnis was geändert hat. Also habe ich eine ganz einfache Lösung geschrieben.

Alternativen #

  • Für ein regelmäßiges, professionelles Backup empfiehlt sich, rsnapshot einzusetzen, wie auf der Seite BackupServer beschrieben. rsnapshot ist wohl unter Linux die beste Lösung, wenn man regelmäßig automatisierte, inkrementelle Backups auf eine Festplatte machen will, die im Notfall sofort einsatzbereit sind. -- ThomasBayen
  • Nach einem online verfügbaren Artikel im Linux User Magazin 02/2007 kann ich auch das Gespann Mondo+Mindi zur Datensicherung mit grafischer (NCurses-)Oberfläche empfehlen.
    Dabei danke ich Thomas Bayen für die Hilfe zum Thema NFS unter DisklessClient. (Das Stichwort nfs-kernel-server wollte mir partout nicht einfallen.) --MarkusMonderkamp am 05.02.2007
Mondo ist wohl eine gute Lösung, wenn man ab und zu Sicherungen seines Basissystems auf CD (und zwar auch zur Komplettwiederherstellung) machen will. Es kann u.a. eine bootfähige Installations-CD erzeugen. -- ThomasBayen

ssh-Zugang #

Zuerstmal muss unser Skript sich ja überhaupt in den fernen Rechner einloggen können, um dort Dateien sichern zu können. Damit das automatisch, d.h. ohne Passworteingabe funktioniert, benutzen wir RSA-Keys.

Zuerst muss auf dem SSH-Client (also dem Backup-Server) ein RSA-Schlüsselpaar erzeugt werden. Dies geschieht mit ssh-keygen -t rsa. Wir benutzen damit einen SSH2-RSA-Key. Eine Passphrase geben wir nicht ein, da wir ja automatisch zugreifen wollen.

Auf dem fernen Server (wo die Backup-Daten liegen) muss nun ein Benutzer ausgewählt werden, der Zugang zu den zu sichernden Daten hat. Zu beachten ist jedoch, daß ein Angreifer, der den Backup-Server erobert, auch Zugriff auf diesen Account hat, da ja nun ein Passwort-loser Zugang vom Backup-Server aus möglich ist. Also sollte man nicht root auswählen, sondern besser einen besonderen User anlegen, der nur Lesezugriffe im System hat.

Nun wird die Datei ~/.ssh/id_rsa.pub auf den fernen Server in die Datei ~/.ssh/authorized_keys kopiert (bzw. angehängt, wenn da bereits Schlüssel drin sind). Damit ist der SSH-Zugang erlaubt.

Vorbereitung #

Am besten loggt man sich jetzt testweise mit ssh username@servername in den fernen Rechner ein. Klappt das ohne Passwort, kann man sofort ein Verzeichnis "backup" anlegen. Hier wird später das jeweils aktuelle tgz-Archiv angelegt. (Falls das Homeverzeichnis des Benutzers gesichert werden soll, darf das backup-Verzeichnis natürlich nicht mitgesichert werden. Dann sollte der Quelltext geändert werden und z.B. /tmp für das Backup genommen werden.

Backup-Script konfigurieren #

Jetzt muss nur noch für jedes zu sichernde Verzeichnis eine Zeile im Script angelegt werden. Danach das Verzeichnis für die Backup-Dateien backupdir anlegen und wie oben im Quelltext angegeben das Script per Cronjob z.B. täglich starten.

Die Einstellung für die SSH-Parameter sollte auf -2 für das SSH2-Protokoll stehen, der tar-Parameter auf -j für bzip2-Kompression. Einzig für den Zugriff auf Sourceforge sind andere Werte nötig, da dort nicht die alerneuesten ssh- bzw. tar-Versionen benutzt werden.

Update: Der Ärger mit den alten Programmversionen bei Sourceforge ist vorbei, seitdem die die Shell-Server neu aufgesetzt haben. Also kann hier auch -2 und -j benutzt werden. -- ThomasBayen

Script-Quelltext #

#!/usr/bin/perl
# backup.pl
# Script f|r automatisches Backup
#
# Dieses Script sollte mit forgender Crontab gestartet werden:
#




----------------------------------------------------------------------
# MAILTO=tbayen@bayen.loc
# @midnight /usr/bin/perl
/home/tbayen/perl/Backup-Manager/backup.pl
#
----------------------------------------------------------------------


use warnings;
use diagnostics;
use strict;


# Parameter
###########

my @quellen=(
  [qw(nevent_cgibin    -2 readuser nevent.pommes.loc     -j
/usr/lib/cgi-bin/)],
  [qw(nevent_eventdata -2 readuser nevent.pommes.loc     -j
/var/eventmanager/)],
  [qw(nevent_wiki      -2 readuser nevent.pommes.loc     -j
/var/wiki/)],
  [qw(empire_wiki      -1 tbayen   shell.sourceforge.net -I
empire/wiki/)],
  [qw(lug_wiki         -1 tbayen   shell.sourceforge.net -I
lug-kr/wiki/)],
);
my $ziel='/home/tbayen/perl/Backup-Manager/backupdir';



foreach my $quelle(@quellen){
 
my($projekt,$parameter,$user,$server,$tarparam,$verzeichnis)=@{$quelle};

  # Hilfsvariablen werden erzeugt:
  my $backupfile="backup/${projekt}_daily.tar.bz2";
  # Ich benutze bzip2, weil es gut komprimiert. Ausserdem sind zwei
  # zip-Archive f|r md5 nicht identisch (ein Byte unterscheidet
sich).
  # Leider ist der Befehl hierfuer nicht bei jedem tar gleich. :-(
  $tarparam.=' -c';
  $tarparam.=' -C /' if $verzeichnis =~ s/^\///;

  # Tar-File erzeugen und Checksumme holen:
  my $output=`ssh $parameter $user\@$server 'tar $tarparam -f
$backupfile $verzeichnis && md5sum $backupfile'`
  unless($output){
    print "Fehler beim Zugriff auf den Server!\n";
    next;
  }

  my $checksum='';
  if(open FILE,"<$ziel/${projekt}_checksum"){
    $checksum=<FILE>;
    close FILE;
  }
  # Wenn sich die Checksumme gedndert hat, wird die Datei geholt
  if($checksum ne $output){
    # Datum soll mit in den Dateinamen, muss also erstmal berechnet
werden
    my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime(time);
    my $time=($year+1900).($mon+1).$mday;
    system "scp $parameter -q $user\@$server:$backupfile
$ziel/${projekt}_$time.tar.bz2";
    # Ldnge speichern, damit Dnderungen beim ndchsten Mal erkannt
werden:
    open FILE,">$ziel/${projekt}_checksum";
    print FILE $output;
    close FILE;
    print "Projekt $projekt gesichert.\n";
  }
}

schnelles Backup zwischendurch #

Wer nur mal schnell ein einzelnes anständiges Backup übers Netz machen will, kann einen Befehl wie den folgenden benutzen:

  ssh root@meinserver 'tar cz /home/' >meinserver-home-$(date+%Y%m%d-%H%M%S).tgz

Wer eine grosse Datei (z.B. ein Image) möglichst schnell per ssh kopieren möchte, kann das mit

  tar cSC /source/dir/ filename | ssh -c blowfish username@zielhost 'tar xSC /target/dir'

machen. Im LAN ist es meiner Erfahrung nach schneller, auf Kompression zu verzichten. Gerne würde ich manchmal auch auf Verschlüsselung verzichten (die einzige ordentliche mir bekannte Methode geht mit netcat), habe aber damit bisher noch nicht viel experimentiert. Einen interessanten Geschwindigkeitsvergleich habe ich unter http://www.spikelab.org/blog/scpTarSshTarNc.html gefunden. Fazit: Niemals scp benutzen, immer komprimieren. Letztere Aussage wage ich zu relativieren, wenn man einen anderen Prozessor oder mehr als die 100MBit-Leitung des Autors benutzt.

Wer ein ganzes System sichern will (nicht nur das Home-Verzeichnis, kann das laut http://linuxclues.blogspot.com/2007/07/backup-your-system-using-tar.html mit folgendem Befehl machen

  sudo tar cvzpf /home/Backup.tgz --same-owner --exclude=/home/Backup.tgz --exclude=/home/error.log --exclude=/proc/* --exclude=/media/* --exclude=/dev/* --exclude=/mnt/* --exclude=/sys/* --exclude=/tmp/* / 2>/home/error.log

Eine weitere Möglichkeit ist die Übertragung mit rsync. Es hat ein paar Vorteile vor allem bei sehr grossen Dateien (z.B. Imagedateien von virtuellen Systemen): Es komprimiert selbst (besser als ssh), es kann mit sparse-Dateien umgehen und es kann abgebrochene Transfers wieder aufnehmen. Außerdem erlaubt es die Angabe eines Bandbreitenlimits, damit bei einem langen Backup nicht das ganze Netz blockiert ist. Beispiel:

  rsync -avzrS --partial --bwlimit=50000 root@meinserver:/home/virtual/.VirtualBox/HardDisks/serverimage.vdi /home/virtual/backups/

Backup auf CD/DVD #

schamlos aus der DLUG-Mailingliste extrahiert, dank an T. Reinartz, Mail vom 13.11.2008 um 21.33 Uhr

Ziel: Sicherung eines Dateisystems < 4,4 GB mit Hard- und Symlinks.
Howto:

  1. Eine Datei erstellen, die so groß wie eine CD (DVD) ist
  2. Diese Datei mit ext2 formatieren
  3. Die Datei einbinden (mount)
  4. In die “Datei” reinschreiben, was man später auf CD
    (DVD) haben möchte
  5. Die “Datei” aushängen (unmont)
  6. Die Datei brennen (wie ein ISO-Image)
  7. Dann die CD (DVD) wieder einhängen und schwupps: CD mit ext2!
Konsolenlog:

Und technisch geht das für eine DVD so:

dd if=/dev/zero of=dvd.ext2 bs=4096 count=1024k

# Es kommt die Frage ... kein spezielles Block-Gerät ... 
# Mit ja beantworten
mke2fs  -b 4096  dvd.ext2

mkdir /mnt/ext2
mount -t ext2 -o loop=/dev/loop0 dvd.ext2 /mnt/ext2

Jetzt kann man in /mnt/ext2 scheiben. Anschließend das Einhängen wieder rückgängig machen und die Datei brennen:

umount /mnt/ext2
# Brennen z. B. mit cdrecord oder Brasero

Diese DVD wird nach dem Einlegen (unter Ubuntu) nicht automatisch erkannt (es gibt sogar eine Fehlermeldung). Das Einhängen muss manuell erfolgen:

mount -r -t ext2 /dev/scd1 /mnt/ext2

Aber dann ist es cool. Die DVD hat in meinem Fall den ganzen Backup-Baum mit allen hard links. Und das browsen im Baum ist viel, viel schneller als in einem tar file.

Damit habe ich meine Lösung, wie ich meinen Dateibaum mit meinen backups dauerhaft sichern und ohne großen Aufwand nach alten Dateiständen suchen kann.

Ergänzung mit LUKS #

schamlos aus der DLUG-Mailingliste extrahiert, dank an H. Zessel, Mail vom 13.11.2008 um 23.30 Uhr

Bei Debian Etch klappt das sogar, wenn das Medium ein LUKS Image hat. Fand ich sehr praktisch.

Da man ja zu Sicherheit immer meist mit der Waffe zwingen muss, habe ich mal meine LUKS Befehlskette hervorgeholt, die ich hinterlegen musste. Die tippe ich nicht aus dem Kopf. Wenigstens nicht den LuksFormat..

Nach dem Imagebauen mit dd gehts dann so weiter:

losetup /dev/loop/1  $PWD/dvd.ext2  # manchmal ziehe ich absolute Pfade vor...
                  # evtl steht der nachher irgendwo zum Nachlesen (losetup -a)

cryptsetup  -v luksFormat -c aes-cbc-essiv:sha256 -h sha1 -s 256 /dev/loop/1

Dann GROSSES YES eingeben (oder -q Option). Dann Passphrase zweimal. (ich habe das auch schon mal 3x machen muessen, weil ich einfach nicht willens oder in der Lage war, GROSSES YES zu lesen und umzusetzen ! LOL Er sagt das naemlich explizit ! )

Hier dann mal zur Kontrolle und spaeterem Vergleich ein

  dmsetup ls

cryptsetup  -v luksOpen /dev/loop/1 dvd.ext2_crypt
Enter LUKS passphrase:
key slot 0 unlocked.
Command successful.

  dmsetup ls

...muesste jetzt ein dvd.ext2_crypt enthalten...

Und jetzt kommst Du wieder mke2fs, dann aber mit /dev/mapper/dvd.ext2_crypt ..._crypt ist einfach nur ne sinnvolle Konvention.

Wenn die automatische Erkennung nicht klappt (ich habe da auch noch einen Gentoo Abkömmling am Laufen, der das nicht kann - zumindest nicht mit Luks), dann kann man das pmount Kommando aber auch leicht manuell einsetzen. Also zB pmount /dev/dvd BACKUP_4711

Und dann kommt eine Passphraseabfrage per X Dialog.

Wenn Du beim mke2fs oder e2label einen sinnvollen Namen angibst, so landet das Ding ohne LUKS dann gleich beim mount in /media/BACKUP_4711. Das machts bei LUKS leider nicht automatisch - wenigstens nicht bei Etch. Da ist manuelles pmount von Vorteil wie oben im Beispiel. Vielleicht hast Du ja doch mal Nerv, das zu probieren :-). Es faellt nachher kaum noch auf. Meine mobilen Platten sind alle so. Wenn ich sie anhaenge - Passphrase, fertig.

  • IBM-Artikel gute Einführung in remote Backups per tar, insbesondere auch in die ssh-Authentifizierung
  • Linuxwiki.de hat einen guten Artikel über inkrementelle Backups mit rsync
Tags:  Backup

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-12) was last changed on 03-Jun-2010 11:22 by ThomasBayen