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 aufbewahrenBackup-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 -deletePostgreSQL
#!/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.dumpDateisystem-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/latestBorgBackup (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 checkrestic (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 checkCloud-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-folderDisaster Recovery
Recovery Time Objective (RTO)
Definition: Maximale Ausfallzeit
Beispiel:
- Kritisch: < 1 Stunde
- Wichtig: < 4 Stunden
- Normal: < 24 StundenRecovery 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
### Datenbankgunzip < /backup/mysql/latest.sql.gz | mysql
### Dateienrsync -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.sha256Monitoring
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 0Speicherplatz
# Backup-Größe überwachen
du -sh /backup/*
# Wachstum beobachten
du -sh /backup/daily-* | sort -hBest 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 einrichtenSicherheit
# 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.gzZusammenfassung
| 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.