= 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.
== 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 ==
<pre>
#!/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";
}
}
</pre>
== 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
''(Habe ich bisher nur bei Login per public key ohne Passwort
getestet -- ThomasBayen)''
== Links ==
*
[http://www-106.ibm.com/developerworks/linux/library/l-backup/?ca=dgr-lnxw16Backup
IBM-Artikel] gute Einführung in remote Backups per tar,
insbesondere auch in die ssh-Authentifizierung
* [http://www.linuxwiki.de/rsync/SnapshotBackups Linuxwiki.de] hat
einen guten Artikel über inkrementelle Backups mit rsync