BLog

ImprintImpressum
PrivacyDatenschutz
DisclaimerHaftung
Downloads 

Backup-Strategie für den FreeBSD-Home-Server

In meinem Heim-Netzwerk befindet sich der FreeBSD-Home-Server mit mehreren macOS-Client-Computern und 3 iPhones. Die Backups der iPhones landen im iTunes auf dem Mac des jeweiligen Benutzers. Das Backup der Macs inklusive des jeweiligen iPhone-Backups läuft über die in macOS seit Version 10.5 integrierte Time Machine, wobei die TM die Backups jeweils stündlich über das Netzwerk auf ein separates Volume des FreeBSD-Home-Servers speichert. Für eine umfassende Datensicherung fehlt also nur eine Backup-Strategie und das dazugehörige System für den Server.

Server-Backup-System

Während bei einem Client-Backup die Sicherung der Daten des Benutzers, womöglich in mehreren Versionen, im Vordergrund steht, geht es beim Server neben der eigentlichen Datensicherung auch um eine schnelle Wiederherstellung der Funktionalität im Ernstfall. Beides erreicht man am besten in dem man in regelmäßigen Abständen eine exakte 1:1 Kopie der Server-Volumes auf eine externe Festplatte überspielt, also einen sogenannten Festplatten-Klon erstellt. Fällt der Server aus, dann kann man den Klon in einen anderen Rechner einbauen, und damit in kürzest möglicher Zeit einen neuen Server mit der Funktionalität auf dem Stand des letzten Sicherungszeitpunkts aufsetzen.

Im Grunde muß die Kapazität der Klon-Festplatte gerade ausreichen, um die Datenmenge der Arbeitsfestplatte aufnehmen zu können. Die allgemeine Erfahrung zeigt, daß Festplatten immer irgendwann voll werden, und damit man keine bösen Überraschungen beim Klonen erlebt, weil die Klon-Platte zu klein ist, wählt man am besten von vornherein für den Klon eine Platte mit derselben Kapazität wie diejenige der Arbeitsfestplatte.

Aus grundsätzlichen Erwägungen heraus ist es sinnvoll die Klon-Platte separat vom Server aufzubewahren. Denn neben inhärenter Systemfehler gibt es ja auch Katastrophen infolge derer das System und seine Datenträger unwiderruflich zerstört bzw. unserem Gebrauch entzogen werden können, z.B. Brand- und Wasserschäden, einstürzende Neubauten, Diebstahl, Beschlagnahme, etc. Damit nun die Klon-Platte nicht demselben Feuer, Hochwasser, Sturz bzw. derselben Wegnahme zum Opfer fallen kann, muß sie nach jedem Backup-Vorgang mit Bedacht an einen feuer- und wasserfesten sowie geheimen Ort ausgelagert werden.

Es empfiehlt sich sogar mindestens 2 Klon-Platten in dem Backup-System zu verwenden. Je nach Datenmenge kann das Klonen nämlich einige Stunden dauern, und wenn einer der genannten Katastrophen während des Klon-Vorganges einträte, dann wäre alles weg. Mindestens 1 Klon sollte also immer an einem sicheren Ort lagern. Jedenfalls bieten sich externe USB-Festplatten zur Datensicherung an. Diese lassen sich einfach an- und abklemmen und nehmen nicht viel Stell- bzw. Lagerplatz ein.

Vorbereitung der Klon-Platte(n)

Die Klon-Platten müssen für FreeBSD partitioniert und formatiert werden. Die folgenden Schritte braucht man im Prinzip je Klon-Platte nur ein einziges Mal durchführen. Es ist jedenfalls wichtig, daß die Gerätekennung der jeweiligen Festplatte eindeutig identifiziert wird, damit nicht versehentlich das falsche Laufwerk formatiert wird. Wir melden uns als root-User an unserem Server an:

ssh -p11 root@192.168.1.35
Password for root@server:

Wir wollen nun die Einträge im System-Logbuch verfolgen, und dazu setzen wir das folgende Kommando ab:

tail -f /var/log/messages

Wir schalten die externe USB-Platte ein und schließen sie an eine freie USB-Schnittstelle des Servers an. Sobald der Server die Festplatte erkannt hat, tauchen entsprechende Einträge im System-Logbuch auf, z.B.:

Aug 18 17:17:41 server kernel: ugen4.2:  at usbus4
Aug 18 17:17:41 server kernel: umass0:  on usbus4
Aug 18 17:17:41 server kernel: umass0:  SCSI over Bulk-Only; quirks = 0x4000
Aug 18 17:17:41 server kernel: umass0:2:0:-1: Attached to scbus2
Aug 18 17:17:41 server kernel: da0 at umass-sim0 bus 0 scbus2 target 0 lun 0
Aug 18 17:17:41 server kernel: da0: Fixed Direct Access SCSI-2 device 
Aug 18 17:17:41 server kernel: da0: Serial Number D57CA3405260
Aug 18 17:17:41 server kernel: da0: 40.000MB/s transfers
Aug 18 17:17:41 server kernel: da0: 953869MB (1953525168 512 byte sectors: 255H 63S/T 121601C)
Aug 18 17:17:41 server kernel: da0: quirks=0x2<NO_6_BYTE>

Im vorliegenden Fall können wir erkennen, daß der soeben angeschlossenen USB-Festplatte vom Betriebssystem die Gerätekennung da0 zugewiesen wurde. Ferner wurde die Platte als Device unter /dev/da0 in die Geräteliste aufgenommen. Wichtig: man darf nicht davon ausgehen, daß die Platte immer dieselbe Kennung bekommt. Wenn ein anderes USB-Massenspeichermedium zuvor angeschlossen wurde, dann kann es sein, daß dieses als da0 geführt wird und unsere Klon-Platte z.B. als da1. Man muß sich also immer über die Gerätekennung eines des Laufwerks vergewissern, bevor man gravierende Änderungen vornimmt.

Zum Formatieren der Platte benutzen wir das FreeBSD-Tool gpart(8). Ggf. muß zunächst die alte Formatierung von daX zerstört werden, wobei in den in der Folge aufgeführten Befehlen daX durch die tatsächliche Gerätekennung ersetzt werden muß:

gpart destroy -F daX​

Mit der folgenden Kommando-Sequenz wird die Festplatte für FreeBSD partitioniert und boot-fähig gemacht:

gpart create -s gpt daX
gpart add -s 128 -a 4k -t freebsd-boot daX
gpart add -s 4G -a 4k -t freebsd-swap -l SWAP daX
gpart add -a 4k -t freebsd-ufs -l BACK daX
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 daX

Mit dem folgenden Befehl kann man die auf diese Weise erstellte Partitionstabelle überprüfen:

gpart show daX
>>>>>
=>        34  1953525101  daX  GPT  (932G)
          34           6       - free -  (3.0k)
          40         128    1  freebsd-boot  (64K)
         168     8388608    2  freebsd-swap  (4.0G)
     8388776  1945136352    3  freebsd-ufs  (928G)
  1953525128           7       - free -  (3.5k)

Nun muß noch das Dateisystem auf der Arbeitspartition daXp3 erzeugt werden:

newfs -nU /dev/daXp3
tunefs -a enable /dev/daXp3​

Die obigen Schritte müssen für jede einzelne der Klon-Platten wiederholt werden.

Der eigentliche Klon-Vorgang

Es wird eine exakte, betriebsbereite Kopie also ein Klon der Arbeitsfestplatte benötigt, und das kann man im Prinzip mit mehreren unter FreeBSD verfügbaren Werkzeugen bewerkstelligen:

  • dump(8)/restore(8) wird häufig als primäre Backup-Lösung für FreeBSD empfohlen. Die Kombination funktioniert, aber sie ist sehr langsam. Backups von großen Datenmengen können extrem lange dauern, und es gibt keinen Synchronisationsmodus bei dem nach einem ersten vollständigen Backup in der Folge nur geänderte Daten vom Original zum Klon übertragen bzw. vom Original entfernte Daten auf dem Klon gelöscht werden.
  • cp(1), also der „normale" copy-Befehl, könnte mit seiner Kommando-Option -Rp (recursive) zum Klonen benutzt werden. Dieser Befehl ist schnell, aber Hard-Links werden in normale Dateien umgewandelt, und Extended Attributes werden nicht kopiert. Ausserdem gibt es auch bei cp keinen Synchronisationsmodus.
  • dd(1) ist das Schweizer Taschenmesser unter den Kopierwerkzeugen. Im Block-Kopiermodus kann es unabhängig vom Dateisystem ein komplettes Gerät (Device) auf ein zweites übertragen. Der Block-Kopiermodus ist die schnellstmögliche Variante, und er erzeugt exakte Kopien, allerdings ist dieser nicht für das Klonen von laufenden Systemen geeignet, weil das Kopieren der Blöcke ohne Rücksicht auf etwaige Dateisystemänderungen im Hintergrund erfolgt. Einen Synchronisationsmodus gibt es nicht, und ferner werden auch leere Blöcke kopiert, d.h. bei halbleeren Platten geht der Geschwindigkeitsvorteil schnell dadurch verloren, daß prinzipbedingt zusätzlich zu den Nutzdaten ein Haufen leerer Datenblöcke mit kopiert werden muß.
  • rsync(1) ist ein bekanntes Dateisystem-Kopierwerkzeug. Es ist nicht Bestandteil des Basissystems, und kann bei Bedarf aus den FreeBSD-Posts heraus installiert werden. rsync kann fast alles was man für das Klonen braucht. Man kann es bei laufendem System benutzen, es erhält die Hard Links und kopiert zum Teil die Extended Attributes (nur User-EA's). Es kann im Synchronisationsmodus betrieben werden, allerdings ist rsync -axAHX --fileflags etwas langsamer als der normale Kopiervorgang cp -Rp. Da rsync nicht die erweiterten Systemattribute (Extended Attributes im System Namespace) überträgt, ist es jedoch nicht grundsätzlich für alle Klon-Vorgänge geeignet.
  • clone(1) ist ein von mir zum Zwecke des Dateisystem-Klonens programmiertes Kopierwerkzeug, und es steht als Open Source Project bei GitHub zur freien Verfügung. Unter FreeBSD kann es aus dem Ports-System heraus installiert werden. clone ist auf Geschwindigkeit und geringen Ressourcen-Bedarf getrimmt. Es funktioniert bei laufendem System, erhält Hard Links, kopiert ACLs, alle Extended Attributes (System und User) und alle File System Attributes und es kennt einen ausgefeilten Synchronisationsmodus.

In der Folge wird das Backup-System rund um clone aufgebaut werden. Wenn man keinen Wert auf die erweiterten Systemattribute legt, dann kann man sinngemäß auch rsync einsetzen. Das Kopierwerkzeug wird als FreeBSD-Binär-Paket installiert:

pkg install clone
>>>>>
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	clone: 1.0.7_3

Number of packages to be installed: 1

21 KiB to be downloaded.

Proceed with this action? [y/N]: y
[1/1] Fetching clone-1.0.7_3.txz: 100%   21 KiB  21.9kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/1] Installing clone-1.0.7_3...
[1/1] Extracting clone-1.0.7_3: 100%

Die Bedienungsanleitung von clone kann man sich wie unter allen Unix-Varianten üblich mit dem man(1)-Befehl anzeigen lassen:

man clone
>>>>>
clone(1)             FreeBSD General Commands Manual (urm)            clone(1)

NAME
     clone - A file tree cloning tool

SYNOPSIS
     clone [-c roff|woff|rwoff] [-d|-i|-s] [-v level] [-x exclude-list]
           [-X excl-list-file] [-y] [-h|-?|?] source/ destination/

DESCRIPTION
     clone is a file tree cloning tool which runs 3 threads - a scheduler
     (main), a reader, and a writer thread. Reading and writing occurs in
     parallel. While this is most beneficial for copying data from one
     physical disk to another, clone is also very well suited for cloning a
     file tree to any place on the same disk.
     ...

Um einen fatalen Fehler beim automatischen Backup auszuschließen, nämlich daß das falsche Volume überschrieben wird, ist es notwendig, die Festplatten-Partitionen eindeutig zu benennen. Sofern die Partitionen der Arbeitsfestplatte des Servers nicht bereits direkt im Anschluß an die FreeBSD-Installation benannt wurden, vergibt man die Namen (Label) mit den folgenden Befehlen:

gpart modify -i 2 -l swap adaX
gpart modify -i 3 -l server adaX​

Auch die Klon-Festplatten wurden schon dementsprechend eingerichtet - s. oben. Dazu diente der folgende Befehl, mit dem die Arbeitspartition den Namen (Label) BACK zugewiesen bekam:

...
gpart add -a 4k -t freebsd-ufs -l BACK daX
...

Ein erstes Backup

Es wird zunächst ein sogenannter Mount-Point erzeugt. Das ist im Grunde ein gewöhnliches Datei-Verzeichnis unter dem der Inhalt einer Laufwerkspartition eingehängt werden kann. Das Verzeichnis bekommt den naheliegenden Namen back, und es wird auf der unteren Verzeichnisebene der Arbeitspartition des Servers / ein für alle mal angelegt:

mkdir /back

Man schaltet eine der Klon-Festplatten ein und schließt sie an einen USB-Port des Servers an. Mit dem mount-Befehl hängt man nun die o.g. BACK-Partition unter /back ein:

mount -o noatime /dev/gpt/BACK /back

Wenn die Klon-Festplatte frisch formatiert wurde, dann befindet sich bis auf ein leeres Verzeichnis mit dem Namen .snap nichts weiter auf der BACK-Partition:

ls -l /back
>>>>>
total 4
drwxrwxr-x  2 root  operator  512 Jul 22 20:00 .snap

Der folgende Befehl klont nun die Arbeitspartition unseres Servers auf die BACK-Partition der Klon-Festplatte:

clone -c rwoff -x .snap:.sujournal / /back
>>>>>
File tree cloning by Dr. Rolf Jansen (c) 2013-2017 - Version 1.0.7 (r80)
clone / /back/
=+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
...
...
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
264861 items copied, 2013.5 MB in 207.58 s -- 9.7 MB/s
No errors occured.
ls -l /back
>>>>>
total 92
-rw-r--r--   2 root  wheel      969 Jan 16  2014 .cshrc
-rw-r--r--   2 root  wheel      257 Jan 16  2014 .profile
-rw-------   1 root  wheel     1024 Feb 28 13:16 .rnd
drwxrwxr-x   2 root  operator   512 Jul 22 20:00 .snap
-r--r--r--   1 root  wheel     6201 Jan 16  2017 COPYRIGHT
drwxr-xr-x   2 root  wheel      512 Jul 22 20:16 back
drwxr-xr-x   2 root  wheel     1024 Jul 18 23:23 bin
drwxr-xr-x   8 root  wheel     1024 Jul 18 23:23 boot
dr-xr-xr-x   2 root  wheel      512 Jul 22 11:47 dev
-rw-------   1 root  wheel     4096 Jul 22 11:47 entropy
drwxr-xr-x  21 root  wheel     2048 Jul  7 15:10 etc
drwxr-xr-x   3 root  wheel     1536 May  5 14:22 lib
drwxr-xr-x   3 root  wheel      512 Feb 28 08:52 libexec
drwxr-xr-x   2 root  wheel      512 Jan 16  2017 media
drwxr-xr-x   2 root  wheel      512 Jan 16  2017 mnt
dr-xr-xr-x   2 root  wheel      512 Jan 16  2017 proc
drwxr-xr-x   2 root  wheel     2560 May  5 14:22 rescue
drwxr-xr-x   6 root  wheel      512 Jul 22 10:31 root
drwxr-xr-x   2 root  wheel     2560 Jan 16  2017 sbin
lrwxr-xr-x   1 root  wheel       11 Jan 16  2017 sys -> usr/src/sys
drwxrwxrwt   8 root  wheel      512 Jul 22 19:24 tmp
drwxr-xr-x  16 root  wheel      512 Jul 21 11:26 usr
drwxr-xr-x  24 root  wheel      512 Jul 22 11:47 var

Das automatische Backup

Der Server soll zu nachtschlafender Zeit automatisch ein Backup starten, wenn denn eine der Klon-Festplatten angeschlossen ist. Damit nicht versehentlich ein Backup auf eine falsche Platte aufgespielt wird, sind gewisse Tests zu durchlaufen:

  1. Überprüfen ob die Arbeitspartition und ihr Mount-Point korrekt sind.
  2. Überprüfen ob das GPT-Label der Backup-Partition existiert.
  3. Überprüfen ob die Backup-Partition nicht bereits in einen Mount-Point eingeklinkt worden ist.
  4. Einklinken der Backup-Partition in ihren Mount-Point und überprüfen ob es erfolgreich war.

Wenn die Tests bestanden wurden, dann darf der Backup-Befehl aufgerufen werden:
/usr/local/bin/clone -c rwoff -s -v0 -x .snap:.sujournal / /back

Die Option -c rwoff schaltet den Lese-/Schreib-Cache weitestgehend ab. Mit der Option -s wird der Synchronisationsmodus aktiviert, d.h. es werden nur neue/geänderte Daten und Verzeichnisse kopiert bzw. gelöscht. Mit -v0 werden alle Diagnosemeldungen unterdrückt, und mit -x .snap:.sujournal werden gewisse Metadaten vom Klonen ausgeschlossen. Die Tests und das Klonen erfolgen automatisch mit dem folgenden Shell-Script:

#!/bin/sh
#
#  Script für das automatische Backup
#
#  Usage: backup.sh LAP MPA LBP MPB
#
#    LAP ($1)  GPT-Label der Arbeitspartition   -- Beispiel: "server"
#    MPA ($2)  Mount-Point der Arbeitspartition -- Beispiel: "/"
#    LBP ($3)  GPT-Label der Backup-Partition   -- Beispiel: "BACK"
#    MPB ($4)  Mount-Point der Backup-Partion   -- Beispiel: "/back"
#

if [ "$1" != "" ] && [ "$2" != "" ] && [ "$3" != "" ] && [ "$4" != "" ] ; then

   date "+%Y-%m-%d %H:%M:%S %Z: Backup-Start..."

   # 1. Überprüfen ob die Arbeitspartition und ihr Mount-Point korrekt sind.
   LAP="$1"
   MPA=`echo "$2" | sed s:/:\\\\\\\/:g`
   atyp=`mount | sed -n "/\/dev\/gpt\/$LAP on $MPA (/{s///;s/, .*//;p;}"`

   if [ "$atyp" == "" ] ; then
      date "+%Y-%m-%d %H:%M:%S %Z: Abbruch - die Arbeitspartition und/oder ihr Mount-Point sind inkorrekt.%n"
      exit 1
   fi

   # 2. Überprüfen ob das GPT-Label der Backup-Partition existiert.
   LBP="$3"
   if ! [ -c "/dev/gpt/$LBP" ] ; then
      date "+%Y-%m-%d %H:%M:%S %Z: Abbruch - das GPT-Label der Backup-Partition ist nicht vorhanden.%n"
      exit 2
   fi

   # 3. Überprüfen ob die Backup-Partition bereits in einen Mount-Point eingeklinkt worden ist.
   btyp=`mount | sed -n "/\/dev\/gpt\/$LBP on .* (/{s///;s/, .*//;p;}"`
   if [ "$btyp" != "" ] ; then
      date "+%Y-%m-%d %H:%M:%S %Z: Abbruch - die Backup-Partition war bereits in einen Mount-Point eingeklinkt.%n"
      exit 3
   fi

   # 4. Einklinken der Backup-Partition in den angegebenen Mount-Point.
   mount -o noatime "/dev/gpt/$LBP" "$4"
   MPB=`echo "$4" | sed s:/:\\\\\\\/:g`
   btyp=`mount | sed -n "/\/dev\/gpt\/$LBP on $MPB (/{s///;s/, .*//;p;}"`
   # ... und überprüfen ob das Einklinken erfolgreich war.
   if [ $? -ne 0 ] || [ "$btyp" == "" ] ; then
      date "+%Y-%m-%d %H:%M:%S %Z: Abbruch - die Backup-Partition konnte nicht in ihren Mount-Point eingeklinkt werden.%n"
      exit 4
   fi

   /usr/local/bin/clone -c rwoff -s -v0 -x .snap:.sujournal $2 $4
   rc=$?
   if [ $rc -ne 0 ] ; then
      date "+%Y-%m-%d %H:%M:%S %Z: Backup-Ende - es sind $rc Fehler aufgetreten.%n"
   else
      date "+%Y-%m-%d %H:%M:%S %Z: Backup-Ende ohne Fehler.%n"
   fi
   umount $4

   exit $rc

else

   echo "Usage: $0 LAP MPA LBP MPB"
   exit -1

fi

Man erzeuge ein Verzeichnis config im Home-Verzeichnis des Users root:

mkdir /root/config

Das Backup-Script speichere man nun unter /root/config/backup.sh ab, und danach kann man es als cronjob in der Cron-Tabelle aufnehmen:

nano /etc/crontab

Darin den folgenden Eintrag anhängen:

...
#
# daily backup by cloning the working partition
10      3       *       *       *       root    /root/config/backup.sh server / BACK /back >> /var/log/backup.log

Damit wird des Nachts um 3:10 der Backup-Vorgang gestartet, wenn denn ein Backup-Laufwerk mit dem GPT-Label BACK angeschlossen ist und noch an keinem Mount-Point hängt. Wenn kein Backup-Laufwerk angeschlossen ist oder eine der anderen o.g. Voraussetzungen nich gegeben sind, dann wird nur eine kurze Meldung im Backup-Logbuch eingetragen, aber ansonsten passiert nichts weiter.

Da die Backup-Partition nur zum Backup in den vorbestimmten Mount-Point eingehängt und nach Backup sofort wieder mit umount /back ausgehängt wird, kann man die Klon-Festplatten ohne weiteres wechseln (ausser währende des Klonens, des Nachts ab 3:10 Uhr). Man schließt also tagsüber eine der Klon-Platten an, und klemmt sie am anderen Morgen einfach wieder ab, um sie ggf. durch eine andere Klon-Platte auszutauschen.

Copyright © Dr. Rolf Jansen - 2018-10-08 10:00:44

Diskussion auf Twitter: 1082830842039357440