[font="Tahoma, sans-serif"]Hallo, hier möchte ich euch mein (inzwischen) kleines Projekt vorstellen.[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]1. Hintergrund[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]1.1 Gegebenheiten[/font]
[font="Tahoma, sans-serif"]Ich habe ein Heimnetz mit 7 Windows - Rechnern, einen RPi3 als Fileserver mit 1,5 TB mit Samba hinter einer Fritz.Box und Benutzer die auch mal unüberlegt klicken. Glücklicher Weise bisher ohne größere Schäden. Das war auch Ausgangspunkt der Idee.[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]1.2 Entwicklung der Idee[/font]
[font="Tahoma, sans-serif"]Systeme wiederherstellen nach Virusbefall ist nervig und zeitraubend aber überschaubar. Anders sieht es bei Ransomware aus. Wenn einer die Maleware runtergeladen hat, werden alle Daten verschlüsselt, inkl. aller Filme, Videos und Fotos die halt auch unwiederbringlich sind. Einzig durch Backups kann man sich zurzeit schützen. Backups sind aber auch nervig, besonders wenn man sie immer wieder manuell durchführen muss, denn automatische Backups werden gleich mit verschlüsselt, - dachte ich. [/font]
[font="Tahoma, sans-serif"]Deshalb war meine erste Idee über den Pi per GPIO eine Steckdose zu schalten, die eine Externe Festplatte für den Backup Prozess einschaltet und danach wieder abschaltet (nach dem unmount). Denn eine nicht laufende Platte kann nicht verschlüsselt werden, so der Gedanke. Damit wollte ich das abkoppeln der externen Festplatte ersetzen. [/font]
[font="Tahoma, sans-serif"]Als nächstes musste ich mich um einen effektiven Vierenschutz für den Pi kümmern, damit nicht auch der Pi angegriffen oder infiziert wird. Denn ich wusste, es gibt inzwischen auch schon einige Vieren für Linux. Das Finden eines effektiven Vierenschutzes gestaltete sich schwieriger als gedacht, nein es war/ist unmöglich...[/font]
[font="Tahoma, sans-serif"]Bei der Recherche und dem lesen in den Foren musste ich feststellen, dass es eigentlich keine Vierenschutzsoftware für den PI gibt, denn der Pi ist (noch) immun gegen Viren (weitestgehend).[/font][font="Tahoma, sans-serif"] Ich hoffe ich führe das jetzt richtig aus: [/font][font="Tahoma, sans-serif"]Die meiste Schadsoftware wird auf Machinenebene programmiert, d.h. sie läuft nur auf bestimmten Prozessorfamilien in Verbindung mit bestimmten Betriebssystemen (Intel & AMD => Windows oder Linux). Da sich aber (bisher) keiner für die ARM Prozessoren interessiert hat, weil die PIs in ihrer Nutzung, Konfiguration und Installation zu heterogen sind und nicht unbedingt einen konventionellen Internetzugang (über Browser) haben oder nutzen, ist es wohl auch kein lohnendes Angriffsziel.[/font]
[font="Tahoma, sans-serif"]Damit schrumpften rapide die Anforderungen an das Projekt. Denn wenn der PI nicht angreifbar ist und somit unsichtbar für Schadsoftware, dann ist auch eine Platte, die nur der PI kennt auch sicher vor der Schadsoftware. Somit kann ich mir auch das Abkoppeln der Platte sparen. Also klemmte ich noch eine große Platte an den PI und suchte nach einer Backupmöglichkeit. Es war klar das es ein Inkrementellbackup sein müsste, denn bei einer Spiegelung oder Update Prozess, hätte der PI die verschlüsselten Dateien gleich mitgespiegelt. Mit dem incremental backup würde zwar das Script im Falle einer Vollverschlüsselung inkrementell ein quasi Vollbackup machen, da alle Dateien verändert wurden, aber die unverschlüsselten Daten stehen mir weiter zur Verfügung durch die Vorangegangenen Backups.[/font]
[font="Tahoma, sans-serif"]Als ich dann unter https://wiki.ubuntuusers.de/Skripte/inkrementelles_Backup/ ein Backupscript gefunden hatte, das alles in allem auch ganz gut funktionierte, war das Projekt als Projekt zunächst gestorben.[/font]
[font="Tahoma, sans-serif"]Das änderte sich als ich die ersten Performance-Daten sah. Durch den USB2.0 und auch möglicherweise durch die Prozessorleistung braucht der PI 1 Stunde um 10 GB zu sichern, das heißt 150 Stunden bzw. mehr als 6 Tage bei 1.5TB. Bei einem täglichen Backup müsste immer wieder bei den rotierenden Vollbackups manuell eingreifen, den cronjob löschen usw. Also auch wieder nicht vollautomatisch. Dazu kam dann noch das mein PI eine Leerlauftemperatur von 48°C hatte und beim Backup-Prozess auf 65°C stieg. Sobald ein zweiter Backup Prozess dazu kam stieg die Temperatur auf 79°C in spitzen bis 81°C. Das bedeutete wenn ich mal das manuelle Abschalten des cronjobs vergesse und er wärend des Backups (6Tage) ein 3. Mal startet grille ich meinen PI. (Um das Temperaturproblem habe ich mich nebenbei auch gekümmert (siehe unten ... kommt noch).)[/font]
[font="Tahoma, sans-serif"]So ist folgende Script entstanden basierend auf dem oben genannten.[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]2. Das Script[/font]
[font="Tahoma, sans-serif"]2.1 Was kann das Script?[/font]
[font="Tahoma, sans-serif"]- täglich aktuelle Backups mit überschaubaren Laufzeiten[/font]
[font="Tahoma, sans-serif"]- Kaskadierendes Vollbackup einer Platte "beliebiger" Größe mit [/font]
[font="Tahoma, sans-serif"]- inkrementell Backup über einen einstellbaren Zeitraum mit[/font]
[font="Tahoma, sans-serif"]- anschließendem wegsichern der Sicherung und erneutes Vollbackup.[/font]
[font="Tahoma, sans-serif"]- Interne Mail mit Backup Report[/font]
[font="Tahoma, sans-serif"]- Backup chain[/font]
[font="Tahoma, sans-serif"]- Kompression des Archivs[/font]
[font="Tahoma, sans-serif"]- "Loadkontrolle" [/font]
[font="Tahoma, sans-serif"]- einfach einstellbar[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]2.2 Was kann das Script (noch) NICHT?[/font]
[font="Tahoma, sans-serif"]- prüfen, ob genug Platz auf der Backupplatte ist.[/font]
[font="Tahoma, sans-serif"]- löschen der überholten Bachups.[/font]
[font="Tahoma, sans-serif"]- kontrollieren ob bereits eine Instanz des Scripts läuft.[/font]
[font="Tahoma, sans-serif"]- den Report an eine externe eMail Adresse senden.[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]2.3 Funktionsweise[/font]
[font="Tahoma, sans-serif"]Es ist mein erstes Bash Script, deshalb bitte ich um Nachsicht, wenn zum Beispiel das Quoting oder andere Syntax nicht optimal ist. Außerdem nochmal der Hinweis das es auf einem Script von [font="Tahoma, sans-serif"] [/font][font="Tahoma, sans-serif"]https://wiki.ubuntuusers.de/Skripte/inkrementelles_Backup/[/font][font="Tahoma, sans-serif"] basiert.[/font][/font]
[font="Tahoma, sans-serif"][font="Tahoma, sans-serif"]Gedacht ist das Script für den täglichen Gebrauch, einzutragen in der crontab. Damit gehen einem nur die Änderungen und neuen Dateien maximal der letzten 24 Stunden verloren.[/font][/font]
[font="Tahoma, sans-serif"]Im Einstellungsbereich werden in zwei Arrays die Verzeichnisse, die einzeln gesichert werden sollen und die Tage bis zum nächsten Vollbackup abgelegt. Die Arrays werden nacheinander abgearbeitet. Das heißt die erste Zahl bezieht sich auf das erste Verzeichnis. Wenn keine Zahl eingetragen ist (wie bei meinen letzten 3 Verzeichnissen) wird das Defaultvalue genommen. Somit kann man bei den Benutzerverzeichnissen ein monatliches Vollbackup anstoßen, während Videos (ich mache da nicht so viele) jedes halbe Jahr komplett gesichert werden und somit die Deltas und das alte Vollbackup überflüssig werden. [/font]
[font="Tahoma, sans-serif"]Bei den Verzeichnissen kann man auch als letzten Eintrag ein "" eintragen, dann wird das komplette Ober- bzw. Elternverzeichnis gesichert OHNE die bereits gesicherten Verzeichnisse aus dem Array.[/font]
[font="Tahoma, sans-serif"]Eine Schleife arbeitet die Arrays ab und erstellt aus den RAW-Verzeichnissen die Verzeichnisse die es benötigt. Wenn das Verzeichnis leer ist wird ein Vollbackup gemacht ist. Wenn die Anzahl der Tage erreicht ist wird der gesamte Backupordner verschoben und ein neues Backup wird erstellt.[/font]
[font="Tahoma, sans-serif"]Das Script überprüft ob bereits ein Vollbackup durchgeführt wurde um die Gesamtlaufzeit des Scriptes überschaubar zu halten. [/font]
[font="Tahoma, sans-serif"]Wenn bereits ein Vollbackup durchgeführt wurde, wird trotz Erreichen der Maximaltage ein weiteres Inkrementellbackup gemacht.[/font]
[font="Tahoma, sans-serif"]Wenn noch gar kein Backup erstellt wurde wird dieses Backup für diesen Tag übersprungen. Das bedeutet, dass dieses Script auch beim ersten Start vollautomatisch funktioniert.[/font]
[font="Tahoma, sans-serif"]Beispiel:[/font]
[font="Tahoma, sans-serif"]1. Tag: 1.Verz. Vollbackup, 2. Verz. kein, 3. Verz. kein, 4. Verz. kein …[/font]
[font="Tahoma, sans-serif"]2. Tag: 1.Verz. inkr.backup, 2. Verz. Vollbackup, 3. Verz. kein, 4. Verz. kein …[/font]
[font="Tahoma, sans-serif"]3. Tag: 1.Verz. inkr.backup, 2. Verz. inkr.backup, 3. Verz. Vollbackup, 4. Verz. kein …[/font]
[font="Tahoma, sans-serif"]4. Tag: 1.Verz. inkr.backup, 2. Verz. inkr.backup, 3. Verz. inkr.backup, 4. Verz. Vollbackup …[/font]
[font="Tahoma, sans-serif"]5. Tag: 1.Verz. inkr.backup, 2. Verz. inkr.backup, 3. Verz. inkr.backup, 4. Verz. inkr.backup …[/font]
[font="Tahoma, sans-serif"]Deshalb sollte man vermeiden ein Verzeichnis mit mehr als 200-250 GB am Stück zu sichern, denn das dauert ca. 20 Stunden und würde so in den nächsten Start des Scriptes laufen.[/font]
[font="Tahoma, sans-serif"]Beim ersten Start des Scriptes bedeutet das, dass es zunächst entsprechend viele Durchläufe/Tage bedarf bis alle Verzeichnisse im Arrey ihr erstes Vollbackup erhalten haben. Danach ist nie wieder ein Teil ungesichert.[/font]
[font="Tahoma, sans-serif"]Die wichtigsten Ereignisse werden als Report am Ende an den eingetragen User geschickt.[/font]
[font="Tahoma, sans-serif"] [/font]
[font="Tahoma, sans-serif"]2.4 Das Script[/font]
(ich habe PHP-Code genommen damit wenigstens ein bischen Syntaxhighlighting ist)
[code=php]#!/bin/bash
# Script fuer inkrementelles Backup mit 30 taegigem Vollbackup
#################### >>>>>>>>>>>>>>>>>>>> Customizing Area <<<<<<<<<<<<<<<<<<<< ############################################################
### Einstellungen ## ##
MAILUSER="root" ## User der die Backupreports bekommen soll
RAWSOURCE="media/usbhdd1" ## Stammverzeichnis (oder Laufwerk) das gesichert werden soll
RAWBACKUPDIR="media/usbBackUp/backup" ## Backupverzeichnis (oder Laufwerk) mit Namensprefix für die Unterordner (hier backup)
TYPES=("TV" "Videos" "Bilder" "Musik" "Archive" "Benutzer" "Downloads" "") ## Inhalt der Backups bzw. Unterordner des Stammverzeichnis die separt gesichert werden sollen. ("" = Gesamtes Stammverzeichnis ohne Unterverzeichnisse, wenn soll(te) es immer am Ende stehen)
DEFAULTDAYS=30 ## Standard an "Tagen" bis zum nächsten Vollbackup
DAYS=( 180 180 90 90 720 ) ## Differenziert "Tage" pro Unterordner (siehe Types) bis zum nächsten Vollbackup
## wenn DAYS auskommentiert ist wird immer DEFAULTDAYS genommen (hier bekommen die letzten 3 die DEFAULTDAYS)
#################### >>>>>>>>>>>>>>>>>> Customizing Area Ende <<<<<<<<<<<<<<<<< ############################################################
MSG="Hallo Admin,\n\n"
FFBU="false" ##FFBU ist das first-full-backup Flag das gesetzt wird wenn das erste Vollbackup gelaufen ist, damit nicht alle Vollbackups an einem Tag laufen
i=-1
for TYPE in "${TYPES[@]}"
do
((i++))
if [ "${TYPE}" = "" ]
then
TYPE2=""
SOURCE="${RAWSOURCE}" ## Verzeichnis(se) welche(s) gesichert werden soll(en)
EXCLUDE="${EXCLUDETEMP}"
else
TYPE2="-${TYPE}"
SOURCE="${RAWSOURCE}/${TYPE}" ## Verzeichnis(se) welche(s) gesichert werden soll(en)
EXCLUDETEMP="$EXCLUDETEMP--exclude=${RAWSOURCE}/${TYPE} "
fi
BACKUPDIR="${RAWBACKUPDIR}${TYPE2}" ## Pfad zum Backupverzeichnis
ROTATEDIR="${RAWBACKUPDIR}${TYPE2}/rotate" ## Pfad wo die Backups nach 30 Tagen konserviert werden
TIMESTAMP="timestamp.dat" ## Zeitstempel
DATUM="$(date +%d-%m-%Y)" ## Datumsformat einstellen
ZEIT="$(date +%H.%M)" ## Zeitformat einstellen
if [ -z "${DAYS[$i]}" ]
then
DAYS[$i]=$DEFAULTDAYS
fi
MSG=$MSG"Backup von ${TYPE} startet um $(date +%H:%M)\n"
### Wechsel in root damit die Pfade stimmen ##
cd /
### Backupverzeichnis anlegen" ##
mkdir -p ${BACKUPDIR}
### Test ob Backupverzeichnis existiert und Mail an Admin bei fehlschlagen ##
if [ ! -d "${BACKUPDIR}" ]; then
MSG=$MSG"das Backup am ${DATUM} konnte nicht erstellt werden. Das Verzeichnis ${BACKUPDIR} wurde nicht gefunden und konnte auch nicht angelegt werden.\n"
continue
fi
### Alle Variablen einlesen und letzte Backupdateinummer herausfinden ##
set -- ${BACKUPDIR}/backup${TYPE2}-???.tgz
lastname=${!#}
backupnr=${lastname##*backup${TYPE2}-}
backupnr=${backupnr%%.*}
backupnr=${backupnr//\?/0}
backupnr=$[10#${backupnr}]
### Backupdateinummer automatisch um +1 bis maximal 30 erhoehen ##
if [ "$[backupnr++]" -ge ${DAYS[$i]} -a "${FFBU}" = "false" ]; then
mkdir -p ${ROTATEDIR}/${DATUM}-${ZEIT}
### Test ob Rotateverzeichnis existiert und Mail an Admin bei fehlschlagen ##
if [ ! -d "${ROTATEDIR}/${DATUM}-${ZEIT}" ]; then
MSG=$MSG"die alten Backups konnten am ${DATUM} nicht verschoben werden. Das Verzeichnis ${ROTATEDIR} wurde nicht gefunden und konnte auch nicht angelegt werden.\n"
continue
else
mv ${BACKUPDIR}/b* ${ROTATEDIR}/${DATUM}-${ZEIT}
mv ${BACKUPDIR}/t* ${ROTATEDIR}/${DATUM}-${ZEIT}
fi
### Abfragen ob das Backupverschieben erfolgreich war ##
if [ $? -ne 0 ]; then
MSG=$MSG"die alten Backups konnte am ${DATUM} nicht verschoben werden.\n"
continue
else
MSG=$MSG"die alten Backups wurde am ${DATUM} erfolgreich nach ${ROTATEDIR}/${DATUM}-${ZEIT} verschoben.\n"
### die Backupnummer wieder auf 1 stellen ##
backupnr=1
fi
fi
if [ "$[backupnr]" -ge ${DAYS[$i]} -a "${FFBU}" = "true" ]; then
MSG=$MSG"das Vollbackup ${Type} wurde als Inkrmentell fortgesetzt, da bereits ein Vollbackup ausgeführt wurde.\n"
fi
backupnr=000${backupnr}
backupnr=${backupnr: -3}
filename=backup${TYPE2}-${backupnr}.tgz
if [ "${backupnr}" = "001" -a "${FFBU}" = "true" ]; then
MSG=$MSG"das Vollbackup ${Type} wurde übersprungen, da bereits ein Vollbackup ausgeführt wurde.\n"
continue
fi
### Nun wird das eigentliche Backup ausgefuehrt ##
tar --no-check-device -cpzf ${BACKUPDIR}/${filename} -g ${BACKUPDIR}/${TIMESTAMP} ${SOURCE} ${EXCLUDE}
### Abfragen ob das Backup erfolgreich war ##
if [ $? -ne 0 ]; then
MSG=$MSG"das Backup ${filename} am ${DATUM} wurde um $(date +%H:%M) mit Fehler(n) beendet.\n"
else
MSG=$MSG"das Backup ${filename} am ${DATUM} wurde um $(date +%H:%M) erfolgreich beendet.\n"
if [ "${backupnr}" = "001" ]; then
FFBU="true"
fi
fi
done
MSG=$MSG"Das gesamte Backup wurde am $(date +%d-%m-%Y) um $(date +%H:%M) beendet\n\n"
MSG=$MSG"Mit freundlichem Gruss Backupscript\n"
echo -e $MSG | mail -s "Backupreport" ${MAILUSER}
[/php]