Kontakt

Carsten Rieger IT Services
Am Danglfeld 8 | 83132 Pittenhart
Telefon: 08624.9009794
E-Mail: info@c-rieger.de

Nextcloud Borg-Backup zur Hetzner Storage Box

Als Ergänzung zum initialen Artikel Borg-Backup Ihrer Nextcloud zeigen wir Ihnen weitere Möglichkeiten zur Sicherung Ihres Servers und Ihrer Daten. Zu diesem Zweck zeigen wir anhand der Hetzner Storage Box die Remotesicherung mittels BORG-Software und SSH.

Borg-Manual: https://borgbackup.readthedocs.io/en/stable/
Borg-GIT: https://github.com/borgbackup

  1. Vorbereitungen
  2. BORG Repository initilalisieren
  3. Backup-Skript
  4. cron-Job
  5. Sicherungen anzeigen
  6. Sicherung(en) mounten
  7. Append-Only“-Modus

1. Vorbereitungen

Generieren Sie zuerst ein Schlüsselpaar auf Ihrem Server, um das Backup mittels Borg und cron vollautomatisiert durchführen zu können.

ssh-keygen -t ed25519 -C "BORG-StorageBox"

Bestätigen Sie den Namen mit der <Enter>-Taste

Enter file in which to save the key (/home/rieger/.ssh/id_ed25519):

und bestätigen auch die weiteren Dialoge mittels der <Enter>-Taste, also ohne eine Passphrase für den Key zu vergeben. Der gesamte Dialog sieht wie folgt aus:

rieger@server:~$ ssh-keygen -t ed25519 -C "BORG-StorageBox"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/rieger/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in id_ed25519
Your public key has been saved in id_ed25519.pub
The key fingerprint is:
SHA256:yv8mpolbxUjnbvmz2n46IBgR3KwoBpjPQSkTLw+aVGI BORG-StorageBox
The key's randomart image is:
+--[ED25519 256]--+
|oE.+.+           |
|B.= o o          |
|+*.o o. .        |
|+*+ o. =         |
|+..  o. S        |
|    ...+..       |
|      +.+.       |
|     o +oo+ .    |
|    o.ooo*B*     |
+----[SHA256]-----+
rieger@server:~$ 

Der öffentliche Teil des Schlüssels (id_ed25519.pub) muss nun auf die Storagebox übertragen werden. Dazu muss zum einen der .ssh-Ordner (.ssh) erzeugt und der Schlüssel in der authorized_keys-Datei (.ssh/authorized_keys) hinterlegt werden. Ersetzen Sie nachfolgend uxxxxx mit Ihren Daten, bspw. u123456.

ssh -p 23 uxxxxxx@uxxxxxx.your-storagebox.de mkdir .ssh

Übertragen Sie nun den öffentlichen Schlüssel zur StorageBox:

scp -P 23 .ssh/id_ed25519.pub uxxxxxx@uxxxxxx.your-storagebox.de:.ssh/authorized_keys

Die StorageBox bietet die Möglichkeit, mehrere Serverbackups zu verwalten, daher nutzen wir die Ablagestruktur mit dem Hauptordner backup und legen darunter je zu sicherndem Server einen Unterordner (bspw. cloud) an:

ssh -p 23 -i .ssh/id_ed25519 uxxxxxx@uxxxxxx.your-storagebox.de mkdir -p backup/cloud

2. Borg Repository initialisieren

Um das BORG Repository initialisieren zu können müssen zwei Variablen (BORG_RSH, BORG_PASSPHRASE) gesetzt werden. Bitte verwenden Sie dabei Ihre spezifischen Pfade und PassPhrases.

export BORG_RSH='ssh -i /home/<user>/.ssh/id_ed25519'
export BORG_PASSPHRASE="67f}.5o-sB5NQ{+r"

Im Anschluss können Sie das BORG Repository bereits initialisieren (anlegen):

borg init --encryption=repokey ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./backup/cloud

Der gesamte Dialog sieht wie folgt aus:

rieger@server:~$ export BORG_RSH='ssh -i /home/<user>/.ssh/id_ed25519'
rieger@server:~$ export BORG_PASSPHRASE="67f}.5o-sB5NQ{+r"
rieger@server:~$ borg init --encryption=repokey ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./backup/cloud
rieger@server:~$

3. Backup-Skript

Wir legen uns das Backup-Skript unter /root an und erstellen das Logverzeichnis für die Backup-Jobs.

sudo -s
touch /root/backup.sh && mkdir -p /var/log/borg /sicherung/sql /restore

Kopieren Sie den nachfolgenden Text in das Backup-Skript (für postgreSQL wählen Sie bitte den nachfolgenden Link aus den Codeberg-Quellen aus) und passen die rot markierten Platzhalter an Ihr System an.

nano /root/backup.sh

Quellen zum Kopieren des Backupskripts:
MariaDB: https://codeberg.org/criegerde/nextcloud/raw/branch/master/skripte/borg-remote-mariadb.sh
postgreSQL: https://codeberg.org/criegerde/nextcloud/raw/branch/master/skripte/borg-remote-psql.sh

Beispiel für MariaDB:

#!/usr/bin/env bash
#
# Nextcloud Sicherung: Hetzner-Storagebox
# Datenbanktyp: MariaDB
# 
###################################################################################################
export BORG_RSH='ssh -i /home/<user>/.ssh/id_ed25519'
# /home/<user>/.ssh/id_ed25519: Pfad zum privaten Schlüssel

export BORG_PASSPHRASE="SECRET-PASSPHRASE"
# SECRET-PASSPHRASE: Passphrase, mit dem das Repo erstellt wurde

VORNAME="Vorname"
# Vorname: Ihr Vorname

NACHNAME="Nachname"
# Nachname: Ihr Nachname

EMAIL="mail@domain.de"
# mail@domain.de: Ihre Emailadresse

NPATH="/var/www/nextcloud"
# NPATH: Pfad zur Nextlcoud-Software

WEBSERVER="nginx"
# WEBSERVER:  "nginx" oder "apache2"

PHPVERSION="8.2"
# PHPVERSION: "8.2" oder "8.1" oder "8.0"

BACKUP_USER="uxxxxxx"
# BACKUP_USER: Ihr Benutzer der Hetzner Storage Box

REPOSITORY_DIR="cloud"
# REPOSITORY_DIR: Der Name des BORG-Repositories

# »»» Ab hier bitte keine Änderungen mehr vornehmen »»»
sudo -u www-data php $NPATH/occ maintenance:mode --on
NEXTCLOUDDATEN=$(sudo -u www-data php $NPATH/occ config:system:get datadirectory)
NEXTCLOUDDB=$(sudo -u www-data php $NPATH/occ config:system:get dbname)
NEXTCLOUDDBUSER=$(sudo -u www-data php $NPATH/occ config:system:get dbuser)
NEXTCLOUDDBPASSWORD=$(sudo -u www-data php $NPATH/occ config:system:get dbpassword)
if [ ! -d "/var/log/borg" ]; then
  mkdir -p /var/log/borg
fi
if [ ! -d "/sicherung/sql" ]; then
  mkdir -p /sicherung/sql
fi
LOG="/var/log/borg/$(date +%y%m%d-%H%M)-backup.log"
REPOSITORY="ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./backup/${REPOSITORY_DIR}"
errorecho() { cat <<< "$@" 1>&2; }
exec > >(tee -i "${LOG}")
exec 2>&1
echo "###### Backup gestartet: $(date) ######"
echo ""
echo "Dienste werden gestoppt ..."
systemctl stop $WEBSERVER.service php$PHPVERSION-fpm.service redis-server.service
echo ""
echo "Datenbanksicherung wird erstellt ..."
mysqldump --single-transaction --routines -h localhost -u$NEXTCLOUDDBUSER -p$NEXTCLOUDDBPASSWORD -e $NEXTCLOUDDB > /sicherung/sql/nextcloud.sql
echo ""
echo "Datenbankgröße ermitteln ..."
mysql -u$NEXTCLOUDDBUSER -p$NEXTCLOUDDBPASSWORD -e "SELECT table_schema 'DB',round(sum(data_length+index_length)/1024/1024,2) 'Size (MB)' from information_schema.tables WHERE table_schema='$NEXTCLOUDDB';"
systemctl stop mariadb.service
echo ""
echo "Übertrage Dateien ..."
borg create -v --stats                   \
    $REPOSITORY::$(date +%y%m%d-%H%M)    \
    /root                                \
    /etc                                 \
    /var/www                             \
    /home                                \
    $NEXTCLOUDDATEN                      \
    /sicherung/sql                       \
    --exclude /backup                    \
    --exclude /dev                       \
    --exclude /proc                      \
    --exclude /sys                       \
    --exclude /var/run                   \
    --exclude /run                       \
    --exclude /lost+found                \
    --exclude /mnt                       \
    --exclude /var/lib/lxcfs
echo ""
borg prune --progress --stats $REPOSITORY --keep-within=7d --keep-weekly=4 --keep-monthly=6
echo ""
echo "Dienste werden gestartet ..."
systemctl restart mariadb.service redis-server.service php$PHPVERSION-fpm.service $WEBSERVER.service
echo ""
echo "Aufräumen ..."
rm -f /sicherung/sql/nextcloud.sql
sudo -u www-data php $NPATH/occ maintenance:mode --off
echo ""
echo "###### Backup beendet: $(date) ######"
mail -s "CLOUD-Backup" -a "FROM: $VORNAME $NACHNAME <$EMAIL>" $EMAIL < $LOG
exit 0
# (c) Carsten Rieger IT-Services
# https://www.c-rieger.de

Machen Sie das Skript ausführbar

chmod +x /root/backup.sh

und führen es erstmalig aus:

/root/backup.sh

Überprüfen Sie das Logfile unter /var/log/borg bspw. mittels

nano /var/log/borg/230113-1028-backup.log

Das Logfile sollte sich wie folgt darstellen:

Sind keine Fehler aufgetreten, so können Sie das automatische Backup per cronjob einrichten.

4. cron-Job

Um eine vollautomatische Sicherung einzurichten legen wir einen cron-Job an.

crontab -e

und fügen darin bspw. folgende Zeile ein:

6 2 * * * /root/backup.sh > /dev/null 2>&1

Somit würde das Backup jede Nacht um 02:06 Uhr starten. Die gesamte crontab sieht exemplarisch wie folgt aus:

5. Sicherungen anzeigen

Um sich die BORG-Sicherungen auflisten zu lassen können Sie sich ein Hilfeskript erstellen.

nano /root/borg-sicherungen.sh

Fügen Sie alle nachfolgenden Zeilen ein und ergänzen die rot markierten Parameter durch ihre Werte

#!/usr/bin/env bash

export BORG_RSH='ssh -i /home/<user>/.ssh/id_ed25519'
export BORG_PASSPHRASE="67f}.5o-sB5NQ{+r"
BACKUP_USER="uxxxxxx"
REPOSITORY_DIR="cloud"
echo "Sicherungen:"
borg list ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./backup/${REPOSITORY_DIR}
exit 0

Markieren Sie das Skript als ausführbar und starten es dann, die Ausgabe des Skripts

chmod +x /root/borg-sicherungen.sh && /root/borg-sicherungen.sh

könnte dann wie folgt aussehen:

6. Sicherung(en) mounten

Um einen Sicherungspunkt (bspw. 230420-1145) einzubinden, um Dateien wiederherstellen zu können, erstellen wir ein weiteres Hilfeskript:

nano /root/borg-restore.sh

Fügen Sie alle nachfolgenden Zeilen ein und ergänzen die rot markierten Parameter durch ihre Werte

#!/usr/bin/env bash
clear
export BORG_RSH='ssh -i /home/<user>/.ssh/id_ed25519'
export BORG_PASSPHRASE="67f}.5o-sB5NQ{+r"
BACKUP_USER="uxxxxxx"
REPOSITORY_DIR="cloud"
/root/borg-sicherungen.sh
echo ""
echo "-----------------------------------------"
echo "Welche Sicherung soll eingebunden werden?"
echo -n "Timestamp: "
read TIMESTAMP
echo "-----------------------------------------"
echo ""
borg mount ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./backup/${REPOSITORY_DIR}::$TIMESTAMP /restore
echo ""
echo "Das Backup wurde wie folgt eingebunden »» /restore:"
echo ""
ls -lsha /restore
echo ""
exit 0

Markieren Sie das Skript als ausführbar und starten es dann:

chmod +x /root/borg-restore.sh
/root/borg-restore.sh

Sie können sich die Daten der Sicherung umgehend anzeigen lassen (bspw. ls -lsha /restore/) und diese nach Bedarf aus dem Backup wieder herstellen:

Vergessen Sie nicht, vor der nächsten BORG-Sicherung, das /restore-Verzeichnis mittels umount zu trennen.

borg umount /restore

Weiterführende Links zur Hetzner Storage Box finden Sie hier.

7. „Append-Only“-Modus

Betrachtet man bei einer Datensicherungslösung den Fall, dass versierten Angreifern das Eindringen in ein beteiligtes System gelingt, so kann sowohl das Quellsystem, als auch das Zielsystem kompromittiert werden.

Um solchen Szenarien seitens der BORG-Software entgegen zu wirken wurde der sogenannte „Append-Only“-Modus implementiert. Backups können somit nur noch hinzugefügt, nicht aber verändert oder gelöscht werden. Um ältere Dateien der Sicherungen zu löschen, müsste man über einen separaten und als vertrauensvoll eingestuften Zugang am Backupserver agieren.

Da dieses Themenfeld sehr komplex ist verweisen wir an dieser Stelle auf die offizielle BORG-Doku.

Die Einrichtung eines BORG-Backups zur Hetzner Storage Box wurde erfolgreich abgeschlossen und so wünsche ich Ihnen viel Spaß mit Ihren gesicherten Daten und Ihrer privaten Nextcloud. Über Ihre Unterstützung (diese wird ordnungsgemäß versteuert!) würden sich meine Frau, meine Zwillinge und ich sehr freuen!