Backup-Server #

Wer von uns hat bei dem magischen Wort "BACKUP" nicht sofort ein schlechtes Gewissen?!? Die wirklich wichtigen Firmendaten sichere ich zwar mit einem Skript, aber schon meine Dokumenten-Verzeichnisse oder meine Photos, etc sichere ich "nach Lust und Laune". Dabei haben sich über die Jahre einige Moden ergeben, so daß ich einige Dinge einfach vom Laptop auf den Server kopiere, manche vorher zum tgz mache, andere auf CD brenne und diese dann irgendwo herumfliegt. Kurz und gut: Da musste ein konsistentes System her! Ich habe in Zukunft kein schleichtes Gewissen mehr! Ich habe mir endlich einen ultimativen, unaufhaltsamen Backup-Server gebaut! -- ThomasBayen

Vorüberlegungen #

Um ein gutes Backup zu machen, sollten folgende Hauptbedingungen erfüllt sein:

 1. Das Backup muss regelmäßig gemacht werden!
 2. Das Backup muss regelmäßig gemacht werden!!
 3. Das Backup muss regelmäßig gemacht werden!!!
 4. Das Backup muss im Notfall zurückspielbar sein

Aus diesen vier Hauptpunkten besteht das Ganze Problem. Alle anderen leiten sich davon ab. Dabei möchte ich nochmals extra auf Punkt 1 hinweisen: Das Backup muss regelmäßig gemacht werden! Letztlich ist es der Punkt 4, der die Arbeit macht, deshalb beschäftigt man sich recht viel damit. Es sind aber die Punkte 1-3, die meistens dazu führen, daß die Arbeit trotzdem für die Katz' ist, wenns drauf ankommt.

Entscheidungen #

Hardware #

Aus Punkt 1-3 ergibt sich für mich, daß ein Backup auf externe Medien wie CD-ROM oder Bandlaufwerk nicht in Frage kommt. Das Backup MUSS vollautomatisch laufen. Ich habe keinen externen Bandwechsler, der mir das aktuell richtige Band aus dem Regal holt und für CD-ROMS gibts sowas wohl auch nicht. Wenn man sich vornimmt, z.B. täglich eine frische CD-ROM einzulegen, verstößt man früher oder später eklatant gegen die Punkte 1-3. Das heisst, es kommt nur ein Backup auf eine Festplatte in Frage.

Außerdem ist der Rechner, der gesichert wird, (und/oder dessen Festplatte) im Notfall garantiert kaputt. Also benötige ich eine externe Festplatte. Dies kann entweder eine USB-Platte oder ein eigener Server sein. Da in jedem gutsortierten Linuxer-Haushalt noch ohne Ende alte Boxen herumstehen, kann man eine davon hierzu reaktivieren. Lediglich die Festplatte sollte neu, in gutem Zustand und angemessen gross sein.

Software #

Um am besten auf das Backup zugreifen zu können und da Plattenplatz sowieso nicht mehr die Welt kostet, habe ich von einer komprimierten Lösung abgesehen. Ich habe eine Lösung vorgezogen, die schlicht und ergreifend normale Linux-Verzeichnisse erzeugt, in denen meine Backup-Daten liegen. Juhu!

Die Grundlage einer jeden guten Sicherung unter Linux ist auf jeden Fall rsync. Dieses kann Dateibäume so über das Netz sichern, daß wirklich nur neue bzw. geänderte Dateien gesichert werden. Außerdem ist es wichtig, ein System zu haben, das bei einer erneuten Sicherung inkrementell, d.h. nur die Änderungen sichert. Dabei muss aber auf jeden Fall gewährleistet sein, daß man einfach den kompletten Dateibaum zurückbekommt (und nicht nur die letzte inkrementelle Änderung).

Eine gute Wahl für Leute, die Weboberflächen und damit einfache Administration mögen, ist wohl BackupPC. Ich habe es mir angesehen und halte die Möglichkeiten für sehr vielversprechend.

Ich selber bin allerdings etwas konsoliger veranlagt und hatte eigentlich vor, mir etwas kleines mit Hilfe von rsync selber zu schreiben. Dann habe ich mich umgeschaut und einen hochinteressanten Artikel gefunden, den ich jedem zu lesen empfehle, in dem ein ebensolches Skript beschrieben und jede dabei getroffene Entscheidung diskutiert wird. Was mich hieran auch fasziniert ist, daß die Backups als normale Verzeichnisse zugänglich sind und somit eine Rücksicherung (auch für normale User) so einfach wie "cp" bzw. die Bedienung des Konqueror ist. Dabei ist das Ganze logisch, einfach und benutzt die Tools aus dem Linux-Baukasten wie cp, ssh, rsync, etc.

Eine Erweiterung dieses einfachen und durchdachten Skript-Ansatzes ist nun rsnapshot. Es ist ein einfaches Konsolenprogramm, das alles kann, was mein Herz begehrt (und es liegt als Debian-Paket vor)!

Installation #

Als Basis habe ich einen Rechner mit einem Debian Etch System aufgesetzt und ihm eine zusätzliche Partition "/backup" mit 100GB spendiert. Dann habe ich das rsnapshot-Paket installiert.

Konfiguration von rsnapshot #

Nun noch in der /etc/rsnapshot.conf einiges eingestellt (d.h. am Ende angefügt):

  # -TB-
  # Was ich nicht sichern will:
  # Verzeichnisse, die per meiner Konvention nicht wichtig sind:
  exclude Download/
  exclude killme/
  exclude dontbackup/
  # Verzeichnisse, die per Linux-Konvention nicht wichtig sind:
  exclude tmp/
  exclude /var/spool/
  # KDE-Trashcan
  exclude .local/share/Trash/
  # Firefox-Cache
  exclude firefox/*/Cache/
  backup  root@krefix:/etc/               krefix_etc/
  backup  root@mailserver:/etc/           mailserver_etc/
  backup  root@mailserver:/home/          mailserver_home/
  backup  root@bmailserver:/var/mail/     mailserver_var_mail/
  backup  root@arbeitsplatz:/etc/         arbeitsplatz_etc/
  backup  root@arbeitsplatz:/home/        arbeitsplatz_home/
  backup  root@server:/                   server/                 one_fs=1

Wichtig ist, daß alle Parameter durch "TAB" getrennt werden (und nicht durch Leerstellen, die dadurch in Dateinamen vorkommen können). Wi man sieht, sieht die Konfiguration sehr einfach aus und das ist sie auch! Auf den zu sichernden Rechnern muss noch das rsync-Paket installiert werden und wir können schon mit

  rsnapshot hourly

ein Backup machen. Wer will kann mit "-v" bzw. "-V" einen Einblick erhalten, was dabei so vor sich geht (Wer obigen Artikel gelesen hat, hat bereits eine gute Vorstellung von der Arbeitsweise, weswegen ich das hier nicht wiederhole).

Nun kann man nach mehreren Durchläufen mit sowas wie

  rsnapshot daily
  rsnapshot weekly

Backups mit größeren Zeiträumen machen (ein Blick in die Konfigurationsdatei erklärt das System). Dabei ist zu beachten, daß z.B. ein "weekly" snapshot genaugenommen immer eine Kopie des ältesten "daily" snapshots ist. Es wird also strenggenommen nicht der jetzige Stand als Wochensicherung genommen, sondern der von vor einer Woche. Dies ist auch richtig, weil der jetzige Stand ja noch als Tagessicherung verfügbar bleibt.

automatisches starten #

Dazu habe ich in die Datei /etc/cron.d/rsnapshot folgendes geschrieben:

  0 4,10,12,14,16,18,20   * * *           root    /usr/bin/rsnapshot hourly
  40 3                    * * *           root    /usr/bin/rsnapshot daily
  20 3                    1,8,15,22 * *   root    /usr/bin/rsnapshot weekly
  0  3                    1 * *           root    /usr/bin/rsnapshot monthly
  40 2                    1 1 *           root    /usr/bin/rsnapshot yearly

Der Eintrag für "weekly" ist so aus der rsnapshot-manpage genommen. Die Debian-Version ist anders aufgebaut. Der Unterschied hängt damit zusammen, daß die Intervalle immer jeweils vom darüberliegenden abhängen. Die hier benutzte Original-Version sorgt dafür, daß die Monatssicherung immer vom 1. des Monats ist. Die Debian-Version sorgt stattdessen dafür, daß die Wochensicherung immer Montags ist, dafür ist die Monatssicherung dann vom ersten Montag des Monats (und vom zweiten, wenn der Monat fünf Montage hat).

passend dazu habe ich in /etc/rsnapshot.conf eingetragen:

  interval        hourly  7
  interval        daily   7
  interval        weekly  4
  interval        monthly 12
  interval        yearly  100

Nun werden die Sicherungen automatisch angefertigt. Übrigens habe auch ich (wie Du bestimmt gerade) am Anfang die Idee, Sicherungen alle zwei Stunden zu machen, für übertrieben gehalten. Andererseits stört das im Grunde keinen. Die Sicherung eines nicht veränderten Verzeichnisses mit ca. 40GB Daten dauert bei mir ca. 1 Minute und benötigt ca. 200MB (für die zusätzlichen Inodes). Das kann ich gut verschmerzen. Dafür kann es sich als Luxus erweisen, nochmal auf die Datei von heute morgen zugreifen zu können, die ich gerade aus Versehen gelöscht habe...

Je nachdem, wie "nackt" das Grundsystem installiert ist, ist die Zeitzone für cron nicht richtig eingestellt. Für mich hat die Installation des Paketes locales sowie ein Neustart von cron (und ggf. anderer Daemonen wie dem Logging) geholfen, dies zu beheben (obwohl eigentlich tzconfig dafür zuständig sein soll, wie ich später bemerkte).

Extra-Sicherungen zu besonderen Zeitpunkten #

Was bei rsnapshot irgendwie vergessen worden zu sein scheint, ist die Notwendigkeit, spezielle Sicherungen zu besonderen Zeitpunkten zu machen. So möchte ich vielleicht vor einem größeren Software-Update nochmal alles festhalten und ablegen. Eine solche Sicherung wäre außerhalb des normalen Sicherungszyklus zu machen.

Ein Sonderfall ist auch der allererste Stand. Wenn man diesen nicht zufällig am 1. des Monats macht, so wird der "Anfangsstand" nicht aufgehoben. Die Tagessicherung nimmt sich ja bekanntlich die "letzte" Stundensicherung. Existiert jedoch noch keine mit der höchstmöglichen Nummer (weil ich mitten im Tag angefangen habe), so wird gar keine Tagessicherung angelegt. Dasselbe geschieht analog dann auch mit der Wochen-, Monats-, usw-Sicherung.

Eine solche Sonderversion erstellt man ganz einfach aus der aktuellsten Sicherung (hourly.0) mit:

  cp -al /home/backup/hourly.0 /home/backup/vorGrossemUpdate

Einloggen auf fremden Rechnern #

Wie man sieht, loggt sich rsync per "ssh" auf die zu sichernden Rechner ein. Dabei will man natürlich kein Passwort vergeben. Hierzu erlauben wir wie auf OpenSSH erklärt, das passwortlose einloggen. Aber Halt! Nun kann jeder böse Mensch, der sich in unseren Backup-Server hackt, Root-Rechte auf allen meinen Servern erhalten... Dazu modifizieren wir auf den zu sichernden Systemen die Datei .ssh/authorized_hosts des Users, unter dem wir uns einloggen (also root in obigen Beispielen), indem wir ganz am Anfang der Zeile unseres Schlüssels folgendes einfügen:

  command="rrsync -ro /" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzGhEeNlPr...

Damit geben wir dem ssh-Daemon vor, statt einen angegebenen Programms nur noch das Kommando rrsync zu starten. Dieses ist ein Skript, das in der rsync-manpage erwähnt wird. Ich habe es auf http://www.inwap.com/mybin/miscunix/?rrsync gefunden. Dieses Skript muss nach /usr/bin/rrsync kopiert und ausführbar gemacht werden. Ich habe es hier eingefügt:

  #!/usr/bin/perl
  # Name: /usr/local/bin/rrsync   Author: Joe Smith <js-cgi@inwap.com> 30-Sep-2004
  # Purpose: Restricts rsync to subdirectory declared in .ssh/authorized_keys
  # (should have a symlink in /usr/bin)
  
  use Socket;
  use constant LOGFILE => '/var/log/rrsync.log';
  my $Usage = <<EOM;
  Use 'command="$0 [-ro] subdir"'
          in front of lines in $ENV{HOME}/.ssh/authorized_keys
  EOM
  
  my $ro = (@ARGV and $ARGV[0] eq '-ro') ? shift : '';    # -ro = Read-Only
  my $subdir = shift;
  die "No subdirectory specified\n$Usage" unless defined $subdir;
  
  # The client uses "rsync -av -e ssh src/ server:dir/", and sshd on the server
  # executes this program when .ssh/authorized_keys has 'command="..."'.
  # For example:
  # command="rrsync logs/client" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzGhEeNlPr...
  # command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmkHG1WCjC...
  #
  # Format of the envrionment variables set by sshd:
  # SSH_ORIGINAL_COMMAND=rsync --server          -vlogDtpr --partial . dir # push
  # SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . dir # pull
  # SSH_CLIENT=client_addr client_port server_port
  
  my $command = $ENV{SSH_ORIGINAL_COMMAND};
  die "Not invoked via sshd\n$Usage"      unless defined $command;
  
  my ($cmd,$dir) = $command =~ /(.* \.) ?(.*)/;
  die "SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $cmd =~ /^rsync\s/;
  die "$0 -ro: sending to read-only directory $dir not allowed\n"
          if $ro and $cmd !~ /^rsync --server --sender /;
  
  my $orig = $dir;
  $dir =  $subdir if $dir eq '';          # Use subdir instead of $HOME
  $dir =~ s%^/%%;                         # Don't allow absolute paths
  $dir =  "$subdir/$dir" unless $dir eq $subdir or $dir =~ m%^\Q$subdir/%;
  $dir =~ s%/\.\.(?=/)%__%g;              # Don't allow foo/../../etc
  $dir =~ tr|-_/a-zA-Z0-9.,|_|c;          # Don't allow ;|][}{*?
  
  if (-f LOGFILE and open LOG,'>>',LOGFILE) {
    my ($mm,$hh) = (localtime)[1,2];
    my $host = $ENV{SSH_CLIENT} || 'unknown';
    $host =~ s/ .*//;                     # Keep only the client's IP addr
    $host = gethostbyaddr(inet_aton($host),AF_INET) || $host;
    $_ = sprintf "%-13s",$host;
    print LOG "$hh:$mm $_ [$command] =",($dir eq $orig ? " OK" : "> $dir"),"\n";
    close LOG;
  }
  
  exec "$cmd $dir" or die "exec($cmd $dir) failed: $? $!";
  # Note: This assumes that the rsync protocol will not be maliciously hijacked.

Nun ist sichergestellt, daß ein fremder Hacker nur noch lesend (-ro) und nur noch auf ein bestimmtes Verzeichnis (im Beispiel /) zugreifen darf. Damit sollte man die Zugriffsrechte etwas eingrenzen können. Natürlich kann ein Fremder (der den Backup-Server gehackt hat), nun alle Dateien z.B. unter "/" lesen und dabei wahrscheinlich auch sicherheitsrelevaten Dinge. Allerdings kann er das sowieso, wenn er in das Backup schaut... Also sollte der Backup-Server bzw. der Zugriff darauf auf jeden Fall nicht leichtsinnig behandelt werden, wenn man solche Daten sichert.

Logging #

Mit

  touch /var/log/rrsync.log

sorge ich dafür, daß Zugriffe geloggt werden. Wer Angst hat, daß dieses Log aus dem Ufer läuft, kann es noch mit einer Datei /etc/logrotate.d/rrsync ähnlich dem folgenden beschränken:

  /var/log/rrsync.log {
        rotate 12
        monthly
  }

Sichern von Binärformaten #

Es gibt Programme, die legen Ihre Daten in "unsicheren" Binärformaten ab. Diese Formate können sich z.B. abhängig von der Programmversion, benutzter Bibliotheken oder auch der Architektur (z.B. Little oder Big Endian bei Daten) unterscheiden. Je nach Anwendung und Wichtigkeit ist es sinnvoll, für solche Applikationen einen Dump in einem definierten Format (meist ein textbasiertes Format) zu erstellen und das dann zu sichern. Dies ist z.B. sinnvoll bei MySQL-Datenbanken oder einem SubVersion-Repository. Die entsprechenden Befehle zum sichern und rücksichern müssen hierzu angegeben werden. Auch dieses kann rsnapshot leisten. Ich verweise für die genaue Konfiguration auf die Dokumentation.

sichern/kopieren des Backups #

Eine Frage bleibt bisher noch unbeantwortet: Wie sichert man ein solcches Backup bzw. was macht man, wenn man den Backupserver z.B. auf eine größere Festplatte übertragen möchte. Da rsnapshot sehr stark auf der Benutzung von Hardlinks basiert, benötigt man eine Methode, um Hardlinks ordentlich kopieren zu können.

Meine Lösung ist folgender Befehl:

  rsync -aHSx --bwlimit=50000 root@backupserver:/ backup/

Damit habe ich es geschafft, einen Backupserver mit ca. 160 GB Daten, die über sehr viele Backup-Sets mit unendlich vielen Hardlinks verteilt waren (ca. Inodes), sauber so auf einen anderen Rechner zu kopieren, daß die Hardlinks alle erhalten blieben. Beide Rechner hatten 512 MB Hauptspeicher (was offensichtlich ausreichte, um die Nodes zu verwalten). Mit "free" hatte ich den Eindruck, daß davon ca. die Hälfte benutzt worden ist.

  wenn -H --hard-links  preserve(erhalten) hard links
  dann würde ich dass ja weglassen 
  und -L benutzen wenn man symlinks nicht brauch
  --JensKapitza
Hmmm... ich bin mir nicht sicher, daß ich Deinen Kommentar verstanden habe. Vielleicht hast Du aber auch das Problem nicht richtig verstanden. Besser, ich erkläre es nochmal: Ich habe 20 Verzeichnisse mit 20 Backup-Ständen. Wo möglich benutzen diese Hardlinks. Wenn nun ein Backup 10 GB benötigt, benötigen 20 Backups aufgrund der Hardlinks nur 15 GB. (Einmal 10 für die allererste Sicherung und dann jeweils alle Änderungen und natürlich eine Menge inodes). Wenn ich dieses Gebilde nun mit "cp" kopiere, hat das Ergebnis 200 GB statt 15 GB. Das ist blöd. Wie kann man das besser machen? --ThomasBayen
Ok da habe ich was nicht richtig gelesen, sry wenn du cp benutzt dann mach mal cp -al $quelle $ziel in der doku steht nur was von link ;) aber meine 400Mb testfile ist in 1 sec kopiert --JensKapitza
Nein, ich möchte ja die bereits vorhandenen Hardlinks auf eine zweite Partition (bzw. neue Festplatte in einem anderen Rechner) kopieren und keine neuen erzeugen. cp war nur ein schlecht gewähltes Beispiel, in Wirklichkeit suche ich etwas, das übers Netz geht. Dein Testfile ist nicht kopiert, sondern verlinkt worden, was nur innerhalb einer Partition geht. Interessanterweise habe ich beim testen gerade festgestellt, daß "cp -a" entgegen meiner festen Überzeugung eben doch Hardlinks kopiert (mein obiges Beispiel wäre damit also gelöst). Nun bräuchte ich sowas noch über ein Netzwerk. Damit könnte man dann die Backups von rsnapshot auf einen zweiten Rechner spiegeln (und da will ich die ganze Zeit hin). --ThomasBayen
1) sshfs und dann cp dass wäre ne einfache Lösung sshfs $quelle:/ $ziel; cp -a $quelle_daten $ziel; --JensKapitza
Ich glaube nicht, daß sshfs die inode-Nummern richtig erhält. Somit dürfte das nicht funktionieren. Andererseits sollte es ja "irgendwelche" inodes benutzen. Hast Du irgendwo ein sshfs laufen, um das mal zu probieren? Dazu kommt, das ssh bei grösseren Datenmengen grottenlangsam ist, aber da kommt man wohl nicht so leicht drumrum. -- ThomasBayen
also wenn ich meine 400 MB mit sshfs kopiere dann dauert es länger *aber ich weiß grade nicht wie ich bei mir gucken kann dass das nicht echte 400 MB sind sondern nur links (hmm sollte mal gößere Daten nehmen um etwas zu sehen ;) )
"ls -l" zeigt hinter den Permissions und vor den Usern die Anzahl der Hardlinks an, die bei Dateien normalerweise "1" ist. Mit "ls -li" steht vorne noch zusätzlich die inode-Nummer, die bei Hardlinks identisch ist. -- ThomasBayen
2) nfs, da es das filesystem des Servers nutzt (ext3) geht es evtl. damit? --JensKapitza
Habs gerade mal ausprobiert und festgestellt, daß nfs tatsächlich die Original-Inode-Nummern angibt und damit auch die Hardlinks erhält. Das ist eine Lösung. :-) Wenn das mal jemand mit sshfs testen könnte, wäre das schön. Dann könnte man NFS Lösung mit hoher Übertragungsrate und sshfs als Lösung, die keine installierten Pakete auf der Gegenseite benötigt, empfehlen. -- ThomasBayen
rsync hat den Vorteil, daß es grundsätzlich auch netzwerktauglich ist und das es die "-H"-Option für Hardlinks besitzt. Leider benötigt dieser Aufruf bei einer entsprechenden Backup-Größe wahrscheinlich viel Hauptspeicher. Bessere Lösungen werden gerne angenommen...

Sichern der Sicherung als gesamtes Image

Bei mir ist der Backup-Server ein virtuelles System. Dadurch ist das Sicherungs-Filesystem eine grosse Image-Datei auf einem Virtualisierungsserver. Diese Datei wächst automatisch mit der Belegung des Platzes, so daß ich die Sicherungspartition sehr groß (im Grunde sogar größer als den physischen Platz auf dem Virtualisierungs-Server) wählen kann. Diese (sehr grosse) Datei kann ich dann ggf. auf einen anderen Rechner kopieren (als Sicherung oder später, um mehr Platz zur Verfügung zu stellen).

Bei der Kopie einer solchen sehr grossen Datei gibt es allerdings ein paar Klippen zu umschiffen. Zuerstmal sollte man darauf achten, daß das Backup-System heruntergefahren ist, damit die Datei sich während der Kopie nicht mehr ändert. Dann sollte man hier rsync nehmen, um auch nur Änderungen zu übertragen. Außerdem stellt rsync sicher, daß man nach einer Unterbrechung nicht wieder ganz von vorne anfangen muss (Bei der Größe der Datei sehr wichtig). Man muss darauf achten, daß Sparse-Teile in der Datei erhalten bleiben. Die Sicherung läuft bei einer grossen Datei über das Netzwerk natürlich recht lange. Daraus ergab sich bei mir noch das praktische Problem, daß das ganze Netzwerk für einige Zeit zusammenbrach. Also wäre eine Bandbreitenbegrenzung gut. Alles in allem habe ich folgende Kommandozeile benutzt:

  rsync -avzrS --partial --bwlimit=50000 root@quattro:/home/vboxuser/.VirtualBox/HardDisks/backupserver.vdi /home/user/backupserver/

Wer den Server nicht als Image rumliegen hat, sondern eine echte Platte benutzt, dürfte ein Problem haben, weil man dann nicht rsync benutzen kann. Kennt da jemand eine Lösung?!?

aufräumen von Festplatten #

Wenn man mehrere verschiedene Systeme sichert, ist es natürlich immer noch so, daß jedes gesicherte System als Basissicherung eine vollständige Kopie eines jeden Systems enthält und auf die Backup-Platte speichert. Da sich mehrere Systeme aber oftmals recht ähnlich sind (gleiche Distribution etc), könnte man noch mehr sparen, wenn man da noch mehr Hardlinks verwendet. Dazu gibt es den Artikel FestplatteAufraeumen.


Autor: ThomasBayen, JensKapitza

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-20) was last changed on 11-Sep-2011 16:22 by ThomasBayen