BorgBackup (Borg) ist ein deduplizierendes Backup-Programm, das Daten effizient komprimiert und optional verschlüsselt. Es ist ideal für Server-Backups und spart durch Deduplizierung erheblich Speicherplatz.

Warum BorgBackup?

Vorteile

- Deduplizierung: Identische Daten nur einmal speichern
- Kompression: LZ4, zstd, lzma
- Verschlüsselung: AES-256
- Schnell: Nur geänderte Chunks übertragen
- Append-only Modus: Schutz vor Ransomware
- Prune: Automatische Backup-Rotation

Vergleich Speicherverbrauch

| Backup-Art | 7 tägliche Backups 1TB | |------------|------------------------| | Vollbackups | 7 TB | | Inkrementell | ~1.3 TB | | Borg (dedupliziert) | ~1.05 TB |

Installation

Debian/Ubuntu

apt install borgbackup

CentOS/RHEL

dnf install epel-release
dnf install borgbackup

Aktuelle Version von GitHub

pip install borgbackup

Version prüfen

borg --version

Repository initialisieren

Lokales Repository

# Mit Verschlüsselung (empfohlen)
borg init --encryption=repokey /backup/borg-repo

# Ohne Verschlüsselung
borg init --encryption=none /backup/borg-repo

Verschlüsselungsmodi

| Modus | Beschreibung | |-------|--------------| | repokey | Schlüssel im Repository, Passphrase nötig | | keyfile | Schlüssel in ~/.config/borg, Passphrase nötig | | repokey-blake2 | Wie repokey, schnellerer Hash | | none | Keine Verschlüsselung |

Schlüssel sichern

# WICHTIG: Schlüssel exportieren und sicher aufbewahren!
borg key export /backup/borg-repo /root/borg-key-backup.txt

Erstes Backup erstellen

Einfaches Backup

borg create /backup/borg-repo::backup-$(date +%Y-%m-%d) /var/www /etc

Mit Optionen

borg create \
    --stats \
    --progress \
    --compression lz4 \
    /backup/borg-repo::backup-$(date +%Y-%m-%d_%H-%M) \
    /var/www \
    /etc \
    /home

Mit Ausschlüssen

borg create \
    --stats \
    --exclude '*.log' \
    --exclude '*.tmp' \
    --exclude '/var/www/*/cache' \
    --exclude-caches \
    /backup/borg-repo::backup-$(date +%Y-%m-%d) \
    /var/www \
    /etc

Exclude-Datei verwenden

# /root/borg-excludes.txt
*.log
*.tmp
*.cache
/var/cache
/var/tmp
/tmp
__pycache__
node_modules
.git
borg create \
    --exclude-from /root/borg-excludes.txt \
    /backup/borg-repo::backup-$(date +%Y-%m-%d) \
    /

Backups verwalten

Backups auflisten

borg list /backup/borg-repo

Backup-Details anzeigen

borg info /backup/borg-repo::backup-2026-01-26

Dateien in Backup anzeigen

borg list /backup/borg-repo::backup-2026-01-26

Repository-Statistiken

borg info /backup/borg-repo

Wiederherstellung

Komplette Wiederherstellung

cd /
borg extract /backup/borg-repo::backup-2026-01-26

In anderes Verzeichnis extrahieren

mkdir /restore
cd /restore
borg extract /backup/borg-repo::backup-2026-01-26

Bestimmte Dateien wiederherstellen

cd /restore
borg extract /backup/borg-repo::backup-2026-01-26 var/www/html/index.html

Verzeichnis wiederherstellen

borg extract /backup/borg-repo::backup-2026-01-26 etc/nginx/

Als FUSE mounten

mkdir /mnt/borg-backup
borg mount /backup/borg-repo::backup-2026-01-26 /mnt/borg-backup

# Dateien durchsuchen
ls /mnt/borg-backup

# Nach Fertig unmounten
borg umount /mnt/borg-backup

Automatische Rotation (Prune)

Alte Backups löschen

borg prune \
    --keep-daily=7 \
    --keep-weekly=4 \
    --keep-monthly=6 \
    /backup/borg-repo

Prune-Optionen

| Option | Beschreibung | |--------|--------------| | --keep-hourly | Stündliche Backups behalten | | --keep-daily | Tägliche Backups | | --keep-weekly | Wöchentliche Backups | | --keep-monthly | Monatliche Backups | | --keep-yearly | Jährliche Backups |

Mit Dry-Run testen

borg prune --dry-run --list \
    --keep-daily=7 \
    --keep-weekly=4 \
    /backup/borg-repo

Automatisiertes Backup-Skript

Basis-Skript

#!/bin/bash
# /usr/local/bin/borg-backup.sh

# Konfiguration
export BORG_REPO='/backup/borg-repo'
export BORG_PASSPHRASE='IhrSicheresPasswort'

# Backup-Name
BACKUP_NAME="backup-$(hostname)-$(date +%Y-%m-%d_%H-%M)"

# Backup erstellen
borg create \
    --stats \
    --compression lz4 \
    ::$BACKUP_NAME \
    /var/www \
    /etc \
    /home \
    --exclude '*.log' \
    --exclude '*/cache/*'

# Alte Backups aufräumen
borg prune \
    --keep-daily=7 \
    --keep-weekly=4 \
    --keep-monthly=6

# Integrität prüfen
borg check --repository-only

Erweitertes Skript mit Logging

#!/bin/bash
# /usr/local/bin/borg-backup.sh

set -euo pipefail

# Konfiguration
export BORG_REPO='/backup/borg-repo'
export BORG_PASSPHRASE='IhrSicheresPasswort'
LOG_FILE="/var/log/borg-backup.log"
LOCK_FILE="/var/run/borg-backup.lock"

# Logging-Funktion
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Fehlerbehandlung
error_exit() {
    log "FEHLER: $1"
    rm -f "$LOCK_FILE"
    exit 1
}

# Lock prüfen
if [ -f "$LOCK_FILE" ]; then
    error_exit "Backup läuft bereits (Lock-Datei existiert)"
fi

touch "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT

log "=== Backup gestartet ==="

# Backup-Name
BACKUP_NAME="$(hostname)-$(date +%Y-%m-%d_%H-%M-%S)"

# Quellverzeichnisse
SOURCES=(
    "/var/www"
    "/etc"
    "/home"
    "/root"
    "/var/lib/mysql"
)

# Ausschlüsse
EXCLUDES=(
    "*.log"
    "*.tmp"
    "*/cache/*"
    "*/.cache/*"
    "*/node_modules/*"
    "*/__pycache__/*"
    "*.pyc"
    "/var/lib/mysql/*.sock"
)

# Exclude-Parameter bauen
EXCLUDE_ARGS=""
for pattern in "${EXCLUDES[@]}"; do
    EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude '$pattern'"
done

# Backup erstellen
log "Erstelle Backup: $BACKUP_NAME"

eval borg create \
    --stats \
    --compression auto,lz4 \
    --exclude-caches \
    $EXCLUDE_ARGS \
    "::$BACKUP_NAME" \
    "${SOURCES[@]}" 2>&1 | tee -a "$LOG_FILE"

if [ ${PIPESTATUS[0]} -ne 0 ]; then
    error_exit "Backup-Erstellung fehlgeschlagen"
fi

# Prune
log "Räume alte Backups auf..."
borg prune \
    --list \
    --keep-hourly=24 \
    --keep-daily=7 \
    --keep-weekly=4 \
    --keep-monthly=6 \
    --keep-yearly=2 2>&1 | tee -a "$LOG_FILE"

# Compact (Borg 1.2+)
log "Kompaktiere Repository..."
borg compact 2>&1 | tee -a "$LOG_FILE" || true

# Repository-Info
log "Repository-Status:"
borg info 2>&1 | tee -a "$LOG_FILE"

log "=== Backup abgeschlossen ==="

Skript einrichten

chmod +x /usr/local/bin/borg-backup.sh

# Testen
/usr/local/bin/borg-backup.sh

Cron-Job

# Crontab bearbeiten
crontab -e

# Täglich um 2:00 Uhr
0 2 * * * /usr/local/bin/borg-backup.sh >> /var/log/borg-backup.log 2>&1

Systemd-Timer

# /etc/systemd/system/borg-backup.service
[Unit]
Description=Borg Backup
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/borg-backup.sh
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
# /etc/systemd/system/borg-backup.timer
[Unit]
Description=Daily Borg Backup

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=1800
Persistent=true

[Install]
WantedBy=timers.target
systemctl enable --now borg-backup.timer

Remote-Backup

SSH-Setup

# SSH-Key generieren
ssh-keygen -t ed25519 -f /root/.ssh/borg_key -N ""

# Key auf Backup-Server kopieren
ssh-copy-id -i /root/.ssh/borg_key.pub backup@backup-server.com

Repository auf Remote-Server

# Auf Backup-Server
mkdir -p /backup/clients/server1

# Repository initialisieren (vom Client aus)
borg init --encryption=repokey ssh://backup@backup-server.com/backup/clients/server1

Remote-Backup-Skript

#!/bin/bash
export BORG_REPO='ssh://backup@backup-server.com/backup/clients/server1'
export BORG_PASSPHRASE='IhrSicheresPasswort'
export BORG_RSH='ssh -i /root/.ssh/borg_key'

borg create \
    --stats \
    --compression auto,lz4 \
    ::backup-$(date +%Y-%m-%d) \
    /var/www /etc /home

Bandbreite begrenzen

export BORG_RSH='ssh -i /root/.ssh/borg_key -o "IPQoS=throughput"'

borg create \
    --remote-ratelimit 5000 \
    ::backup-$(date +%Y-%m-%d) \
    /var/www

Append-only Modus

Schutz vor Ransomware

Auf dem Backup-Server:

# ~/.ssh/authorized_keys auf Backup-Server
command="borg serve --append-only --restrict-to-path /backup/clients/server1",restrict ssh-ed25519 AAAA... root@client

Client kann nur hinzufügen

- Backups erstellen: Ja
- Backups löschen: Nein (nur auf Server)
- Prune: Nein (nur auf Server)

Datenbank-Backups

MySQL/MariaDB

#!/bin/bash
# Datenbank dumpen vor Borg-Backup

mysqldump --all-databases --single-transaction | gzip > /backup/mysql/all-databases.sql.gz

borg create \
    ::backup-$(date +%Y-%m-%d) \
    /var/www \
    /etc \
    /backup/mysql

PostgreSQL

pg_dumpall | gzip > /backup/postgres/all-databases.sql.gz

borg create ::backup-$(date +%Y-%m-%d) /var/www /backup/postgres

Monitoring und Wartung

Repository prüfen

# Nur Repository-Struktur
borg check --repository-only /backup/borg-repo

# Vollständige Prüfung (langsam)
borg check /backup/borg-repo

# Mit Reparatur (vorsichtig!)
borg check --repair /backup/borg-repo

Speicherverbrauch

# Repository-Info
borg info /backup/borg-repo

# Detailliert
borg info --json /backup/borg-repo | jq '.cache.stats'

Kompaktieren (Borg 1.2+)

borg compact /backup/borg-repo

Backup-Verifizierung

Test-Restore

#!/bin/bash
# Monatlicher Test-Restore

RESTORE_DIR="/tmp/borg-test-restore"
mkdir -p "$RESTORE_DIR"

cd "$RESTORE_DIR"
LATEST=$(borg list --last 1 --short /backup/borg-repo)
borg extract /backup/borg-repo::$LATEST

# Dateien prüfen
if [ -f "$RESTORE_DIR/etc/passwd" ]; then
    echo "Test-Restore erfolgreich"
else
    echo "Test-Restore FEHLGESCHLAGEN!"
fi

rm -rf "$RESTORE_DIR"

Zusammenfassung Befehle

| Aktion | Befehl | |--------|--------| | Repository erstellen | borg init --encryption=repokey /backup/repo | | Backup erstellen | borg create ::name /pfade | | Backups auflisten | borg list /backup/repo | | Wiederherstellen | borg extract ::name pfad/ | | Mounten | borg mount ::name /mnt | | Alte löschen | borg prune --keep-daily=7 | | Prüfen | borg check | | Info | borg info |

Fazit

BorgBackup ist ein hervorragendes Backup-Tool für Server. Die Deduplizierung spart erheblich Speicherplatz, und die Verschlüsselung schützt sensible Daten. Mit dem Append-only Modus sind Backups sogar vor Ransomware geschützt. Automatisieren Sie Ihre Backups mit einem Shell-Skript und Cron, und vergessen Sie nicht, regelmäßig Test-Restores durchzuführen.