Hinweis: Dieser Artikel ist älter als 3 Jahre
Inhalte, Quelltexte oder Links können zwischenzeitlich überholt sein.
Hinweis: Dieser Artikel ist älter als 3 Jahre
Inhalte, Quelltexte oder Links können zwischenzeitlich überholt sein.
Eine Nextcloud-Instanz zu installieren ist schnell erledigt. Es gibt zahlreiche Tutorials und bei besseren NAS-Systemen oder Hosting-Anbietern sogar fertige Appliances zum eleganten Zusammenklicken. Bei der Datensicherung erschöpfen sich meiner Beobachtung nach die Quellen und die wenigen Anleitungen im Netz würde ich eher nicht verwenden.
Dieser Blog-Beitrag möchte helfen, den Datenschutz mit einer automatisierten, täglichen und vollständigen Sicherung für die eigene Nextcloud zu erhöhen. Zielgruppe sind private Betreiber. Dabei soll nicht das Skript im Vordergrund stehen, sondern viel mehr die Gedanken und Abwägungen drum herum.
Angefangen mit Bare-Metal-Sicherungen ganzer Server oder Partitionen, tar, rsync oder borg für vollständige oder inkrementielle Datensicherungen bis hin zu 7zip für verschlüsselte Datenweitergaben an Dritte, gibt es zahlreiche Sicherungslösungen. Und das sind nur einige freie Lösungen. Von den vielen unfreien Lösungen wie Acronis, Veeam & Co will ich gar nicht erst anfangen.
Meine Ideallösung eines Sicherungskonzeptes sieht nicht nur eines, sondern mehrere, ineinandergreifende Tools vor. Für die Ansprüche und Datenmengen in meiner Nextcloud-Instanz habe ich mich für GNU tar entschieden. Die Gründe:
Das Sicherungsziel ist eine SMB-Netzwerkfreigabe auf einem anderen Rechner, in meinem Fall ein FreeNAS. Das Skript geht davon aus, das diese Freigabe direkt erreicht werden kann. Wer seine Nextcloud in abgetrennten Netzwerksegmenten betreibt, muss diese direkte Verbindungsmöglichkeit in Firewall und/oder Routingtabellen eingerichtet haben.
Geschrieben ist alles auch aus der Debian-Perspektive. Bei Anwendung auf die verschiedenen Derivate ist dies bitte zu berücksichtigen. Gestartet und nachher als cronjob ausgeführt wird das Script unter dem Nutzer root. Ein sudo gibt es von Haus aus nicht auf einem frisch installierten Debian-Server und sollte daher, zusammen mit dem cifs-utls, installiert werden:
# apt install cifs-utils sudo
Ferner setze ich einen funktionierenden Mailserver voraus, der Statusmeldungen mit “sendmail” verschicken kann. Zum Überprüfen, ob dieser richtig eingerichtet ist und E-Mails auch wirklich versendet, reicht der nachfolgende Einzeiler an die eigene E-Mail-Adresse. Wenn alles funktioniert sollte eine leere E-Mail im Postfach landen:
# sendmail "email@domain.tld" < /dev/null
Desweiteren setze ich voraus, dass die mySQL/MariaDB Datenbank und das Nextcloud /data Verzeichnis auf dem gleichen Host liegen. Was das /data Verzeichnis betrifft, bitte auch den Abschnitt unter “Optimierungen” lesen.
Der überwiegende Teil meiner Daten liegt auf einer FreeNAS und wird als “Externer Speicher” eingebunden. Das hält die Nextcloud relativ schlank. Wir reden, in meinem Beispiel, von “nur” 31 GB an zu sichernden Daten, die in ca. 30 Minuten gesichert werden. Eine akzeptable Downtime der Nextcloud, die während der vollständigen Sicherung in den Wartungsmodus gesetzt wird und während dessen nicht nutzbar ist.
Aus der Vogelperspektive betrachtet existieren grundsätzlich zwei Strategien für Datensicherungen: Push- und Pull-Sicherungen.
Bei einem Push-Backup verbindet sich der zu sichernde Host mit einem meist zentralen Sicherungsserver und kopiert seine Daten dorthin. Der Umkehrfall wird als Pull-Backup bezeichnet. Hier verbindet sich ein zentraler Sicherungsserver mit dem zu sichernden Host und zieht sich die Daten nach einer zuvor fest vorgegebenen Logik.
Oberflächlich betrachtet erscheint ein Pull-Backup sicherer. Praktisch ist die Situation etwas komplizierter. Hier einige Faktoren, die gegen eine Pull-Backup-Strategie sprechen:
Wie so oft ist es eine Abwägung zwischen Vor- und Nachteilen und auch anhand der bestehenden Begebenheiten.
Das hier gezeigte Skript arbeitet mit der Push-Strategie, d.h. die Nextcloud mounted einen SMB-Share, kopiert die Daten und unmountet diesen anschließend wieder.
Neben dem Umstand, dass tar keine Verschlüsselung anbietet ist aus anderen Gründen eine Verschlüsselung in unserem Szenario unerwünscht:
Verschlüsselt werden sollten Daten nach Möglichkeit nur dort, wo ein Übergang oder Transport von der eigenen, sicheren Umgebung in eine unsichere erfolgt (z.B. bei Hinterlegung von Backups auf Festplatten bei Dritten).
Die zum Mounten der SMB-Netzwerkfreigabe benötigten Zugangsdaten werden in einer Textdatei im Root-Homeverzeichnis abgelegt. Unerreichbar für andere Benutzer. Der Name dieser Datei ist frei wählbar, wir benennen diese “.smbcredentials”. Der Inhalt besteht nur aus drei Textzeilen, in denen die Zugangsdaten zu hinterlegen sind:
username=
password=
domain=
Mit mysqldump werden wir auch ein vollständiges Backup der Nextcloud-Datenbank machen und benötigen auch die Zugangsdaten hierfür. Daher sind in der Datei “.my.cnf” im Root-Homeverzeichnis zu hinterlegen. Dieser Dateiname ist vorgegeben und muss exakt so übernommen werden.
[mysqldump]
user=
password=
Damit das SMB-Netzwerklaufwerk eingehängt werden kann, braucht es noch einen geeigneten Ordner. Das Skript erwartet diesen im Homeverzeichnis von Root unter /root. Dort erstellt Ihr bitte einfach einen Unterordner mit dem Namen “backup”.
# mkdir /root/backup
Sind die Zugangsdaten hinterlegt, kann es mit dem Skript losgehen.
Mit einem Texteditor der freien Wahl wird eine Textdatei mit dem Namen “backupscript” im Root-Homeverzeichnis erstellt und der nachfolgende Inhalt in dieser eingesetzt.
Das Skript besteht aus zwei Teilen. In der ersten Hälfte werden alle benötigten Parameter gesetzt und sind dem eigenen Anwendungsfall anzupassen.
Die zweite Hälfte beinhaltet das eigentliche Skript. Hier sollte nach Möglichkeit nichts verändert werden. Zum besseren Verständnis habe ich jede Zeile einzeln kommentiert.
Zwei wichtige Hinweise: Am Ende des Skriptes erfolgt ein Aufräumvorgang. Dabei werden die im Root-Homeverzeichnis erstellten temporären Dateien wieder entfernt. Wer die Logdatei benötigt muß das Script entsprechend anpassen.
Es erfolgt auch keine Überprüfung des verfügbaren Speicherplatzes auf dem Ziellaufwerk. Ich gehe davon aus, dass dieses von Zeit zu Zeit überprüft und bereinigt wird.
#!/bin/bash
# Datum Praefix vor den Dateinamen YYYYMMDD
DATE_PREFIX=$(date +%Y%m%d)
# SMB-Netzwerklaufwerk
SMB_DIR="//remotehost/share"
# Mountingpoint vom SMB Netzwerklaufwerkes
MOUNT_DIR="/root/backup"
# SMB Credentials Datei für die SMB Zugangsdaten
SMB_CRED_FILE="/root/.smbcredentials"
# Das Nextcloud Verzeichnis
NEXTCLOUD_DIR="/var/www/cloud.domain.tld"
# Der Datenbankname
NEXTCLOUD_DB=nextcloud
# Name und Ablageort der Statusdatei YYYYMMDD-backuplog.txt
THE_LOG="/root/$DATE_PREFIX-backuplog.txt"
# Name und Ablageort des Datenbank Dumps
THE_DUMP="/root/$DATE_PREFIX-cloud-DB.sql"
# Empfänger der Statusdatei
SEND_REP="email@domain.tld"
# Exclude Dateien oder Ordner
EXCLUDE_PATTERN="--exclude='$NEXTCLOUD_DIR/data/updater*' --exclude='$NEXTCLOUD_DIR/data/*.log'"
# -- Bitte ab hier nichts mehr manuell anpassen --
# Erstellen der Statusdatei und Hinterlegung der Startzeit
echo "Beginne Backup (Startzeit: $(date +%T))..." > $THE_LOG
# SMB Laufwerk mounten
mount -t cifs -o credentials=$SMB_CRED_FILE $SMB_DIR $MOUNT_DIR
# Wartungsmodus der Nextcluod aktivieren
sudo -u www-data php $NEXTCLOUD_DIR/occ maintenance:mode --on
# Erstellen mysql Dump
mysqldump $NEXTCLOUD_DB > $THE_DUMP
# Alles in das Zielverzeichnis mit tar sichern
tar $EXCLUDE_PATTERN -cvpf "$MOUNT_DIR/$DATE_PREFIX-cloud.tar" $NEXTCLOUD_DIR $THE_DUMP
# Wartungsmodus deaktivieren
sudo -u www-data php $NEXTCLOUD_DIR/occ maintenance:mode --off
# Zielverzeichnis prüfen, Stopzeit festhalten
echo "...Backup beendet (Stopzeit: $(date +%T))" >> $THE_LOG
ls -lh $MOUNT_DIR >> $THE_LOG
# Statusdatei senden
sendmail $SEND_REP < $THE_LOG
# Garbagge Collection
rm $THE_LOG $THE_DUMP &
umount $MOUNT_DIR
Ist die Datei erstellt, muss diese noch ausführbar gemacht werden:
# chmod +x /root/backupscript
Das war’s! Das Skript kann jetzt manuell oder automatisiert z.B. mit crontab nachts oder an Wochenenden gestartet werden. Einzige Voraussetzung: Es muss als root gestartet werden.
Abhängig von Anzahl der Benutzer und Menge der Daten kann eine Sicherung längere Zeit in Anspruch nehmen. Da das Skript bewusst immer vollständige Sicherungen ausführt, beinhaltet es einige kleine aber feine Optimierungen:
Die erste Optimierungsmöglichkeit besteht aus dem Auslassen der in der Regel sehr grossen Log-Dateien. Auch das Updater-Verzeichnis mit den Sicherungen vergangener Versionen kann getrost ausgelassen werden. Aus diesem Grund existiert die EXCLUDE_PATTERN-Zeile:
EXCLUDE_PATTERN="--exclude='$NEXTCLOUD_DATA_DIR/updater*' --exclude='$NEXTCLOUD_DATA_DIR/*.log'"
Eine weitere Optimierungsmöglichkeit wäre das vorherige Löschen des Papierkorbs aller Benutzer. Ich habe es nicht in das Skript aufgenommen. Wer aber möchte, der kann bei Bedarf zwischen dem Einschalten des Wartungsmodus und dem Erstellen der Datenbank-Dumps diese Zeile einfügen:
sudo -u www-data php $NEXTCLOUD_DIR/occ trashbin:cleanup --all-users
Das Skript sichert ohne Kompression damit die Downtime möglichst gering gehalten wird. Wem diese egal ist und mehr Wert auf möglichst kleine, komprimierte Sicherungsdateien legt, der kann die -j Option (für bzip2) aktivieren und die Dateierweiterung ergänzen:
tar $EXCLUDE_PATTERN -cvjpf "$MOUNT_DIR/$DATE_PREFIX-cloud.tar.bz2" $NEXTCLOUD_DIR $THE_DUMP
In meinem Fall lohnt sich eine Kompression nicht, da der Benefit nur bei ca. 5% (2 GB) an gewonnenem Speicherplatz liegt, dafür aber eine 4x längere Sicherungszeit kostet (2h anstelle 30 Min). Your milage may vary und es gibt neben bzip natürlich weitere Kompressionsverfahren in mit unterschiedlichen Kompressionsstärken und Geschwindigkeiten.
Den grössten Vorteil, nicht nur bei der Sicherheit, sondern auch hinsichtlich Performance, erzielt man durch die die richtige Lage des /data-Verzeichnisses. Dieses sollte nach Möglichkeit ausserhalb des Nextcloud-Ordners liegen. Idealerweise auf einer anderen Festplatte.
Das Skript geht vom Nextcloud-Installationsdefault ohne verschobenes /data Verzeichnis aus. Wer dieses woanders liegen hat, muss das Skript um eine zusätzliche Variable NEXTCLOUD_DATA_DIR ergänzen:
# Das Nextcloud /data Verzeichnis
NEXTCLOUD_DATA_DIR="/var/data"
Die Ausnahmeliste muss mit der neuen Variable wie folgt verändert werden:
# Exclude Dateien oder Ordner
EXCLUDE_PATTERN="--exclude='$NEXTCLOUD_DATA_DIR/updater*' --exclude='$NEXTCLOUD_DATA_DIR/*.log'"
Und zuletzt muss natürlich die tar-Zeile um das zusätzlich zu sichernde Verzeichnis ergänzt werden:
# Alles in das Zielverzeichnis mit tar sichern
tar $EXCLUDE_PATTERN -cvpf "$MOUNT_DIR/$DATE_PREFIX-cloud.tar" "$NEXTCLOUD_DIR" "$NEXTCLOUD_DATA_DIR" $THE_DUMP
Was ist der Unterschied zwischen
mysqldump $NEXTCLOUD_DB > $THE_DUMP
und
mysqldump $NEXTCLOUD_DB > $THE_DUMP &
Normalerweise werden Anweisungen in Bashskripten nacheinander abgearbeitet. Durch das kaufmännische “&"-Zeichen am Ende der Zeile, wird der Befehl im Hintergrund und damit parallel zum Skript abgearbeitet. Je nach Größe der Datenbank spart man ein paar Minuten Laufzeit.
Das kann gemacht werden, wenn sicher ist, dass die Sicherungszeit der Datenbank kürzer als die der Verzeichnisse ist. In der Regel sollte dies gegeben sein, ich empfehle hier aber ein vorheriges, manuelles Überprüfen.
Für Verantwortungslosigkeit gibt es kein Mitleid und noch weniger eine Entschuldigung. Erst Recht nicht wenn es sich dabei um eine gemeinsam mit anderen genutzte Nextcloud handelt. Auch wenn wir von einer privaten “Familiencloud” reden, so stellt diese in der Regel einen wichtigen Bestandteil des persönlichen Lebens dar, mit allen Bildern, Chats und dem gemeinsamen Datenpool von wichtigen Dokumenten bis hin zu gemeinsamen Erinnerungen.
Dieser Blog-Beitrag zeigt: Eine vollständige und automatisierte Sicherung ist kein Hexenwerk.
In diesem Sinne, viel Spaß und Erfolg!