Eine durchdachte Backup-Strategie schützt vor Datenverlust. Dieser Artikel erklärt bewährte Methoden und deren Umsetzung für Server.

Grundprinzipien

3-2-1-Regel

3 Kopien:     Original + 2 Backups
2 Medien:     Verschiedene Speicherarten
1 Offsite:    Mindestens eine Kopie extern

Beispiel:
- Original: Server-Festplatte
- Backup 1: NAS im gleichen Gebäude
- Backup 2: Cloud-Storage (extern)

Backup-Typen

| Typ | Beschreibung | Speicher | Restore | |-----|--------------|----------|---------| | Voll | Alle Daten | Hoch | Schnell | | Inkrementell | Änderungen seit letztem Backup | Niedrig | Langsam | | Differenziell | Änderungen seit letztem Voll-Backup | Mittel | Mittel |

GVS-Schema (Großvater-Vater-Sohn)

Täglich (Sohn):      7 Tage aufbewahren
Wöchentlich (Vater): 4 Wochen aufbewahren
Monatlich (Großvater): 12 Monate aufbewahren

Backup-Rotation

Hanoi-Tower-Schema

Tag 1:  A
Tag 2:  B
Tag 3:  A
Tag 4:  C
Tag 5:  A
Tag 6:  B
Tag 7:  A
Tag 8:  D
...

Wochenrotation mit rsync

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

BACKUP_DIR="/backup"
SOURCE="/var/www /home /etc"
DAY=$(date +%A)

# Tägliches Backup (inkrementell)
rsync -avz --delete --link-dest=$BACKUP_DIR/latest \
    $SOURCE $BACKUP_DIR/daily-$DAY/

# Link zu latest aktualisieren
rm -f $BACKUP_DIR/latest
ln -s $BACKUP_DIR/daily-$DAY $BACKUP_DIR/latest

# Wöchentliches Backup (Sonntag)
if [ "$DAY" = "Sunday" ]; then
    WEEK=$(date +%V)
    cp -al $BACKUP_DIR/latest $BACKUP_DIR/weekly-$WEEK
fi

# Monatliches Backup (1. des Monats)
if [ $(date +%d) = "01" ]; then
    MONTH=$(date +%Y-%m)
    cp -al $BACKUP_DIR/latest $BACKUP_DIR/monthly-$MONTH
fi

# Alte Backups löschen
find $BACKUP_DIR -maxdepth 1 -name "daily-*" -mtime +7 -exec rm -rf {} \;
find $BACKUP_DIR -maxdepth 1 -name "weekly-*" -mtime +28 -exec rm -rf {} \;
find $BACKUP_DIR -maxdepth 1 -name "monthly-*" -mtime +365 -exec rm -rf {} \;

Datenbank-Backups

MySQL/MariaDB

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

BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Alle Datenbanken
mysqldump --all-databases --single-transaction \
    --routines --triggers | gzip > $BACKUP_DIR/all-$DATE.sql.gz

# Einzelne Datenbank
mysqldump --single-transaction wordpress | gzip > $BACKUP_DIR/wordpress-$DATE.sql.gz

# Alte Backups löschen
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

PostgreSQL

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

BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Alle Datenbanken
pg_dumpall | gzip > $BACKUP_DIR/all-$DATE.sql.gz

# Einzelne Datenbank
pg_dump dbname | gzip > $BACKUP_DIR/dbname-$DATE.sql.gz

# Custom Format (komprimiert, parallel restore)
pg_dump -Fc dbname > $BACKUP_DIR/dbname-$DATE.dump

Dateisystem-Backups

rsync (Standard)

#!/bin/bash
# Inkrementelles Backup mit Hardlinks

rsync -avz --delete \
    --exclude='/tmp/*' \
    --exclude='/var/cache/*' \
    --exclude='/var/tmp/*' \
    --link-dest=/backup/latest \
    / /backup/$(date +%Y%m%d)/

rm -f /backup/latest
ln -s /backup/$(date +%Y%m%d) /backup/latest

BorgBackup (dedupliziert)

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

export BORG_REPO=/backup/borg
export BORG_PASSPHRASE='sicheres-passwort'

# Backup erstellen
borg create --stats --progress \
    ::'{hostname}-{now:%Y-%m-%d}' \
    /etc /home /var/www \
    --exclude '/home/*/.cache' \
    --exclude '*.tmp'

# Alte Backups bereinigen
borg prune --keep-daily=7 --keep-weekly=4 --keep-monthly=6

# Integrität prüfen
borg check

restic (cloud-fähig)

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

export RESTIC_REPOSITORY="s3:s3.amazonaws.com/bucket-name"
export RESTIC_PASSWORD="sicheres-passwort"
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."

# Backup
restic backup /etc /home /var/www \
    --exclude-caches \
    --exclude '*.tmp'

# Aufräumen
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Integrität
restic check

Cloud-Backups

AWS S3

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

BUCKET="s3://my-backup-bucket"
DATE=$(date +%Y%m%d)

# Backup erstellen
tar -czf /tmp/backup-$DATE.tar.gz /var/www /etc

# Zu S3 hochladen
aws s3 cp /tmp/backup-$DATE.tar.gz $BUCKET/backups/

# Lokal löschen
rm /tmp/backup-$DATE.tar.gz

# Alte S3-Objekte löschen (Lifecycle-Policy empfohlen)

rclone (Multi-Cloud)

# rclone konfigurieren
rclone config

# Backup
rclone sync /backup remote:backup-folder \
    --transfers 4 \
    --checkers 8 \
    --progress

# Verschlüsselt
rclone sync /backup crypt:backup-folder

Disaster Recovery

Recovery Time Objective (RTO)

Definition: Maximale Ausfallzeit

Beispiel:
- Kritisch: < 1 Stunde
- Wichtig: < 4 Stunden
- Normal: < 24 Stunden

Recovery Point Objective (RPO)

Definition: Maximaler akzeptabler Datenverlust

Beispiel:
- Kritisch: < 1 Stunde (stündliche Backups)
- Wichtig: < 1 Tag (tägliche Backups)
- Normal: < 1 Woche (wöchentliche Backups)

DR-Plan dokumentieren

# Disaster Recovery Plan

## 1. Systemausfall
1. Benachrichtigung: admin@example.com, +49 123 456789
2. Neuen Server bereitstellen
3. OS installieren
4. Backup-Zugang konfigurieren
5. Daten wiederherstellen
6. Services starten
7. DNS aktualisieren
8. Funktionstest

## 2. Restore-Befehle

### Datenbank

gunzip < /backup/mysql/latest.sql.gz | mysql

### Dateien

rsync -avz /backup/latest/ /

## 3. Kontakte
- Hosting-Provider: ...
- Domain-Registrar: ...
- Backup-Storage: ...

Backup-Verifizierung

Restore-Tests

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

# Test-Verzeichnis
TEST_DIR=/tmp/restore-test

# Backup wiederherstellen
mkdir -p $TEST_DIR
tar -xzf /backup/latest.tar.gz -C $TEST_DIR

# Dateien vergleichen
diff -rq /var/www $TEST_DIR/var/www

# Datenbank testen
mysql -e "CREATE DATABASE restore_test"
gunzip < /backup/mysql/latest.sql.gz | mysql restore_test
mysql -e "SHOW TABLES FROM restore_test"
mysql -e "DROP DATABASE restore_test"

# Aufräumen
rm -rf $TEST_DIR

echo "Backup-Verifizierung abgeschlossen"

Checksummen

# Beim Backup
sha256sum /backup/backup-$DATE.tar.gz > /backup/backup-$DATE.sha256

# Bei Verifizierung
sha256sum -c /backup/backup-$DATE.sha256

Monitoring

Backup-Überwachung

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

BACKUP_DIR="/backup"
MAX_AGE=86400  # 24 Stunden in Sekunden

LATEST=$(find $BACKUP_DIR -maxdepth 1 -type d -name "2*" | sort | tail -1)
LATEST_TIME=$(stat -c %Y "$LATEST")
NOW=$(date +%s)
AGE=$((NOW - LATEST_TIME))

if [ $AGE -gt $MAX_AGE ]; then
    echo "CRITICAL: Letztes Backup älter als 24 Stunden!"
    mail -s "Backup-Warnung" admin@example.com <<< "Backup ist $AGE Sekunden alt"
    exit 2
fi

echo "OK: Letztes Backup: $LATEST"
exit 0

Speicherplatz

# Backup-Größe überwachen
du -sh /backup/*

# Wachstum beobachten
du -sh /backup/daily-* | sort -h

Best Practices

Checkliste

□ 3-2-1-Regel befolgen
□ Backups verschlüsseln
□ Regelmäßige Restore-Tests
□ Backup-Logs überwachen
□ Offsite-Kopie aktuell halten
□ DR-Plan dokumentieren
□ Kontaktliste aktuell halten
□ Benachrichtigungen einrichten

Sicherheit

# Backup-Verzeichnis schützen
chmod 700 /backup
chown root:root /backup

# Backup-User mit minimalen Rechten
useradd -r -s /bin/false backup-user

# Verschlüsselung
gpg -c backup.tar.gz

Zusammenfassung

| Strategie | Speicher | Restore | Einsatz | |-----------|----------|---------|---------| | Voll | Hoch | Schnell | Wöchentlich | | Inkrementell | Niedrig | Langsam | Täglich | | Differenziell | Mittel | Mittel | Täglich | | Snapshot | Niedrig | Schnell | Stündlich |

| Tool | Typ | Features | |------|-----|----------| | rsync | Sync | Schnell, Hardlinks | | BorgBackup | Dedupe | Kompression, Verschlüsselung | | restic | Dedupe | Cloud-Support | | rclone | Sync | Multi-Cloud |

Fazit

Eine solide Backup-Strategie kombiniert verschiedene Methoden und befolgt die 3-2-1-Regel. Regelmäßige Restore-Tests sind wichtiger als das Backup selbst. Dokumentieren Sie Ihren DR-Plan und halten Sie ihn aktuell. Automatisierung und Monitoring stellen sicher, dass Backups zuverlässig laufen. Verschlüsseln Sie sensible Daten, besonders bei Cloud-Backups.