Dies ist die archivierte Version des Blogs vom 05.01.2017. Aktuelle Beiträge findest du unter thomas-leister.de
 

Meine Server-Backups mache ich seit vorgestern über das Tool rdiff-backup, das bereits in den Repositories größerer Linux-Distributionen liegt. Rdiff-backup kann inkrementelle Backups von lokalen oder entfernten Quellen anlegen und verfügt über eine Delta-Synchronisierung, d.h. nur geänderte Bereiche einer Datei werden tatsächlich übertragen. Das macht rdiff-backup besonders effizient und damit zum idealen Werkzeug für Server-Backups.

Zuhause betreibe ich einen kleinen Server, der sich täglich die aktuellen Daten von den Servern im RZ herunterladen soll. Auf dem Server habe ich einen neuen user „serverbackup“ angelegt, unter dem die Backup-Prozesse laufen sollen. Als Home-Directory bekommt der User ein Verzeichnis auf einem großen Software-RAID:

# mkdir /storage/serverbackups
# adduser --home /storage/serverbackups --disabled-password serverbackup
# chown serverbackup:serverbackup /storage/serverbackups

Als serverbackup-User habe ich mich angemeldet und einen SSH-Schlüssel generiert:

# sudo -i -u serverbackup
$ ssh-keygen

Mit dem erzeugten Schlüssel wird sich der serverbackup-User später zu jedem Server verbinden und sämtliche Daten herunterladen können. Um Zugriff auf alle Daten des Servers zu haben, ist es erforderlich, dass sich der Backupserver als root an zu sichernden Server anmeldet (dazu später mehr).

Den Public Key des SSH-Schlüssels habe ich mir zunächst auf den eigenen Rechner kopiert und dann auf den Server („server1“) übertragen, dessen Daten abgesichert werden sollen:

scp root@backupserver:/storage/serverbackups/.ssh/id_rsa.pub /tmp
scp /tmp/id_rsa.pub root@server1:/root/

Auf „server1“ dann:

# cat id_rsa >> .ssh/authorized_keys

Zurück auf dem Backupserver kann die Verbindung dann getestet werden (die erste Verbindung zu einem neuen Server muss bestätigt werden)

$ ssh root@server1

Das Tool rdiff-backup muss auf Backup-Server und den zu sichernden Servern installiert werden:

apt install rdiff-backup

Theoretisch könnte an dieser Stelle bereits ein Daten-Backup des Servers angelegt werden (auf dem Backup-Server, eingeloggt als serverbackup-user):

$ rdiff-backup root@server1::/var/www /storage/serverbackups/server1/www

(achtet auf die zwei Doppelpunkte!) Das Kommando würde das /var/www/ Verzeichnis des Servers auf dem Backup-Server unter /storage/serverbackups/server1/www absichern. Das war für mich allerdings noch nicht ausreichend: Teilweise verfügen meine Server auch über MySQL-Datenbanken, deren Dumps ebenfalls gesichert werden sollen. Bevor eine Sicherung des Dateisystems erstellt wird, muss zunächst ein Dump aller Datenbanken generiert werden.

Auf jedem Server mit MySQL-Datenbank befindet sich daher unter /root/backup/ ein Skript „dbdump.sh“, das von den genannten Datenbanken je einen Dump in /root/backups/dbdumps/ erstellt.

Das Skript:

#!/bin/bash

DBUSER="backup"
DBPASSWD="passwort"
DBBAKPATH="/root/backup/dbdumps/"

DBS="owncloud vmail"

for DBNAME in $DBS; do echo "Creating backup for database $DBNAME" && mysqldump -u $DBUSER -p$DBPASSWD $DBNAME > $DBBAKPATH"$DBNAME.sql"; done

Die zu sichernden Datenbanken werden durch ein Leerzeichen getrennt in „DBS“ aufgelistet. Außerdem wird für die DB-Dumps ein eigener MySQL-user „backup“ genutzt, den ich so angelegt habe:

# mysql -u root -p
create user 'backup'@'localhost' identified by 'passwort';
grant select, show view, reload, replication client, event, trigger, lock tables on *.* to 'backup'@'localhost';
quit;

Das Skript wird unter „/root/backup/dbdump.sh“ abgespeichert und ausführbar gemacht. Außerdem wird das Verzeichnis „dbdumps“ erstellt, in dem die fertigen Dumps abgespeichert werden:

# chmod u+x /root/backup/dbdump.sh
# mkdir /root/backup/dbdumps

Nun zurück zum Backup-Server. Auch hier habe ich ein kleines Skript unter „/storage/serverbackups/backup.sh“ erstellt, das auf dem Server (server1) zuerst die DB-Dumps erstellt und dann alle Daten mit rdiff-backup herunterlädt:

#!/bin/bash

ROOTDIR="/storage/serverbackup/server1/"
LOG=${ROOTDIR}backup.log

# copy script output to logfile
exec > >(tee -i ${LOG})
exec 2>&1

echo "###### Backup on $(date) ######"

# Create DB dumps at remote server before copying them
echo "###### Creating DB dump ######"
ssh root@server1 'dbdump'

echo "###### Downloading files from server ######" 
rdiff-backup root@server1::/root/backup/dbdumps ${ROOTDIR}dbdumps
rdiff-backup root@server1::/var/www ${ROOTDIR}www


# Remove old versions (older than 1 month)
echo "###### Removing old versions ######"
rdiff-backup --remove-older-than 1M ${ROOTDIR}dbdumps
rdiff-backup --remove-older-than 1M ${ROOTDIR}www

echo "###### Backup Finished! ######"

Das Verzeichnis „server1“ muss vor dem ersten backup natürlich noch angelegt werden:

$ mkdir ~/server1

Nachdem die DB-Dumps erzeugt wurden und die Daten aus /root/backup/dbdumps und /var/www heruntergeladen wurden, werden alte Backup-Versionen entfernt. Euch fällt vielleicht auf, dass beim dumpen der Datenbanken das Kommando „dbdump“ via ssh auf dem entfernten Server ausgeführt wird. Das Kommando gibt es noch nicht, aber wir führen das jetzt ein – zusammen mit einem Mechanismus, der für mehr Sicherheit sorgt. Damit der Backup-Server sämtliche Daten auf server1 lesen kann, habe ich ihm root-Rechte gegeben. Das hat den Nachteil, dass bei einem gekaperten Backup-Server auch alle anderen Server betroffen sind, zu denen der Backup-User vollen Zugriff hatte. Das sollte man so nicht stehen lassen; deshalb werden nun Zugangsbeschränkungen eingeführt.

In der Datei /root/.ssh/authorized_keys, in die zu Beginn der Public Key vom User „serverbackup“ kopiert wurde, kann mittels

command="date" ssh-rsa AAAAB3NzaC1yc2EAAA [...]  serverbackup@backupserver

… beispielsweise festgelegt werden, dass der Besitzer des Keys AAAAB […] nur das Kommando „date“ ausführen darf. Ein Kommando ist in meinem Fall allerdings zu wenig – schließlich will ich zwei Kommandos ausführen können: dbdump und rdiff-backup (das wird automatisch auch auf dem Server ausgeführt). Leider kann in „command“ nur ein einziges Kommando angegeben werden, sodass an dieser Stelle ein kleiner Trick nötig ist. Für command= wird ein kleines Script angegeben:

command="/bin/bash /root/backup/backup-commands.sh" ssh-rsa [...]

In dem genannten Skript wiederum findet eine Überprüfung des gesendeten Kommandos statt: Ist das vom SSH-Client gesendete Kommando bekannt, wird es ausgeführt – andernfalls nicht. Der Inhalt dieses Skripts lautet wie folgt:

#!/bin/bash 

case $SSH_ORIGINAL_COMMAND in
   "dbdump")
       /bin/bash /root/backup/dbdump.sh
       ;;
   "rdiff-backup --server")
       rdiff-backup --server --restrict-read-only /
       ;;
   *)
       echo "Unknown command"
esac

Als gültige Kommandos werden „dbdump“ (das führt dann letztendlich /root/backup/dbdump.sh aus) und „rdiff-backup –server“ zugelassen (welches dann ein rdiff-backup –server –restrict-read-only / ausführt). Gleichzeitig werden durch die Option „–restrict-read-only“ Schreibzugriffe durch rdiff-backup verhindert.

Ein Backup anlegen

Um ein Backup von server1 anzulegen, genügt es, auf dem Backup-Server einfach das Skript „backup.sh“ auszuführen: (ggf. vorher ausführbar machen: chmod u+x backup.sh)

$ ./backup.sh

Ein Cron-Job führt das Skript jede Nacht um 1:00 Uhr aus:

$ crontab -e

Zeile hinzufügen:

0 1 * * * /bin/bash ~/backup.sh > /dev/null 2>&1

… und fertig ist der Backup-Server.


Post published on 23. Februar 2016 | Last updated on 23. Februar 2016
Tags:           

Diesen Blog unterstützen

Wenn Dir der Beitrag gefallen hat, freue ich mich über einen kleinen Obolus :-) Bitcoin QR Code

PayPal-Seite: https://www.paypal.me/ThomasLeister
Meine Bitcoin-Adresse: 15z8 QkNi dHsx q9WW d8nx W9XU hsdf Qe5B 4s

Siehe auch: Unterstützung

Informationen zum Autor

Thomas Leister

Geb. 1995, Kurzhaar-Metaller, Geek und Blogger. Nutzt seit Anfang 2013 ausschließlich Linux auf Desktop und Servern. Student der Automobilinformatik an der Hochschule für angewandte Wissenschaften in Landshut.

9 thoughts on “Serverbackups (Dateisystem + MySQL) mit rdiff-backup

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.