Tutorial | Server Backup mit Borg

von Thomas


Erstellt am 05.11.2020


CD USB-Stick Festplatte und externe Festplatte

Einführung

Zu jedem Server der im World Wide Web unterwegs ist gehört ein gutes Backup-System. Meins habe ich im Laufe diesen Jahres voll auf Borg umgestellt und genau das möchte ich euch in diesem Artikel näherbringen.

Borg

Borg hat den Vorteil, dass es nicht auf Dateiebene arbeitet. Das Backup-System zerlegt alle Daten in kleine sogenannte Chunks und ist somit sehr schnell. Für weitere genauere Informationen über das Chunking empfehle ich euch die Docs von Redhat. Nur nicht bekannte Chunks werden von Borg gespeichert. Gespeichert werden die Chunks in einem Repository, welches vor einem Backup-Prozess erzeugt werden muss. Aus dem Repository können bei einem Datenverlust ganze Ordnerstrukturen oder nur einzelne Dateien wiederhergestellt werden.

Ein weiterer Vorteil ist, dass Borg das Backup mit AES verschlüsseln kann. Das macht die gesicherten Daten sicherer vor dem Zugriff von Unberechtigten, denn ein Speichern auf einem entfernten Computer wird via ssh unterstützt.
Es gibt zu Borg keine GUI und kein Verwaltungstool. Das Programm ist voll auf die Kommandozeile ausgelegt und macht es so Linux Administratoren spielend einfach. Meist wird ein Backup-System somit über Skripte realisiert. Meine Skripte möchte ich in den nächsten Abschnitten nach einer kleinen Einführung mit euch teilen.

Erste Schritte mit Borg

Im Folgenden erstellen wir ein Repository und Backups. Diese Kommandos verwenden wir später um das Ganze automatisch mit einem Skript geschehen zu lassen.

Repository erstellen (borg init)

Um Daten zu sichern muss zunächst zwingend ein Repository angelegt werden. Das kann lokal oder auch auf einem entferntem Rechner via ssh entstehen.

lokal:

borg init --encryption=repokey /pfad/zum/backup/

remote:

borg init --encryption=repokey user@server.ip.oder.domain:/pfad/zum/backup/folder

Alternativ können die Daten auch unverschlüsselt gesichert werden. Dazu verwendet man bei encryption die Option none. Ich empfehle Backups aber immer verschlüsselt abzuspeichern.
Wichtig: Solltet ihr euch für die Verschlüsselungsmethode repokey entschieden haben, müsst ihr euren repokey auch aus dem Repository heraus abspeichern. Ohne diesen Key ist eine Wiederherstellung nicht möglich.

borg key export /pfad/zum/backup repokey

Backup erstellen (borg create)

Ein erstes Backup erstellt ihr mit folgendem Befehl:

borg create -v --stats /backup/::'{now:%Y-%m-%d_%H-%M}' /etc
Enter passphrase for key /backup:
Creating archive at "/backup/::{now:%Y-%m-%d_%H-%M}"
------------------------------------------------------------------------------
Archive name: 2020-11-03_17-16
Archive fingerprint: da1be0567875956fe88a52e302fd6f6586721e9016b373c01df7ec0c0f5f2b6d
Time (start): Tue, 2020-11-03 17:16:47
Time (end):   Tue, 2020-11-03 17:16:47
Duration: 0.04 seconds
Number of files: 47
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
This archive:              128.93 kB             51.96 kB             51.70 kB
All archives:              128.93 kB             51.96 kB             51.70 kB

                       Unique chunks         Total chunks
Chunk index:                      44                   46
------------------------------------------------------------------------------

Das Kommando erzeugt ein Backup in das Repository /backup/. Der Archive Name, immer hinter :: angegeben, und weitere Informationen sind durch die Optionen -v und - -stats gegeben. Die Angabe {now:%Y-%m-%d_%H-%M} erzeugt ein Datum mit Uhrzeit. Der Name des Archivs muss immer einzigartig sein. Daher ist es sinnvoll etwas wie ein Datumsformat zu verwenden. Theoretisch ist es aber auch möglich die Namen ab ::1 zählen zu lassen. Erzeugt man aber zwei Archive mit dem gleichen Namen, würde folgende Fehlermeldung erscheinen:

Creating archive at "/backup/::1"
Archive 1 already exists

Archive im Repository anzeigen (borg list)

Wollen wir herausfinden, welche Archive sich in einem Repository befinden, verwenden wir dazu das Kommando list.

borg list /backup/
Enter passphrase for key /backup:
2020-11-03_17-16                     Tue, 2020-11-03 17:16:47 [da1be0567875956fe88a52e302fd6f6586721e9016b373c01df7ec0c0f5f2b6d

Wiederherstellen von Daten (borg extract)

Wir können einzelne Dateien oder ganze Ordner aus dem Borg Backup wiederherstellen. Möchten wir z. B. die nginx Konfiguration aus /etc/nginx herstellen verwenden wir folgendes Kommando, dabei wird der Ordner in den aktuellen Pfad kopiert.

borg extract /backup/::1 etc/nginx

Backups löschen (borg prune / borg delete)

Es gibt zwei Möglichkeiten Archive zu löschen;
Einmal mit delete und einmal mit prune. Die Option prune ist jedoch dazu gedacht nach einem bestimmten Muster zu löschen. Dadurch ist es mit prune möglich z. B. jeweils ein Backup aus den vergangen sechs Monaten zu behalten – dazu später mehr. Mit delete können wir ggf. das komplette Repository löschen.

Löschen des Repository

borg delete -v --stats /backup/
Enter passphrase for key /backup:
You requested to completely DELETE the repository *including* all archives it contains:
2020-11-03_17-16                     Tue, 2020-11-03 17:16:47 [da1be0567875956fe88a52e302fd6f6586721e9016b373c01df7ec0c0f5f2b6d]
Type 'YES' if you understand this and want to continue: YES

Löschen eines Archivs

borg delete -v --stats /backup/::1
Enter passphrase for key /backup:
Deleting archive: 1 (1/1)
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
Deleted data:             -128.69 kB            -51.75 kB            -32.86 kB
All archives:              128.93 kB             51.96 kB             51.70 kB

                       Unique chunks         Total chunks
Chunk index:                      44                   46
------------------------------------------------------------------------------

Soweit so gut. Wir können nun ein Backup-Repository erstellen, Archive anlegen und bei Bedarf auch löschen. Nun kommen wir zu dem Teil, das alles zu automatisieren.

Automatische Borg-Backups mit Bash-Skripten

Wir werden nun zwei Skripte erstellen. Das Eine wird unsere Backups durchführen, das Andere ältere löschen. Im Folgenden sprechen wir von dem Backup-Skript, welches die Backups erstellt und von dem prune Skript, welches alte Backups aufräumt.
Die beiden Skripte können zu beliebigen Zeiten mit Cron ausgeführt werden. Ich werde mein Backup und prune Skript hier teilen und ausreichend kommentieren, sodass eine weitere Erläuterung hoffentlich nicht möglich ist.

Backup Skript

#!/bin/bash
## Damit das Passwort vom Repository nicht eingegeben werden muss
## kann es in einer Umgepungsvariable gesetzt werden
export BORG_PASSPHRASE="thisIsYourPassword"

##
## Setzten von Variablen.
## Das Log wird auf eine entsprechende Datei festgelegt.
## Der Backup_User wird nur beim Speichern auf einen entfernten Server
## via SSH benötigt
##

LOG="/var/log/borg/backup.log"

## OPTIONAL
BACKUP_USER="yourUser"
REPOSITORY_DIR="/backup/"
HOST=`hostname`

REPOSITORY=“${REPOSITORY_DIR}“
## OPTIONAL via SSH
## REPOSITORY="ssh://${BACKUP_USER}@yourServerNameOrIp:/${REPOSITORY_DIR}"

##
## Die Ausgabe von -v und - - stats soll in die Logdatei
## geschrieben werden
##

exec > >(tee -i ${LOG}.temp)
exec 2>&1

echo "#### Backup gestartet: $(date) ####"

##
## An dieser Stelle können verschiedene Aufgaben vor der
## Übertragung der Dateien ausgeführt werden, wie z.B.
##
## - Liste der installierten Software erstellen
## - Datenbank Dump erstellen
##

## OPTIONAL
## DBUSER="backup"
## DBPASSWD="yourPassword"
## DBBAKPATH="/path/to/db"

## DBS="DBName"

## for DBNAME in $DBS;
## do echo "Creating backup for database $DBNAME" && mysqldump -u $DBUSER -p$DBPASSWD ## $DBNAME > $DBBAKPATH"$DBNAME.sql";
## done

##
## Dateien ins Repository übertragen
## Gesichert werden hier beispielsweise die Ordner root, etc,
## var/www und home
##

borg create -v --stats                   \
    $REPOSITORY::'{now:%Y-%m-%d_%H-%M}'  \
    /root		\
    /var/www	\
    /etc		\
    /home
#    --exclude /var/lib/lxcfs

echo "#### Backup beendet: $(date) ####"

## OPTIONAL Admin benarichtigen
## mailx -a "From: "$HOST" Backup <"$HOST"@yourDomain.com>" -s "Backup  "$HOST your@mailAddressReciever.com < $LOG.temp

## Logs aufräumen; DB Dums löschen
cat ${LOG}.temp >> ${LOG}
rm ${LOG}.temp
rm ${DBBAKPATH}*.sql

Prune Skript

#!/bin/bash

## Damit das Passwort vom Repository nicht eingegeben werden muss
## kann es in einer Umgepungsvariable gesetzt werden
export BORG_PASSPHRASE="thisIsYourPassword"

## OPTIONAL
BACKUP_USER="yourUser"
REPOSITORY_DIR="/backup/"
HOST=`hostname`

REPOSITORY=“${REPOSITORY_DIR}“
## OPTIONAL via SSH
## REPOSITORY="ssh://${BACKUP_USER}@yourServerNameOrIp:/${REPOSITORY_DIR}"

# den output in das Logfile schreiben
exec > >(tee -i ${LOG})
exec 2>&1

echo "#### beginne pruning $(date) ####"

## Mit den keep Optionen werden die sieben letzten täglichen Backups,
## eins aus den jeweiligen letzten vier Wochen und eins der letzten sechs
## Monate behalten
borg prune -v $REPOSITORY \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=6

echo "#### pruning beendet ####"

Integrität prüfen

Auf ein weiteres Kommando mit Borg möchte noch eingehen – check. Es prüft die vorhanden Daten und Hashes auf Integrität.

borg check -v /backup/
Starting repository check
Starting repository index check
Completed repository check, no problems found.
Starting archive consistency check...
Enter passphrase for key /backup:
Analyzing archive 2020-11-03_17-16 (1/1)
Archive consistency check complete, no problems found.

Es sollte die Option -v verwendet werden, sodass der Prozess mitverfolgt werden kann.