Backup Shell-Script SCP

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

Nachdem ich einige WordPress-Backup-Plugins, Provider-Backups, Snapshot-Backups und manuellen Ansätzen 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 eine Hetzner Storage Box kopiert. Gerade die großen Tarife (z.B. BX40) bieten ein super Preis je GB. Alternativ kann mit folgendem Backup-Script auch Backup-Space bei einem anderen Provider verwendet werden, sofern SSH 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 SCP ohne Passwort einrichten.

Ich verwende eine Hetzner Storage Box, die es erlaubt, öffentliche Schlüssel einzurichten. Die Beschreibung 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. Selber habe ich es 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 vom Backup-Script 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 vom Backup-Archiv 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 schnell 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). 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. Webserver VPS, Dedicated Server oder Mac OS MacBook).

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.

Veröffentlicht von Patrick

Hallo, ich bin Patrick. Hier blogge ich zu verschiedensten Technik-Themen.

Schreibe einen Kommentar

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

Ich stimme zu, dass meine Angaben und Daten zur Veröffentlichung des Kommentars gemäß Datenschutzerklärung elektronisch erhoben und gespeichert werden.