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.
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
kann ich auch das Gespann Mondo+Mindi
zur Datensicherung mit grafischer (NCurses-)Oberfläche empfehlen.
unter DisklessClient. (Das Stichwort nfs-kernel-server wollte mir partout nicht einfallen.) --MarkusMonderkamp am 05.02.2007
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.
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.
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
#!/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";
}
}
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, aber dazu ist mir bisher noch keine einfache, universelle Methode eingefallen.
gute Einführung in remote Backups per tar, insbesondere auch in die ssh-Authentifizierung
hat einen guten Artikel über inkrementelle Backups mit rsync