= 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.

Für ein regelmäßiges, professionelles Backup empfiehlt sich, [http://rsnapshot.org rsnapshot] einzusetzen, wie auf der Seite BackupServer beschrieben.

== 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