BorgBackup ist eine Backupsoftware mit Deduplizierung, es ist dabei sehr Speicherplatz Sparend, der genauen funktionsumfang kann sich hier angeschaut werden
https://www.borgbackup.org
wer das mit einer GUI haben möchte kann sich das hier anschauen
auf Debian/Ubuntu Systemen muss nur das Paket borgbackup installiert werden, das Script ist getestet mit BorgBackup Version 1.2.x hier ein Beispiel:
apt install borgbackup
borg Repository initialisieren mit Verschlüsselung, das Backuplaufwerk wurde auf dem Client eingebunden in /mnt/borgbackup
borg init --encryption=repokey /mnt/borgbackup
anschließend dein Passwort für die Verschlüsselung in dieser Zeile eintragen
export BORG_PASSPHRASE=‘dein-borgrepo-passwort’
oder ohne Verschlüsselung
borg init --encryption=none /mnt/borgbackup
wen man das Backup über SSH auf einen Backupserver schieben möchte erstellt man noch einen SSH key
ssh-keygen -t ed25519 -f ~/.ssh/id_borgbackup
auf dem Backupserver den öffentliche Schlüssel eintragen unter dem User über den die Verbindung aufgebaut wird z.b. root mit der Beschränkung nur auf das Backup Verzeichnis zugreifen zu dürfen, der öffentliche Schlüssel ist in diesem Beispiel am ende gekürzt
/root/.ssh/authorized_keys
command="borg serve --restrict-to-path /mnt/borgbackup",no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3Nz.......
auf dem Client noch den Log Ordner erstellen /var/log/borg
wen das Backup Repository direkt auf dem Client eingebunden ist, muss die Zeile so angerpasst werden
BORG_REPO=“/mnt/borgbackup”
wen das Repository unverschlüsselt ist, aus dieser Zeile das Kommentar entfernen, und die beiden Zeilen auskommentieren
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
#export BORG_PASSPHRASE=‘dein-borgrepo-passwort’
#export BORG_RSH=‘ssh -i /root/.ssh/id_borgbackup’
anpassbare Optionen
Log Verzeichnis
LOG_DIR="/var/log/borg"
Logdatei Name
LOG_BASENAME="backup"
Anzahl Tage, die Logdateien aufbewahrt werden
LOG_RETENTION_DAYS=7
zu sicherndes Verzeichnis, entweder "/"
für das Hauptverzeichnis oder z.B. "/etc /home /var/www"
für einzelne Verzeichnisse
BACKUP_SOURCE="/"
Sekunden, bis Borg auf ein Repository-Lock wartet
LOCK_WAIT=600
Kompressionsmethode und -stufe
COMPRESSION_METHOD="zstd,8"
Anzahl aufzubewahrender Archive, 7 Tage
KEEP_WITHIN_DAYS=7
wie oft wiederholt werden soll wen das Backup fehlschlägt
RETRIES=5
welche Ordner oder Dateien ausgeschlossen werden sollen
EXCLUDES=( --exclude /var/log/borg )
das Script ist so aufgebaut das mehrere Client zur selben zeit einen Cronjob haben können, die warten auf einander bis das Backup Repository frei ist und das Backup ausgeführt werden kann, 600 Sekunden wird gewartet sollte ein lock vorhanden sein, danach wird ein neuer Backupversuch gestartet, nach jedem versuch wird 120 Sekunden gewartet bevor ein neuer versuch startet, wen sich eine Datei geändert hat während sie gesichert wurde, zählt das als Backup fehlgeschlagen, es wird bis zum ende weiter gesichert und anschließend ein neuer Backupversuch gestartet, bis maximal 5 versuche für jede Aufgabe, die Wiederholungen können aber angepasst werden oder auch wie lange gewartet werden soll wen ein lock vorhanden ist
Aufgaben vom Script
- “Create” Backup erstellen
- “Prune” alte Backup löschen
- “Compact” nicht mehr vorhandene Dateien aus dem Repository entfernen
- “clean logfile” die letzten 7 Tage Logdateien behalten
dieses Beispiel Script ist für ein verschlüsseltes Repository, die Backup werden vom Client über SSH gesichert,
borg_backup-client.sh
#!/bin/bash
# Repo-Konfiguration
BORG_REPO="root@IP-vom-Backupserver:/mnt/borgbackup"
export BORG_PASSPHRASE='dein-borgrepo-passwort'
#export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
export BORG_RSH='ssh -i /root/.ssh/id_borgbackup'
# Logfile-Konfiguration
LOG_DIR="/var/log/borg"
LOG_BASENAME="backup"
LOG_RETENTION_DAYS=7
# Backup-Konfiguration
BACKUP_SOURCE="/" # oder z.B. "/etc /home /var/www"
LOCK_WAIT=600
COMPRESSION_METHOD="zstd,8"
KEEP_WITHIN_DAYS=7
RETRIES=5
EXCLUDES=(
--exclude /proc
--exclude /sys
--exclude /dev
--exclude /run
--exclude /mnt
--exclude /media
--exclude /lost+found
--exclude /tmp
--exclude /var/tmp
--exclude /var/log/borg
--exclude /swap
--exclude /swapfile
--exclude /var/lib/lxcfs
--exclude /var/lib/docker/containers
--exclude /var/lib/docker/overlay2
)
#---*** AB HIER NICHTS ÄNDERN ***---
HOSTNAME=$(hostname -s)
BORG_ARCHIVE="${HOSTNAME}-{now:%Y-%m-%d_%H-%M}"
LOG_TIMESTAMP="$(date +%Y-%m-%d_%H-%M-%S)"
LOGFILE_NAME="${LOG_BASENAME}_${LOG_TIMESTAMP}.log"
LOGFILE="${LOG_DIR}/${LOGFILE_NAME}"
exec > >(tee -i "${LOGFILE}")
exec 2>&1
echo "==== $(date '+%F %T') - Starte Backup für $HOSTNAME ===="
# Create
for i in $(seq 1 $RETRIES); do
borg create --verbose --stats --progress \
--lock-wait "$LOCK_WAIT" \
--compression "$COMPRESSION_METHOD" \
"${BORG_REPO}::${BORG_ARCHIVE}" \
${BACKUP_SOURCE} "${EXCLUDES[@]}"
if [ $? -eq 0 ]; then
echo "Backup erfolgreich beim Versuch $i"
break
else
echo "Backup-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
echo "entferne alte Archive..."
# Prune
for i in $(seq 1 $RETRIES); do
borg prune --verbose --list \
--lock-wait "$LOCK_WAIT" \
--keep-within "${KEEP_WITHIN_DAYS}d" \
-a "${HOSTNAME}-*" \
"${BORG_REPO}"
if [ $? -eq 0 ]; then
echo "Prune erfolgreich beim Versuch $i"
break
else
echo "Prune-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
echo "Entferne ungenutzte Datenblöcke aus dem Repository..."
# Compact
for i in $(seq 1 $RETRIES); do
borg compact --verbose \
--lock-wait "$LOCK_WAIT" \
"${BORG_REPO}"
if [ $? -eq 0 ]; then
echo "Compact erfolgreich beim Versuch $i"
break
else
echo "Compact-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
# clean logfile
echo "Bereinige alte Logdateien..."
find "$LOG_DIR" -type f -name "${LOG_BASENAME}_*.log" ! -newermt "$(date -d "$LOG_RETENTION_DAYS days ago" +%F)" -delete
echo "==== $(date '+%F %T') - Backup abgeschlossen ===="
Cron Job täglich um 3 Uhr Nachts
0 3 * * * root /root/borg_backup-client.sh > /dev/null 2>&1
Beispiel Script um Sicherungen mit BorgBackup auf der Hetzner Storagebox zu erstellen
#!/bin/bash
# Repo-Konfiguration
export BORG_RSH='ssh -i /root/.ssh/id_borgbackup'
export BORG_PASSPHRASE='dein-borgrepo-passwort'
export BACKUP_USER='Storagebox-username'
export REPOSITORY_DIR='borg-backup'
# Logfile-Konfiguration
LOG_DIR="/var/log/borg"
LOG_BASENAME="borg-backup"
LOG_RETENTION_DAYS=7
# Backup-Konfiguration
BACKUP_SOURCE="/" # oder z.B. "/etc /home /var/www"
LOCK_WAIT=600
COMPRESSION_METHOD="zstd,8"
KEEP_LAST=7
RETRIES=5
EXCLUDES=(
--exclude /proc
--exclude /sys
--exclude /dev
--exclude /run
--exclude /mnt
--exclude /media
--exclude /lost+found
--exclude /tmp
--exclude /var/tmp
--exclude /var/log/borg
--exclude /swap
--exclude /swapfile
--exclude /var/lib/lxcfs
--exclude /var/lib/docker/containers
--exclude /var/lib/docker/overlay2
)
#---*** AB HIER NICHTS ÄNDERN ***---
HOSTNAME=$(hostname -s)
BORG_ARCHIVE="${HOSTNAME}-{now:%Y-%m-%d_%H-%M}"
LOG_TIMESTAMP="$(date +%Y-%m-%d_%H-%M-%S)"
LOGFILE_NAME="${LOG_BASENAME}_${LOG_TIMESTAMP}.log"
LOGFILE="${LOG_DIR}/${LOGFILE_NAME}"
export REPOSITORY="ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./${REPOSITORY_DIR}"
exec > >(tee -i "${LOGFILE}")
exec 2>&1
echo "==== $(date '+%F %T') - Starte Backup für $HOSTNAME ===="
# Create
for i in $(seq 1 $RETRIES); do
borg create --verbose --stats --progress \
--lock-wait "$LOCK_WAIT" \
--compression "$COMPRESSION_METHOD" \
"${REPOSITORY}::${BORG_ARCHIVE}" \
${BACKUP_SOURCE} "${EXCLUDES[@]}"
if [ $? -eq 0 ]; then
echo "Backup erfolgreich beim Versuch $i"
break
else
echo "Backup-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
echo "entferne alte Archive..."
# Prune
for i in $(seq 1 $RETRIES); do
borg prune --verbose --list \
--lock-wait "$LOCK_WAIT" \
--keep-last="$KEEP_LAST" \
-a "${HOSTNAME}-*" \
"${REPOSITORY}"
if [ $? -eq 0 ]; then
echo "Prune erfolgreich beim Versuch $i"
break
else
echo "Prune-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
echo "Entferne ungenutzte Datenblöcke aus dem Repository..."
# Compact
for i in $(seq 1 $RETRIES); do
borg compact --verbose \
--lock-wait "$LOCK_WAIT" \
"${REPOSITORY}"
if [ $? -eq 0 ]; then
echo "Compact erfolgreich beim Versuch $i"
break
else
echo "Compact-Versuch $i fehlgeschlagen, warte 2 Minuten..."
sleep 120
fi
done
# clean logfile
echo "Bereinige alte Logdateien..."
find "$LOG_DIR" -type f -name "${LOG_BASENAME}_*.log" ! -newermt "$(date -d "$LOG_RETENTION_DAYS days ago" +%F)" -delete
echo "==== $(date '+%F %T') - Backup abgeschlossen ===="