Linux Backups: rsync, Timeshift und die 3-2-1-Strategie
Backups sind wie Versicherungen: Niemand braucht sie – bis man sie braucht. Und dann muss alles funktionieren. Dieser Guide zeigt, wie du mit rsync und Timeshift robuste Backup-Strategien umsetzt – von einfachen Datei-Backups bis hin zu vollständigen System-Snapshots.
Die 3-2-1-Backup-Strategie
Die Regel, die sich in der Praxis bewährt hat:
3 Kopien der Daten
├── 2 auf verschiedenen Speichermedien
│ ├── Original (Primärsystem)
│ └── Lokales Backup (externe Festplatte, NAS)
└── 1 off-site (geographisch getrennt)
└── Cloud, Remote-Server, Freund/Familien-NAS
Warum 3-2-1?
- 1 Kopie schützt nicht gegen Festplattenausfall
- 2 Kopien am selben Ort schützen nicht gegen Brand/Diebstahl
- 2 Kopien ohne Off-site schützen nicht gegen Katastrophen
Typische Umsetzung für Linux-Desktop
Original: /home/andre/ (SSD)
Backup 1: /mnt/backup/ (externe Festplatte)
Backup 2: remote-server:/backup/ (VPS oder Cloud)
Für Server
Original: /var/www/, /etc/, /var/lib/mysql/ (Server-SSD)
Backup 1: /mnt/backup-disk/ (zweite Festplatte)
Backup 2: backup-server:/backups/hostname/ (getrennter Server)
rsync: Der Standard für Datei-Backups
rsync (Version 3.4.1) ist das Schweizer Taschenmesser für Datei-Synchronisation: Es überträgt nur geänderte Dateiteile, prüft Prüfsummen und ist über SSH absicherbar.
Grundlegende Syntax
rsync [OPTIONEN] QUELLE ZIEL
# Wichtige Optionen:
# -a (--archive) : Archiv-Modus = -rlptgoD
# r=rekursiv, l=Symlinks, p=Berechtigungen,
# t=Zeiten, g=Gruppe, o=Besitzer, D=Gerätedateien
# -v (--verbose) : Ausgabe was kopiert wird
# -z (--compress) : Komprimierung (gut für langsame Verbindungen)
# --progress : Fortschrittsanzeige
# --delete : Auf Ziel löschen was in Quelle fehlt
# -n (--dry-run) : Simulieren ohne zu kopieren
# --exclude : Bestimmte Dateien/Muster ausschließen
Einfache lokale Backups
# Home-Verzeichnis auf externe Festplatte
rsync -av /home/andre/ /mnt/backup/home/andre/
# Mit Fortschrittsanzeige
rsync -av --progress /home/andre/ /mnt/backup/home/andre/
# Simulieren (--dry-run, -n): Was würde kopiert?
rsync -avn /home/andre/ /mnt/backup/home/andre/
# Mit --delete (Ziel spiegelt Quelle exakt)
rsync -av --delete /home/andre/ /mnt/backup/home/andre/
Trailing Slash ist entscheidend!
rsync -av /home/andre/ /backup/ # Inhalt von andre/ → /backup/ rsync -av /home/andre /backup/ # Verzeichnis andre → /backup/andre/
Wichtige Ausschlüsse
# Muster ausschließen
rsync -av --exclude='*.tmp' --exclude='*.cache' \
/home/andre/ /backup/
# Aus Datei ausschließen
cat > /etc/backup-exclude.txt << 'EOF'
.cache/
.local/share/Trash/
Downloads/tmp/
*.pyc
__pycache__/
node_modules/
.git/
EOF
rsync -av --exclude-from='/etc/backup-exclude.txt' \
/home/andre/ /backup/home/andre/
Server-Backup: Wichtige Verzeichnisse
# Kritische Server-Verzeichnisse sichern
rsync -av --delete \
--exclude='/proc/' \
--exclude='/sys/' \
--exclude='/dev/' \
--exclude='/run/' \
--exclude='/tmp/' \
--exclude='/mnt/' \
--exclude='/media/' \
--exclude='/lost+found' \
/ /mnt/backup/server-full/
# Nur Konfigurationen und Daten (schneller, reicht für die meisten Fälle)
rsync -av /etc/ /backup/etc/
rsync -av /var/www/ /backup/www/
rsync -av /var/lib/mysql/ /backup/mysql/ # wenn kein Dump nötig (DB muss gestoppt sein!)
rsync -av /home/ /backup/home/
Inkrementelle Backups mit Hard-Links
Inkrementelle Backups speichern nur Änderungen, belegen aber trotzdem wenig Platz dank Hard-Links: Unveränderte Dateien zeigen auf dieselben Daten auf der Festplatte.
# Backup-Skript mit Daily-Snapshots (Hard-Link-Methode)
sudo nano /usr/local/bin/backup-inkrementell.sh
#!/bin/bash
# Inkrementelles Backup mit rsync und Hard-Links
# Jedes Backup erscheint wie ein vollständiges, belegt aber nur Platz für Änderungen
QUELLE="/home/andre/"
BACKUP_DIR="/mnt/backup/snapshots"
DATUM=$(date +%Y-%m-%d_%H-%M-%S)
LETZTES="$BACKUP_DIR/latest"
# Backup-Verzeichnis anlegen
mkdir -p "$BACKUP_DIR"
# Backup ausführen (Hard-Links auf "latest" für unverändertes)
rsync -av --delete \
--link-dest="$LETZTES" \
--exclude='.cache/' \
--exclude='Downloads/tmp/' \
"$QUELLE" \
"$BACKUP_DIR/$DATUM/"
# "latest" symlink aktualisieren
rm -f "$LETZTES"
ln -s "$BACKUP_DIR/$DATUM" "$LETZTES"
echo "Backup fertig: $BACKUP_DIR/$DATUM"
sudo chmod +x /usr/local/bin/backup-inkrementell.sh
# Testen
sudo /usr/local/bin/backup-inkrementell.sh
# Ergebnis: separate Verzeichnisse, aber kaum mehr Platz
ls -la /mnt/backup/snapshots/
# lrwxrwxrwx 1 root root ... latest -> /mnt/backup/snapshots/2026-02-18_10-00-00
# drwxr-xr-x 2 root root ... 2026-02-18_10-00-00/
# drwxr-xr-x 2 root root ... 2026-02-17_10-00-00/
# Speicher: Hard-Links machen's effizient
du -sh /mnt/backup/snapshots/*/
# 2.3G 2026-02-18_10-00-00 ← vollständiges Backup (letztes)
# 4.2M 2026-02-17_10-00-00 ← nur Änderungen (älter)
Alte Backups automatisch aufräumen
# Backups die älter als 30 Tage sind löschen
find /mnt/backup/snapshots/ -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
# Die letzten 7 Backups behalten, ältere löschen
ls -1t /mnt/backup/snapshots/ | grep -v "^latest$" | tail -n +8 | \
xargs -I{} rm -rf /mnt/backup/snapshots/{}
rsync über SSH (Remote-Backup)
# Basis: rsync über SSH
rsync -av -e ssh /home/andre/ backup-user@backup-server:/backups/andre/
# Mit Port (wenn SSH nicht auf 22)
rsync -av -e "ssh -p 2222" /home/andre/ backup-user@backup-server:/backups/
# Mit spezifischem SSH-Schlüssel
rsync -av -e "ssh -i ~/.ssh/id_backup" \
/home/andre/ backup-user@backup-server:/backups/andre/
# Kompression für langsame Verbindungen
rsync -avz -e ssh /home/andre/ backup-user@backup-server:/backups/
SSH-Key für automatische Backups
# Separaten Schlüssel für Backups erstellen (ohne Passphrase!)
ssh-keygen -t ed25519 -C "backup-key-$(hostname)" -f ~/.ssh/id_backup -N ""
# Auf Backup-Server hinterlegen
ssh-copy-id -i ~/.ssh/id_backup.pub backup-user@backup-server
# Verbindung testen
ssh -i ~/.ssh/id_backup backup-user@backup-server "echo OK"
Inkrementell remote
# Remote inkrementell: erstes Mal dauert länger, danach nur Differenzen
rsync -av --delete \
-e "ssh -i ~/.ssh/id_backup" \
--link-dest=/backups/latest/ \
/home/andre/ \
backup-user@backup-server:/backups/$(date +%Y-%m-%d)/
# "latest" auf dem Remote-Server aktualisieren
ssh -i ~/.ssh/id_backup backup-user@backup-server \
"ln -sfn /backups/$(date +%Y-%m-%d) /backups/latest"
Timeshift: System-Snapshots
Timeshift erstellt System-Snapshots (ähnlich Windows-Systemwiederherstellung). Ideal für:
- Snapshot vor System-Updates
- Snapshot vor riskanten Änderungen
- Schnelle Wiederherstellung des Betriebssystems
# Installieren
sudo apt install timeshift # Ubuntu/Debian
sudo dnf install timeshift # Fedora
# Grafisch (empfohlen für Einrichtung)
sudo timeshift-gtk
# Kommandozeile
sudo timeshift --list # Snapshots anzeigen
sudo timeshift --create # Snapshot erstellen
sudo timeshift --create --comments "Vor nginx-Update"
sudo timeshift --delete --snapshot '2026-02-17_10-00-01'
sudo timeshift --restore # Wiederherstellen
Timeshift konfigurieren
# Timeshift einrichten (CLI)
sudo timeshift --setup
Wichtige Einstellungen:
- Snapshot-Typ: RSYNC (flexibel) oder BTRFS (wenn Dateisystem BTRFS ist)
- Zeitplan: Täglich 5 behalten, wöchentlich 2 behalten
- Ausschlüsse:
/home/(eigene Daten separat mit rsync sichern)
# Konfigurationsdatei
sudo nano /etc/timeshift/timeshift.json
{
"backup_device_uuid": "abc12345-...",
"do_first_run": "false",
"btrfs_mode": "false",
"include_btrfs_home_for_backup": "false",
"stop_cron_emails": "true",
"schedule_monthly": "false",
"schedule_weekly": "true",
"schedule_daily": "true",
"schedule_hourly": "false",
"schedule_boot": "false",
"count_monthly": "2",
"count_weekly": "3",
"count_daily": "5",
"exclude": [
"+ /root/**",
"- /home/**"
]
}
Automatisierung: cron und systemd Timer
Backup-Skript für Server
sudo nano /usr/local/bin/server-backup.sh
#!/bin/bash
# Server-Backup: Configs, Web-Daten, Datenbank
# Getestet auf Ubuntu 24.04 LTS
set -euo pipefail
BACKUP_ROOT="/mnt/backup"
LOG="/var/log/backup.log"
DATUM=$(date +%Y-%m-%d_%H-%M)
HOSTNAME=$(hostname)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"
}
log "=== Backup gestartet: $DATUM ==="
# 1. Konfigurationen
log "Backup /etc..."
rsync -a --delete /etc/ "$BACKUP_ROOT/etc/"
# 2. Web-Daten
log "Backup /var/www..."
rsync -a --delete --exclude='*.log' /var/www/ "$BACKUP_ROOT/www/"
# 3. Home-Verzeichnis
log "Backup /home..."
rsync -a --delete \
--exclude='.cache/' \
--exclude='node_modules/' \
/home/ "$BACKUP_ROOT/home/"
# 4. MySQL/MariaDB Dump
if systemctl is-active --quiet mysql; then
log "MySQL Dump..."
mkdir -p "$BACKUP_ROOT/mysql"
mysqldump --all-databases --single-transaction \
--routines --triggers \
> "$BACKUP_ROOT/mysql/all-databases_${DATUM}.sql"
# Alte Dumps löschen (älter als 7 Tage)
find "$BACKUP_ROOT/mysql" -name "*.sql" -mtime +7 -delete
fi
# 5. Remote-Sync (optional)
if ping -c1 -W2 backup-server &>/dev/null; then
log "Remote-Sync zu backup-server..."
rsync -az --delete \
-e "ssh -i /root/.ssh/id_backup" \
"$BACKUP_ROOT/" \
backup-user@backup-server:/backups/$HOSTNAME/
fi
log "=== Backup abgeschlossen ==="
log "Speicherverbrauch: $(du -sh $BACKUP_ROOT | cut -f1)"
sudo chmod +x /usr/local/bin/server-backup.sh
sudo /usr/local/bin/server-backup.sh # Testen
Mit cron automatisieren
sudo crontab -e
# Täglich um 02:00 Uhr
0 2 * * * /usr/local/bin/server-backup.sh 2>&1 | logger -t backup
# Wöchentlich Sonntag um 03:00 (separates Full-Backup)
0 3 * * 0 /usr/local/bin/server-backup-full.sh
Mit systemd Timer (besser für Server)
sudo nano /etc/systemd/system/server-backup.service
[Unit]
Description=Tägliches Server-Backup
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/server-backup.sh
StandardOutput=journal
StandardError=journal
User=root
sudo nano /etc/systemd/system/server-backup.timer
[Unit]
Description=Tägliches Server-Backup um 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=300
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now server-backup.timer
# Status prüfen
systemctl status server-backup.timer
systemctl list-timers server-backup.timer
Backup-Tests: Das oft vergessene Muss
Ein Backup ist erst dann ein Backup, wenn der Restore funktioniert.
# Monatlicher Restore-Test: Zufällige Datei wiederherstellen
TEST_DATEI=$(find /mnt/backup/home -type f | shuf -n 1)
echo "Restore-Test: $TEST_DATEI"
# Auf /tmp/ wiederherstellen
rsync -av "$TEST_DATEI" /tmp/restore-test/
# Prüfen ob die Datei korrekt ist
file /tmp/restore-test/$(basename $TEST_DATEI)
md5sum "$TEST_DATEI" /tmp/restore-test/$(basename $TEST_DATEI)
# Beide MD5-Sums müssen übereinstimmen!
Wiederherstellung (Restore)
Einzelne Datei/Verzeichnis wiederherstellen
# Einzelne Datei aus Backup wiederherstellen
rsync -av /mnt/backup/home/andre/dokument.pdf /home/andre/
# Verzeichnis aus Backup wiederherstellen
rsync -av /mnt/backup/www/meine-seite/ /var/www/meine-seite/
# Spezifische Version (aus Snapshot)
rsync -av /mnt/backup/snapshots/2026-02-17_10-00-00/home/andre/ /home/andre/
Vollständige System-Wiederherstellung mit Timeshift
# Von Live-CD booten, dann:
sudo timeshift --restore --snapshot '2026-02-17_10-00-01'
# Oder: Snapshot zum Wiederherstellen auswählen
sudo timeshift --restore
Remote-Backup wiederherstellen
# Daten vom Backup-Server zurückübertragen
rsync -av \
-e "ssh -i ~/.ssh/id_backup" \
backup-user@backup-server:/backups/mein-server/home/andre/ \
/home/andre/
# Komplette Server-Wiederherstellung
rsync -av \
-e "ssh -i ~/.ssh/id_backup" \
backup-user@backup-server:/backups/mein-server/ \
/restore/
Häufige Fehler und Lösungen
rsync: Permission denied
# rsync als root ausführen
sudo rsync -av /etc/ /backup/etc/
# Oder: sudo für bestimmte rsync-Instanzen
rsync -av --rsync-path="sudo rsync" user@server:/etc/ /backup/
rsync: No space left on device
# Backup-Disk prüfen
df -h /mnt/backup/
# Alte Backups löschen
find /mnt/backup/snapshots -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
MySQL-Dump schlägt fehl
# Kein Passwort in Befehlszeile (sicherheitstechnisch schlecht)
# .my.cnf verwenden:
nano /root/.my.cnf
[mysqldump]
user=root
password=DeinPasswort
chmod 600 /root/.my.cnf
# Dann klappt mysqldump ohne Passwort-Parameter
Backup-Disk nicht automatisch gemountet
# In /etc/fstab eintragen
sudo blkid /dev/sdb1 # UUID herausfinden
sudo nano /etc/fstab
# UUID=abc123... /mnt/backup ext4 defaults,nofail 0 2
# nofail: System bootet auch wenn Disk fehlt
sudo mount -a # testen
Fazit
Ein gutes Backup-System braucht drei Dinge: Automatisierung (damit es nicht vergessen wird), Redundanz (3-2-1-Regel) und regelmäßige Tests (damit der Ernstfall kein Desaster wird).
Für die meisten Linux-Nutzer ist die optimale Kombination:
- rsync + cron/systemd Timer für Daten-Backups (täglich)
- Timeshift für System-Snapshots (vor Updates)
- Remote-Server oder Cloud als Off-site-Backup