Dein Proxmox Backup Server läuft. Vzdump jeden Tag um Mitternacht. PBS zeigt grüne Haken. Retention Policy? Konfiguriert. Verify Jobs? Bestehen.

Du hast kein Backup. Du hast eine Hoffnung.

Ein Backup ist erst ein Backup wenn du bewiesen hast, dass der Restore funktioniert. Alles andere ist Schrödingers Datensicherung — gleichzeitig vorhanden und verloren, bis du die Box öffnest.


Die Lücke

Proxmox prüft bei Verify Jobs nur die Integrität der Chunks — sind die Daten vollständig und konsistent? Was es nicht prüft:

  • Kann die VM tatsächlich aus dem Backup wiederhergestellt werden?
  • Bootet das restored System?
  • Sind die Services im Gast funktionsfähig?

Zwischen “Chunks sind valide” und “VM läuft nach Restore” liegt ein ganzer Ozean möglicher Fehler: korrupte Bootloader, kaputte Filesysteme, fehlende Kernel-Module, stale CIFS-Mounts die den Snapshot töten.

Die Lösung: Automatisierter Restore-Test

Ein Bash-Script das wöchentlich:

  1. Eine VM aus dem Remote-PBS restored (Round-Robin durch alle VMs)
  2. Alle Netzwerk-Interfaces entfernt (keine IP-Konflikte mit Produktion)
  3. Die VM bootet und 90 Sekunden wartet
  4. Den Boot-Status prüft (per Guest-Agent, nicht per qm status)
  5. Die Test-VM sofort zerstört
  6. Einen Bericht per Telegram schickt

Sicherheitsarchitektur

Wenn ein Script automatisch VMs auf deinem Proxmox-Host erstellt und zerstört, willst du verdammt sicher sein, dass es nicht versehentlich eine Produktions-VM überschreibt.

Pre-Flight Checks (ALLE müssen bestehen, sonst ABBRUCH):
├── Test-VMID existiert NICHT (qm status + pct status)
├── Test-VMID nicht in /cluster/resources (pvesh — Doppelcheck)
├── Kein laufender vzdump-Job (Lock-Konflikt-Vermeidung)
├── Genug Speicher für die Quell-VM + 10 GB Puffer
└── Jeder Fehler → sofortiger Abbruch + Cleanup + Alarm

Die Test-VMID (z.B. 9901) liegt absichtlich weit weg vom Produktionsbereich (100-199). Paranoia ist hier eine Feature, kein Bug.

Der entscheidende Trick: Guest-Agent statt Status-Check

Hier wird es interessant. Dein erster Instinkt für den Boot-Check ist wahrscheinlich:

qm status 9901
# status: running

Das ist wertlos. qm status prüft nur, ob der QEMU-Prozess läuft. Die VM könnte in einem Kernel Panic hängen, im BIOS-Screen stecken, oder — wie mir passiert — im Emergency Mode auf ein Root-Passwort warten. Für Proxmox ist das alles “running”.

Der echte Check läuft über den QEMU Guest Agent:

# Linux (systemd)
qm guest exec 9901 -- /bin/systemctl is-system-running
# → "running" = OK
# → "degraded" = einige Services fehlgeschlagen
# → timeout = VM hängt

# pfSense / FreeBSD (kein systemd)
qm guest exec 9901 -- /sbin/pfctl -s info
# → "Status: Enabled" = Paketfilter läuft = pfSense ist oben

Das setzt voraus, dass der Guest-Agent im Gast installiert und aktiv ist. Falls nicht:

Für Linux (Debian/Ubuntu):

apt install qemu-guest-agent
systemctl enable --now qemu-guest-agent

Für pfSense (FreeBSD):

# Paket ist im pfSense-Repo verfügbar
pkg install qemu-guest-agent
# In /etc/rc.conf:
sysrc qemu_guest_agent_enable="YES"
service qemu-guest-agent start

Für alle VMs: In der Proxmox-Config agent: 1 setzen (oder in der WebUI unter Options → QEMU Guest Agent → aktivieren).

Wichtig: Das VirtIO Serial Device (/dev/vtcon/org.qemu.guest_agent.0 auf FreeBSD, /dev/virtio-ports/org.qemu.guest_agent.0 auf Linux) muss existieren. Ohne Device ist der Agent installiert aber kann nicht kommunizieren.

Restore-Befehle: LXC vs. QEMU

Die Proxmox-APIs für LXC und QEMU sind nicht symmetrisch. Das hat mich beim ersten Versuch auf die Nase fallen lassen:

# LXC — hat --start
pct restore 9901 "pbs-storage:backup/ct/100/2026-03-26T23:01:05Z" \
    --storage local-zfs --unique 1 --start 0

# QEMU — hat KEIN --start (Unknown option!)
qmrestore "pbs-storage:backup/vm/108/2026-03-26T15:07:44Z" 9901 \
    --storage local-zfs --unique 1

--unique ist wichtig: Es generiert neue MAC-Adressen und UUIDs, damit die Test-VM nicht mit der Produktions-VM kollidiert.

NIC entfernen — vor dem Boot

Die Test-VM darf kein Netzwerk haben. Sonst hast du zwei VMs mit der gleichen IP im Netz, und dein Abend ist gelaufen.

# Alle Netzwerk-Interfaces aus der Config entfernen
# LXC:
for net in $(pct config 9901 | grep '^net' | cut -d: -f1); do
    pct set 9901 --delete "$net"
done

# QEMU:
for net in $(qm config 9901 | grep '^net' | cut -d: -f1); do
    qm set 9901 --delete "$net"
done

Cleanup: Immer. Auch bei Abbruch.

trap 'cleanup' ERR

cleanup() {
    # QEMU?
    if qm status 9901 &>/dev/null; then
        qm stop 9901 --timeout 30 2>/dev/null || true
        sleep 2
        qm destroy 9901 --purge 2>/dev/null || true
    fi
    # LXC?
    if pct status 9901 &>/dev/null; then
        pct stop 9901 2>/dev/null || true
        sleep 2
        pct destroy 9901 --purge 2>/dev/null || true
    fi
}

--purge entfernt auch die Disk. Kein Müll auf deinem ZFS-Pool.

Round-Robin: Jede VM wird getestet

Mit 11 VMs und wöchentlichem Test wird jede VM etwa alle 11 Wochen getestet. Die Reihenfolge folgt der DR-Priorität — die kritischsten VMs (Gateway, Domain Controller) zuerst.

VM_ROTATION=(
    "108:16"    # Gateway         QEMU  16G
    "107:20"    # Domain Controller LXC  20G
    "100:12"    # Mail Gateway    LXC   12G
    "102:36"    # Mailserver      QEMU  36G
    "105:56"    # Fileserver      QEMU  56G
    "101:180"   # Docker Host     LXC   180G
    ...
)

Das Format VMID:DISK_GB ermöglicht einen dynamischen Speicher-Check: Wenn die VM größer als der verfügbare Platz ist, wird sie übersprungen und die nächste getestet.

Der Beweis

✅ PBS Restore Test — Erfolgreich

📦 VM: gw-deathstar (VMID 108, QEMU)
⏱ Restore-Dauer: 898s
🔍 Boot-Status: running (pfSense: pfctl enabled)
🗑 Test-VM: zerstört

Nächster Test: 2026-04-03

15 Minuten für den Restore einer 16 GB pfSense-VM über einen WireGuard-Tunnel. Automatisch. Ohne manuellen Eingriff. Jeden Sonntag um 4 Uhr.

Und wenn es schiefgeht:

🚨 PBS Restore Test FEHLGESCHLAGEN

❌ qmrestore fehlgeschlagen: unable to open file '/etc/pve/...' - I/O error
📦 VM: gw-deathstar (VMID 108, QEMU)
🗑 Test-VM: aufgeräumt

Dann weißt du es jetzt — nicht erst wenn du den Restore wirklich brauchst.

Lessons Learned

  1. qm status running ist kein Boot-Check. Eine VM im Emergency Mode meldet sich als “running”. Ohne Guest-Agent bist du blind.

  2. qmrestore und pct restore haben unterschiedliche Parameter. Nicht copy-pasten, man-Pages lesen. --start gibt es nur bei LXC.

  3. Guest-Agent installieren ist nicht genug. Auf pfSense war der Agent seit Wochen installiert, aber nie gestartet. Auf UCS-Systemen lief er erst nach einem Reboot. Prüfe mit qm guest exec VMID -- /bin/echo test ob er wirklich antwortet.

  4. Backups die nie getestet werden sind keine Backups. Sie sind eine Hoffnung. Und Hoffnung ist kein Disaster-Recovery-Plan.

Checkliste

  • Guest-Agent auf allen QEMU-VMs installiert und gestartet
  • agent: 1 in der Proxmox-Config jeder QEMU-VM
  • Test-VMID weit weg vom Produktionsbereich (9900+)
  • Script mit --dry-run getestet
  • Erster echter Restore-Test bestanden
  • Cron oder Timer für wöchentliche Ausführung
  • Telegram/Mail/Webhook für Ergebnis-Benachrichtigung
  • ZFS-Speicher regelmäßig prüfen (Test-VMs brauchen temporär Platz)

Das komplette Script findest du als Open Source — es ist ein einzelnes Bash-File ohne Abhängigkeiten. Passe die VM-Liste, den PBS-Storage und die Telegram-Credentials an deine Umgebung an.