Aufgabenstellung: Zu sichern ist ein Ubuntu Server (20.04), der bei einem Online Webhoster steht. Der Backup-Server ist ein lokal gehosteter Debian Server (11). Gesichert werden soll das komplette Dateisystem des Remote-Servers, bis auf die generischen Dateisysteme (/proc
; /sys;
/dev
; /run
und das Swapfile
, sofern vorhanden). Darüber hinaus soll auf dem Backup-Server eine Versionierung der Backups mit geeigneten Rotationsintervallen stattfinden.
Löungsansatz: Der Backup-Server synchronisiert täglich mit rsync
das Dateisystem des Remote-Servers in ein Verzeichnis current
auf ein btrfs
formatiertes Volume und speichert jeden Lauf als btrfs-Snapshot
ab. Somit steht je nach Rotationsschema für jeden Backuplauf ein Snapshot des Remote-Servers auf dem Backup-Server zur Verfügung. Sowohl rsync
wie auch btrfs
übertragen bzw. speichern nur die geänderten Daten auf den Backup-Server. Der Backup-Server soll die Verbindung zum Quell-Server aufbauen und nur während des Backups geöffnet lassen, damit bei einem kompromittierten Remote-Server die Daten auf dem Backup-Server nicht erreichbar sind.
Voraussetzungen: Folgende Voraussetzungen müssen für die Umsetzung des o.g. Lösungsansatzes erfüllt sein:
- Btrfs-Dateisystem auf dem Backup-Volume im Backup-Server.
- Der Remote-Server muss per SSH-Key-Authentication erreichbar sein.
- Root-Rechte auf dem Remote-Server.
1. Backup-Server Setup
Der für dieses Tutorial verwendete Backup Server ist ein Linux Debian 11 System.
1.1 Btrfs-Partition
Btrfs
ist ein modernes Copy-on-Write
(CoW) Dateisystem für Linux Systeme und implementiert erweiterte Features, wie z.B. das Erstellen inkrementeller Snapshots von Subvolumes
.
Empfehlenswert ist für das Speichern der Backups eine dedizierte btrfs
formatierte Partition. Das restliche Betriebssystem installiere ich persönlich auf ext4
formatierten Partitionen, um etwaigen Problemen mit btrfs
formatierten Boot-Partitionen aus dem Weg zu gehen.
Das Partitions-Layout auf dem Backup-Server stellt sich wie folgt dar:
# lsblk
NAME FSTYPE SIZE MOUNTPOINT
sda 200G
├─sda1 ext4 14G /
├─sda2 swap 1,9G [SWAP]
└─sda3 btrfs 184,2G /backup
1.2 Verzeichnis-Hirachie
Das btrfs-Dateisystem
bietet einen build-in Snapshot Support. Es können einzelne Verzeichnisse innerhalb eines btrfs
formatierten Dateisystems als Subvolumes definiert werden, deren Inhalt dann mit Snapshots separiert und gesichert werden können. Zum Anlegen eines btrfs-Subvolume
benutzen Sie das btrfs-Kommando
:
# btrfs subvolume create /backup/current
Das Verzeichnis welches die Snapshots abspeichern soll, kann ganz normal mit mkdir
anglegt werden. Im hier vorliegenden Fall wäre das dann noch /backup/snapshots
.
# ls -l /backup/
insgesamt 0
drwxr-xr-x 1 root root 258 28. Dez 2020 current
drwxr-xr-x 1 root root 0 23. Okt 00:07 snapshots
1.3 Kommandos und Skripte
Für das Backup und für die Snapshot Rotation werden zwei Kommandos benötigt, die im Folgenden näher beschrieben werden.
1.3.1 Rsync
Initial wird mit rsync
der gesamte Verzeichnisbaum des Remote-Servers in das Verzeichnis /backup/current
gesynct, im weiterem Verlauf wird das Delta inkrementell in das selbe Verzeichnis gesynct. Auf dem Remote-Server gelöschte Dateien werden auch im Backup gelöscht (--delete
), so dass im Verzeichnis /backup/current
nach der Synchronisation immer der aktuelle Stand des Remote-Servers abgebildet wird.
Der Schalter --numeric-ids
wird benutzt, um rsync anzuweisen die User- und Groupnames des Remote-Servers nicht mit denen des Backup-Servers zu ersetzen.
Die von der Synchronisation ausgeschlossenen Verzeichnisse werden in der Datei /root/orgfiles/exclude_dir.txt
gepflegt:
/proc/* /sys/* /dev/* /run/* /media/* /mnt/* /swapfile
Das vollständige Kommando zum Aufruf von rsync
:
rsync -avH --numeric-ids --delete --delete-excluded --exclude-from=/root/orgfiles/exclude_dir.txt root@[Remote_Server_IP_Address]:/ /backup/current/
1.3.2 btrfs
Zum Erstellen des Snapshots verwende ich ein fertiges Skript, welches auf Github heruntergeladen werden kann. Dieses Skript erstellt den btrfs-Snapshot
und rotiert die gewünschte Anzahl vorgehaltener Versionen durch. Das Skript wird mit folgenden Parametern zusammen mit dem oben erwähnten rsync-Kommando
in einem Skript ausgeführt.
btrfs-snap.sh -r -c -B $SNAPSHOT_DIR $MACHINE_DIR @$MACHINE 30
Der verwendete Parametersatz im einzelnen:
-r
: Erstellt den Snapshot read-only. Erfordert btrfs-tools v0.20.-c
: Formatiert den Namen des Snapshots-B $SNAPSHOT_DIR
: Speichert den Snapshot im angegebenen Verzeichnis, ohne weitere Verzeichnisse wie zB das aktuelle oder übergeordnete Verzeichnis.$MACHINE_DIR
: Das Remoteverzeichnis, welches zu sichern ist.@MACHINE
: Ein Identifier des Snapshot im Dateinamen30
: Anzahl der vorgehaltenen Versionen
1.3.3 Backup-Skript
Die Kommandos der beiden Skripte rsync
und btrfs
werden in einem Skript zusammengefasst und auf dem Backup Server regelmäßig ausgeführt:
#!/bin/bash MACHINE=185.216.xxx.xxx MACHINE_DIR=/backup/current_185.216.xxx.xxx/ SNAPSHOT_DIR=/backup/snapshots/ EXCLUDE_FILE=/root/orgfiles/exclude_dir.txt SCRIPT_DIR=/root/orgfiles/scripts # rsync server root from $MACHINE rsync -avzH --numeric-ids --delete --delete-excluded --exclude-from=$EXCLUDE_FILE root@$MACHINE:/ $MACHINE_DIR # Create btrfs-snaphot; keep 30 versions $SCRIPT_DIR/btrfs-snap.sh -r -c -B $SNAPSHOT_DIR $MACHINE_DIR @$MACHINE 30
1.4 Cron Konfiguration
Folgender Aufruf in der /etc/crontab
führt das Skript jeden Tag um 03:00 Uhr auf:
00 3 * * * root /root/orgfiles/scripts/backup_185.216.xxx.xxx.sh