Nachdem ich einige WordPress-Backup-Plugins, Provider-Backups, Snapshot-Backups und manuelle Ansätze für Website-Backup bzw. Webserver-Backup durchprobiert habe, hat sich ein Backup-Shell-Script als „Tool of the Trade“ herausgestellt.
Das Backup wird per SCP auf Remote-Speicher kopiert.
In meinem Fall ist das eine Hetzner Storage Box. Die Tarife dort bieten einen super Preis je GB und statt irgendwelchen Apps und Web-Oberflächen sind alle gängigen Protokolle (FTP, SCP, Samba usw.) inklusive.
Alternativ kann mit folgendem Backup-Script auch ein Backup-Space bei einem anderen Provider verwendet werden, sofern SSH bzw. SCP und die Einrichtung von SSH-Keys möglich ist.
Inhaltsverzeichnis
Backup-Shell-Script (SCP)
Generelles zum Backup-Script
Zum automatischen Backup wird ein Shell-Script eingesetzt, was auf den gängigen UNIX-basierten Systemen verwendet werden kann.
Das ist neben gängigen Linux-Distributionen (z.B. Ubuntu, RHEL, CentOS, Debian) z.B. auch Mac OS (dazu hier ein Mac OS Backup-Script im zweiten Absatz).
Das Backup-Script führt Dateien aus dem File-System in einem TAR-Archiv zusammen, verschlüsselt das Archiv (AES-256) und lädt es per SCP auf den Remote-Speicher hoch.
Statt ein vollständiges System-Abbild zu erzeugen, werden individuelle Projektdaten gesichert.
Das Recovery-Szenario basiert also auf dem Grundsatz, dass das System von Hand neu aufgesetzt wird und anschließend die Projektdaten wieder eingespielt werden.
Vorbereitung
RSA-Schlüsselpaar erzeugen (für Backup-Verschlüsselung)
Ein RSA-Schlüsselpaar ist auf einem Unix-basierten System (auch Mac OS) schnell erzeugt:
ssh-keygen -t rsa -b 4096 -f backup_key
An der Stelle empfiehlt es sich eine starke Passphrase zu vergeben, was zusätzliche Sicherheit im Falle eines Abhanden gekommenen privaten Schlüssels bietet.
Wir verwenden den öffentlichen Schlüssel anschließend dafür, das Keyfile für das Backup mit dem RSA Utility zu verschlüsseln.
Zunächst benötigen wir den Public-Key im PEM-Format, mit dem OpenSSL arbeiten kann.
openssl rsa -in backup_key -pubout -out backup_key.pub.pem
Um ein Backup-Archiv zu öffnen, wird später der private Schlüssel benötigt.
Der darf also nicht verloren gehen!
SSH-Keys für Backup Space einrichten (SCP ohne Passwort)
Wir kopieren das Backup später per SCP auf den Backup-Space.
Normalerweise öffnet SCP eine Passwort-Eingabe.
Bei einem Shell-Script (+ ggf. Cronjob) ist das ungünstig, da der Workflow dadurch unterbrochen wird.
Wir müssen dafür also SCP ohne Passwort einrichten.
Ich verwende eine Hetzner Storage Box, die es erlaubt, SSH-Schlüssel einzurichten.
Die Dokumentation im Hetzner Wiki beschreibt alle notwendigen Schritte.
Alternativ sollte z.B. auch HiDrive (Online-Speicher von Strato) inkl. Protokollpaket (Voraussetzung für SCP) in Frage kommen.
Ich habe es jedoch nicht probiert.
Die Einrichtung von einem SSH-Schlüssel für die Authentifizierung ohne Passwort scheint ebenfalls möglich zu sein (siehe Strato FAQ).
Ist der öffentliche Schlüssel auf dem Host-System eingerichtet, erfolgt via SCP keine Passwortabfrage mehr.
Verzeichnisse anlegen
Das Shell-Script, der öffentliche Schlüssel und die temporären Backup-Dateien können z.B. an folgendem Ort abgelegt werden (‚user‘ ersetzen).
mkdir -p /home/user/backup/{files,script}
Backup-Script für Linux (Use Case: Webserver-Backup)
Die erste Variante des Backup-Scripts ist für den Einsatz zum Backup von einer Webseite bzw. von einem Webserver (LAMP) gedacht.
In das Backup werden Webseite-Daten (Document-Root) und Datenbanken (MySQL) eingeschlossen.
Zunächst werden Variablen zu Dateinamen und Pfaden bestimmt.
TIME=$(date +"%Y-%m-%d-%H%M") PROJECT_NAME="mywebproject" FILE="$PROJECT_NAME-backup-$TIME.tar" KEYFILE="$PROJECT_NAME-key-$TIME.bin" BACKUP_DIR="/home/user/backup/files" SCRIPT_DIR="/home/user/backup/script"
Im nächsten Schritt wird das Document-Root-Verzeichnis zum Backup hinzugefügt.
WWW_DIR="/var/www/html" WWW_TRANSFORM='s,^var/www/html,www,' tar -cvf $BACKUP_DIR/$FILE --transform $WWW_TRANSFORM $WWW_DIR
Als nächstes wird eine MySQL-Datenbank zum Backup-Archiv hinzugefügt:
DB_USER="dbuser" DB_PASS="dbpass" DB_NAME="dbname" DB_FILE="$PROJECT_NAME-$TIME.sql" DB_TRANSFORM='s,^home/user/backup,database,' mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/$DB_FILE tar --append --file=$BACKUP_DIR/$FILE --transform $DB_TRANSFORM $BACKUP_DIR/$DB_FILE rm $BACKUP_DIR/$DB_FILE
Damit ist das Beispiel-Backup vollständig und kann für den Upload in den Remote-Speicher per SCP vorbereitet werden.
Vor dem Upload wird das TAR-Archiv mit GZIP komprimiert und AES-256 verschlüsselt.
Sollte der Backup-Speicher kompromittiert werden, kann ein Hacker mit den Backup-Daten so nur wenig anfangen.
Für die AES-256-Verschlüsselung vom Backup-Archiv eine zufällige Kette mit 128-Zeichen erzeugt, die als Schlüssel dient.
Nach der Verschlüsselung des Backup-Archivs wird der Schlüssel mit dem RSA-Utility und dem eigenen, öffentlichen Schlüssel verschlüsselt.
Anschließend erfolgt der Remote-Upload per SCP.
gzip -9 $BACKUP_DIR/$FILE openssl rand -base64 128 -out $BACKUP_DIR/$KEYFILE openssl enc -aes-256-cbc -salt -in $BACKUP_DIR/$FILE.gz -out $BACKUP_DIR/$FILE.gz.enc -pass file:$BACKUP_DIR/$KEYFILE openssl rsautl -encrypt -inkey $SCRIPT_DIR/backup_key.pub.pem -pubin -in $BACKUP_DIR/$KEYFILE -out $BACKUP_DIR/$KEYFILE.enc \rm $BACKUP_DIR/$FILE.gz \rm $BACKUP_DIR/$KEYFILE scp $BACKUP_DIR/* user@the-remote-server.de:/$PROJECT_NAME \rm $BACKUP_DIR/*
Backup automatisieren (Cronjob)
Wenn das Backup-Script fertig eingerichtet ist, geht die Automatisierung ganz einfach per Cronjob.
Folgender Cronjob führt das Backup jeden Montag um 3:30 Uhr in der Nacht aus:
30 3 * * 1 /home/user/backup/script/backup.sh
Backup-Script für MacOS (Use Case: persönliche Daten)
Das Shell-Script lässt sich ohne größere Anpassungen auch für das Backup unter Mac OS einsetzen.
Zuvor hatte ich einen Linux-Server als „inoffizielle“ Time Capsule für das Backup via Time Machine genutzt (siehe hier).
Die Lösung funktioniert, jedoch nur wenn die Internetverbindung sehr gut ist.
Das Shell-Script scheint mir unterm Strich solider zu sein.
Im Beispiel unten werden zwei Verzeichnisse in das Backup-Archiv eingeschlossen, das Archiv wird verschlüsselt und anschließend per SCP in den Backup-Space hochgeladen.
Kleine Einschränkung: TAR unterstützt unter Mac OS die TRANSFORM-Option nicht (Quelle).
Die Pfade im Archiv werden deshalb nicht verkürzt, wie es beim Shell-Script für den Linux-Webserver der Fall ist.
Hinweis: „Me“ durch Mac OS-Nutzernamen ersetzen.
#!/bin/bash TIME=$(date +"%Y-%m-%d-%H%M") PROJECT_NAME="mymac" FILE="$PROJECT_NAME-backup-$TIME.tar" KEYFILE="$PROJECT_NAME-key-$TIME.bin" BACKUP_DIR="/Users/Me/Backup/Files" SCRIPT_DIR="/Users/Me/Backup/Script" DOCS_DIR="/Users/Me/Documents" PICS_DIR="/Users/Me/Pictures" tar -cvf $BACKUP_DIR/$FILE $DOCS_DIR tar --append --file=$BACKUP_DIR/$FILE $PICS_DIR gzip -9 $BACKUP_DIR/$FILE openssl rand -base64 128 -out $BACKUP_DIR/$KEYFILE openssl enc -aes-256-cbc -salt -in $BACKUP_DIR/$FILE.gz -out $BACKUP_DIR/$FILE.gz.enc -pass file:$BACKUP_DIR/$KEYFILE openssl rsautl -encrypt -inkey $SCRIPT_DIR/backup_key.pub.pem -pubin -in $BACKUP_DIR/$KEYFILE -out $BACKUP_DIR/$KEYFILE.enc \rm $BACKUP_DIR/$FILE.gz \rm $BACKUP_DIR/$KEYFILE scp $BACKUP_DIR/* user@the-remote-server.de:/$PROJECT_NAME \rm $BACKUP_DIR/* exit 0
Recovery-Szenario
Kommt es zu einem Datenverlust, wird zuerst das jeweilige System neu aufgesetzt (z.B. Backup per Shell-Script (Linux + Mac) via SCP ohne Passwort auf Hetzner Storage BoxVPS, Dedicated Server oder Mac).
Anschließend kann das letzte Backup aus dem Cloud-Speicher heruntergeladen werden.
Wie folgt wird das Archiv entschlüsselt:
openssl rsautl -decrypt -inkey ~/.ssh/backup_key -in mywebproject-key-2017-01-01-0000.bin.enc -out mywebproject-key-2017-01-01-0000.bin openssl enc -d -aes-256-cbc -in mywebproject-backup-2017-01-01-0000.tar.gz.enc -out mywebproject-backup-2017-01-01-0000.tar.gz -pass file:mywebproject-key-2017-01-01-0000.bin
Wichtig: Der private Schlüssel (backup_key) ist zwingend notwendig, um die Backup-Archive wieder zu entschlüsseln. Geht der private Schlüssel verloren, ist das Backup wertlos.
Den privaten Schlüssel solltest Du deshalb unbedingt sicher (aber getrennt von den Backup-Daten) aufbewahren.