Backup
Code

Backup per Shell-Script (Linux + Mac) via SCP ohne Passwort auf Hetzner Storage Box

Bild: Depositphotos.com / © REDPIXEL

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.

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.

Patrick Woessner

Ich bin Patrick und hier blogge ich zu verschiedenen Themen rund um Technik, Gadgets und mehr. Früher hatte ich gleich mehrere Blogs zu diesem Thema. Mittlerweile steht Tech Junkies im Mittelpunkt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert