Intelligentes Skript für automatisiertes Backup der Clients im Lan vom Server aus

le0m

Cadet 4th Year
Registriert
Juni 2015
Beiträge
94
Hi,

ich möchte ein Skript für meinen Backup Server schreiben, mit dem alle Clients im LAN regelmäßig gesichert werden.

  • Der Backup Server ist ein Raspberry Pi 2 und läuft 24/7.
  • Der wichtigste Client ist ein Laptop, welches unregelmäßig bootet und unregelmäßig lange läuft. Die zu sichernde Partition ist mit Luks/dm verschlüsselt.
  • Ein weiterer Client ist ein Renderserver, der sehr selten und unregelmäßig bootet und auch unregelmäßig lange läuft.
Hier die Liste der Features, die die Backup-Lösung beinhalten soll:

  1. a) Der Server startet das Backup, wenn ein Client-Filesystem im LAN (NFS) verfügbar ist.
    b) Der Server startet das Backup NUR, wenn das Client-Filesystem aus 1a) bereits vom Client entschlüsselt wurde.
  2. Der Server startet das Backup NICHT, wenn der NFS mounting Point am selben Tag schon einmal komplett gesichert wurde.
  3. Der Server führt die Client-Backups nacheinander aus, falls mehrere Client-Filesystems im LAN (NFS) verfügbar sind.
  4. Bei den Backups handelt es sich um incremental Backups, die im Snapshot Verfahren gespeichert werden.
Vorweg:
Kennt jemand eine fertige Lösung für genau die Aufgabe? Dann bräuchte ich das Rad nicht neu erfinden, das wäre spitze!
Ich hab schon etwas gegoogelt und bis jetzt nichts gefunden, werde aber gleich noch weiter suchen.
Wenn das Skript am Ende was wird, dann poste ich es hier.

Welche Sprache?
Ich bin mir nicht sicher, ob ich das Skript in Python oder Bash schreiben soll. In Bash habe ich bis jetzt nur ein paar kleine Skripts geschrieben und fand die Sprache ziemlich unangenehm. Ich hab von mehreren Personen gehört, dass sie komplett auf Bash verzichten und an Stelle dessen Python verwenden. Meint ihr es macht Sinn, das Skript in Python zu schreiben? Rein sprachlich hätte ich auch mehr Bock auf Python..

Zu 1)
a) Ich hätte die Filesystems der Clients, welche gesichert werden sollen per NFS exportiert. Der Server könnte diese dann mounten und die Backups lokal starten.
Ich frage mich, wie man hier am besten triggert. Ich hätte gesagt, der Server schaut stündlich, ob ein Rechner im LAN verfügbar ist. Wenn einer verfügbar ist, müsste er irgendwie überprüfen, ob die NFS Exports verfügbar sind. Wenn ein NFS verfügbar ist würde er mit 1b) weiter machen.
b)Ich vermute, dass ein Problem durch die Verschlüsselung mancher Client Partitionen hinzukommt. Wenn z.B. ein Client bootet, ohne die Partition zu entschlüsseln, dann wäre er im LAN verfügbar und sein NFS Export wäre auch verfügbar, allerdings nur als leerer Ordner. Der Server dürfte das Backup in dem Fall nicht starten. Es müsste also noch eine Validierung stattfinden. Z.B. könnte der Server noch prüfen, ob der NFS Export leer ist oder Ähnliches.

Zu 2)
Ich denke am einfachsten wäre es eine .txt File anzulegen, in welcher der Server notiert, welche Filesystems wann gesichert wurden. Allerdings wäre ich dafür auf ein Feedback von Rsync angewiesen. Wenn ich von Rsync eine Nachricht bekomme, ob der Task abgeschlossen wurde, könnte ich diese Info mit dem entsprechenden Timestamp in die Txt schreiben.
Hier sind weitere Probleme denkbar:
1) Was ist wenn ein Backup länger läuft als 1Std.?
2) Was ist wenn ein Backup länger läuft als 24Std.?
Eine Mehrfachausführung muss verhindert werden.

Zu 3)
Das ist wichtig, weil der Raspberry Pi sonst schnell überlastet wäre. Ich denke auch hier wäre wie in 2) ein Feedback von rsync nötig, um zu wissen, wann das nächste Backup starten darf. Oder das Script müsste irgendwie überprüfen, ob der Vorherige Prozess noch aktiv ist oder Ähnliches.

Zu 4)
Die Backups sollen im Snapshot Verfahren erstellt werden, damit ich am Ende verschiedene Zeitpunkte eines Backups abrufen kann. Dabei werden Ordner für jeden Snapshot bzw. Zeitpunkt angelegt. Alle Dateien, die sich nicht verändert haben, werden einfach als Hardlink kopiert. Auf die Weise bekommt man mehere Snapshots, ohne großen Bedarf and Festplattenspeicher..
Für die Umsetzung könnte ich mich auf diese Herangehensweise berufen:
http://www.mikerubel.org/computers/rsync_snapshots/

Am Ende soll das Backup in etwa so aussehen:

daily.0
daily.1
daily.2
weelkly.0
weelkly.1
weelkly.2
monthly.0
monthly.1
monthly.3
yearly.0
yearly.1
yearly.3


Ich würde mich über Tipps und Ratschläge sehr freuen! :-)
 
Wieso soll der Backupserver das Backup starten? Im Falle des Pi ist dieses Gerät das langsamste System und um die Hashes der zu sicherenden Dateien zu prüfen muss der Backupserver den ganzen Netzwerkoverhead in Kauf nehmen, anstatt, dass der Client das lokal macht. Abgesehen davon, dass ein Raspi elend langsam ist, wenn er über Ethernet welches per USB angeschlossen ist gleichzeitig noch auf einen USB Speicher zugreifen muss.

Daher Vorschlag: Lass die Clients ihr Backup anstoßen und prüfen, ob ihre Dateien neuer sind als das was der Backupserver vorhält. Eine extrem simple Lösung ist da: deja-dub (gui) bzw. duplicity (terminal)
 
Es wäre einfacher, wenn die Clients auch etwas beitragen, ist das gar keine Option? Einfachster Weg wäre, die Cients beim Runterfahren per Rsync auf den Server kopieren zu lassen. Der prüft einmal am Tag auf Änderungen und erstellt bei Bedarf eine neues Backup. Ansonsten könnten die Clients auch auf Netzlaufwerken arbeiten, falls das eine Option ist, oder ihre Daten über Seafile / Owncloud auf den Server packen. So wären auch alle Sicherungen vom gleichen Zeitpunkt am Tag und nicht wild verteilt, je nachdem wann der Server mal den Client gefunden hat.

Ich wollte dir eigentlich noch ein tolles Tutorial zu Snapshots mit Rsync verlinken, bis ich gesehen hab, dass du das schon kennst. Ich hab damit nur gute Erfahrungen gemacht, hält besonders die Festplattenlast schön niedrig.
 
Wieso soll der Backupserver das Backup starten?
Kurz gesagt, mein Wunsch ist es möglichst alles was mit "Backup" und "File serving" zu tun hat von den Clients zu trennen.

Aus meiner Sicht gehört das Backup nicht in den Aufgabenbereich eines Clients. Meine Clients haben ihre eigenen Aufgaben. Der Pi ist einzig und allein für die Aufgabe gedacht Daten zu sichern und Daten bereit zu stellen. Ich möchte alles was mit diesen Aufgaben zu tun hat dort konfigurieren und verwalten. Ich versuche einen möglichst modularen Ansatz zu erreichen. Das hat den Vorteil, dass das Backupsystem als Modul unabhängig von den restlichen Systemen läuft. Dem Backup-Server ist es dann egal, ob auf einem Client ein neues OS installiert oder neue Hardware konfiguriert wurde oder was auch immer mit einem Client alles geschehen kann. Alles was der Server braucht ist eine Ordnerfreigabe, wie die zu stande kommt ist dem Server dann egal, solange er das lesen kann, was er mountet.
Ich hoffe auf die Weise eine Backup Lösung zu finden, die über Jahre hinweg mit geringstem Einschreiten läuft. Der Pi soll mir wöchentlich eine Übersicht per Mail schicken und damit ist dann erst mal ruhe für die nächsten 10 Jahre was das Thema Backup angeht.. hoffentlich ;-)

Im Falle des Pi ist dieses Gerät das langsamste System und um die Hashes der zu sicherenden Dateien zu prüfen muss der Backupserver den ganzen Netzwerkoverhead in Kauf nehmen, anstatt, dass der Client das lokal macht. Abgesehen davon, dass ein Raspi elend langsam ist, wenn er über Ethernet welches per USB angeschlossen ist gleichzeitig noch auf einen USB Speicher zugreifen muss.

Bis jetzt konnte ich keinen Unterschied beim Kopieren von Files im Wlan feststellen, egal wer rsync startet. Ich habe einen 4GB Sample Ordner mehrmals auf beide Weisen kopiert. Manchmal war die eine schneller als die andere und manchmal umgekehrt. Die Schwankungen im Wlan verfälschen den Test… Vielleicht werde ich es noch mal mit größeren Mengen testen. Unabhängig davon scheint der Performance Unterschied nicht so groß zu sein, als dass ich dafür auf die modulare Herangehensweise verzichten würde.
Die ~10MB/s die der Pi momentan bei Copy über Wlan macht reichen mir. Der soll ruhig arbeiten. Mit 10MB/s wird er schon hinterher kommen. Selbst wenn er eine 100GB große VM sichern müsste, wäre er damit in 2-3 Std. durch.. und wie oft passiert das schon. Normalerweise produziere ich am Tag viel weniger.

Es wäre einfacher, wenn die Clients auch etwas beitragen, ist das gar keine Option?
Ja, aber so kompliziert ist es anders herum auch nicht.

Die Validierung hab ich fertig.

Zu 1a)
Hier pingt der Server einfach den Client an und guckt ob er antwortet.

Zu 1b)
Hier ist mir eine einfache aber effektive und sichere Lösung eingefallen. Jede Freigabe die gesichert werden soll, muss im obersten Verzeichnis eine File mit dem namen ".backup_valid" beinhalten. Der Server guckt einfach ob er sie findet. Wenn er sie findet weiß er, dass das Drive entschlüsselt wurde und das Filesystem bereit ist für das Backup.

Hier der bisjetzige Zustand:

https://github.com/feluxe/very-hungry-backup/blob/master/very-hungry-backup.sh

Code:
#!/bin/bash
#
# le0m's Very Hungry Backup
# ----------------------------------------------------------------------
# The basic idea is to run an incremental backup of all specified clients in
# a lan. The clients do only share the content which has to be saved.
# ----------------------------------------------------------------------

# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/bin/touch;

RSYNC=/usr/bin/rsync;

# ------------- Main Vars -----------------------------------------

SOURCE_MACHINE_IP="IP";
SOURCE_MOUNTING_POINT="PATH";
SOURCE_VALIDATION_FILE="PATH"

# ------------- the script itself --------------------------------------

# Check if source machine is online.

if ! ping -c 3 $SOURCE_MACHINE_IP &> /dev/null; then
  echo "Source machine is NOT available"
  exit 1
fi

# Check if source is correct filesystem

FS_CHECK=$(df -P -T $SOURCE_MOUNTING_POINT | tail -n +2 | awk '{print $2}')

if ! [ "$FS_CHECK" == "nfs4" ]; then
	echo "NFS mounting point is not nfs4 file system."
	exit 1
fi

# Check if source contains validation file.

if ! [ -f "$SOURCE_VALIDATION_FILE" ]; then
	echo "Validation file not found."
	exit 1
fi

# Make sure we're running as correct user.
if (( `$ID -u` != 2000 )); then
	echo "Sorry, wrong user executing this script."
	exit 1 
fi

echo "Validation complete..."
echo "Starting backup..."
 
Da die Geräte wohl meist per DHCP mit IPs versorgt werden würde ich versuchen über eine DNS Abfrage herauszubekommen, welche IP die Geräte gerade haben.

Anstatt zu warten, dass ein verschlüsseltes Filesystem vom Nutzer entschlüsselt wird, würde ich per sshfs einfach das Filesystem mounten. Schön per puplic key auth und SSH Server auf den Clients (Login per user:login deaktiviert, damit man in fremden Netzwerken nicht sinnlos BruteForce Angriffen ausgesetzt wird). Dann muss sich der Nutzer nicht lokal angemeldet sein, damit das Backup loslegen kann.

Die Clients sollten irgendwie prüfen können, wie lang das letzte Backup zurückliegt und den Nutzer damit belästigen wenn Zeitraum X überschritten wurde.

Den ganzen Spaß den du machen willst gibt es echt schon: duplicity (ja, ist eine Wiederholung)
 
Danke für die Infos!

Da die Geräte wohl meist per DHCP mit IPs versorgt werden würde ich versuchen über eine DNS Abfrage herauszubekommen, welche IP die Geräte gerade haben.
Über die Fritzbox lassen sich feste IPs für alle Netzwerkgeräte vergeben. Die Fritzbox verwendet dafür die MAC-Adressen der Geräte. So gesehen ist DNS nicht mehr notwendig.

Anstatt zu warten, dass ein verschlüsseltes Filesystem vom Nutzer entschlüsselt wird, würde ich per sshfs einfach das Filesystem mounten.
Mein Ursprüngliche Idee war es SSH zu verwenden. Ich hab mich dann für NFS entschieden, weil ich die Transfer-Verschlüsselung von SSH im Home-Lan nicht benötige. Die Übertragungs-Geschwindigkeit von SSH ist gegenüber der von NFS deutlich schlechter. Ich denke NFS ist für das File Shareing in reinen Linux Netzwerken eine sehr gute Wahl. Sonst wäre der Ansatz per sshfs aber sehr praktisch, da gebe ich dir recht! Schon allein durch die saubere Validierung der Client Filesystems durch die Keyfiles.

Dann muss sich der Nutzer nicht lokal angemeldet sein, damit das Backup loslegen kann.
Der User muss sich anmelden, um seine Partitionen zu entschlüsseln, sonst kann der Backup-Server nichts mounten. Das müsste unter sshfs genauso geschehen.

Die Clients sollten irgendwie prüfen können, wie lang das letzte Backup zurückliegt und den Nutzer damit belästigen wenn Zeitraum X überschritten wurde.
Ich stelle den Backup Server so ein, dass er die Clients jede Stunde anpingt. Wenn er einen Client findet und das FS valide ist, startet er das Incremental Backup (siehe Script). Der User muss sich um gar nichts mehr kümmern. Er muss lediglich im Lan sein und seine Festplatte entschlüsseln.

Um zu verhindern, dass der Server mehrfach die gleichen Backups startet oder gleichzeitig mehrere Clients sichert und sich selbst überlastet, könnte ich einfach prüfen, ob rsync bereits läuft. Solange eine Instanz von rsync läuft wird keine weitere gestartet.

Den ganzen Spaß den du machen willst gibt es echt schon: duplicity (ja, ist eine Wiederholung)

Duplicity backs directories by producing encrypted tar-format volumes and uploading them to a remote or local file server. Because duplicity uses librsync, the incremental archives are space efficient and only record the parts of files that have changed since the last backup. Because duplicity uses GnuPG to encrypt and/or sign these archives, they will be safe from spying and/or modification by the server.

Ich hab die Website von duplicity zwei mal überflogen aber konnte nicht wirklich feststellen, in wie weit es mein Vorhaben erleichtert.

backs directories by producing encrypted tar-format volumes
Ich brauche keine "encrypted tar-format" Backups.

... and uploading them to a remote or local file server.
Die Backups sollen nicht auf dem Client gemacht und anschließend auf einen Server geladen werden. Der Backup-Server soll sich um die Backups kümmern. Die Clients stellen nur die FS bereit, die gesichert werden sollen.

Because duplicity uses librsync, the incremental archives are space efficient and only record the parts of files that have changed since the last backup.
Das macht rsync auch. librsync und rsync sind praktisch das selbe.
 
Zuletzt bearbeitet:
Zurück
Oben