How it works
The technical background, for the curious. You don't need any of it to use pvebackup.
Two connections to each Proxmox host
- The Proxmox API (port 8006), read-only: nodes, guests, storages and the next free VMID. At sign-in the app creates
an API token for the user, so the password is not kept. A read-only user is enough here, e.g.
pvebackup@pvewith the role PVEAuditor on/. - SSH (port 22) for backups and restores. Data only moves inside this connection: no extra port is opened on the host or on the NAS. The host's SSH key is remembered at the first connection, and a changed key is refused.
Nothing is installed on the host
For each backup or restore the app sends a small helper script over SSH. It runs from memory with Proxmox's own Perl
modules and ends with the run. The only files it leaves on the host for the duration of a backup are a temporary image in
/var/tmp and a socket in /tmp; both are removed afterwards. Backups and restores appear in
Proxmox's task log, like its own.
Incremental backups of running VMs
- The snapshot. In one atomic QEMU transaction for all disks of the VM, the app starts a new dirty bitmap (a map of changed 4 MB blocks), stops the previous one and starts fleecing: before the VM overwrites a block, QEMU copies the old content to the temporary image. The VM keeps running and sees no difference. If the QEMU guest agent is installed, the guest's filesystems are frozen for this moment, so the snapshot is consistent.
- The export. QEMU serves the snapshot over NBD on a local socket on the host. The NAS reaches that socket through the SSH connection.
- Only changes. The app asks QEMU which blocks the previous backup's bitmap marks as changed and which are empty. Only changed blocks are read; the others are taken over from the previous backup without touching them.
- Only new data. The helper computes the SHA-256 of each block on the host first. Blocks the NAS already has (from any VM or version) are not sent at all.
- Clean up. After a successful backup the old bitmap is dropped and the new one keeps recording until the next backup. If a backup fails, the two are merged, so the next backup is still incremental.
A backup reads the whole disk when there is no bitmap to continue from: the first backup, after the VM was stopped or
restarted (QEMU keeps bitmaps in memory), or after a disk was resized. Thanks to step 4, even then only new data travels
to the NAS. Stopped VMs are read directly from their disk images (read-only, through qemu-nbd), empty areas are
skipped. Containers have no change tracking: they are read with vzdump each time, and the stream is cut into
content-defined chunks, so unchanged data is still stored only once.
How backups are stored
Everything is in the shared folder pvebackup. Data is kept as chunks named by their SHA-256, each stored once.
A backup version is a small file listing its chunks plus the VM's Proxmox configuration. That is why many versions take
little space. Deleting a version removes only that list; chunks no longer used by any version are removed afterwards.
Check backups for damage reads every chunk and verifies its hash: for chosen guests, a single backup (its
Actions menu), or on a schedule, which checks only guests with a new backup since their last check. A check that
finds damage sends an e-mail and calls the webhook, if they are switched on.
Restores
A restore to a new VMID allocates the disks on the chosen storage through Proxmox's storage layer, writes the data through
qemu-nbd and recreates the VM from the saved configuration. A restore task updates an existing copy in
place: only blocks that differ from the backup are written. After each update a Proxmox snapshot is kept as a sync point
(on storages with snapshots). A copy that was started since its last update is never overwritten: it may hold newer data,
so its restores pause until you resume them.
Reading files out of a backup
For Actions → Files… the app reads the stored blocks as a disk, straight from the NAS: it finds the partitions (GPT or MBR) and reads the filesystem structures of ext2/3/4 and NTFS itself, block by block, only what the folder or file you open needs. Nothing is mounted, unpacked or copied first, and the package still runs without root. A container backup is one archive; the app walks through it once and keeps a list of where each file starts.
Why the SSH login must be root
Dirty bitmaps, fleecing and the NBD export are only available through QEMU's control socket
(/var/run/qemu-server/<vmid>.qmp), which belongs to root. Proxmox's storage layer, which activates and
allocates volumes, and its tools qm, pct and vzdump also require root. The only
incremental backup without root is Proxmox's built-in backup to a Proxmox Backup Server. A sudo user limited to these
commands would not be safer: each of them can do anything as root.
To keep it tight, use the app's SSH key (Hosts → Change next to the host → SSH login: SSH key) and limit it to your NAS by putting
from="<NAS IP>" in front of it in /root/.ssh/authorized_keys. Don't add
no-port-forwarding or restrict: the app reaches the NBD socket through the SSH connection.
No internet needed
The app only connects to your Proxmox hosts (and scans your LAN when you use Scan LAN). It sends nothing anywhere else: no telemetry, and the license is checked offline. If you switch on e-mail notifications or the webhook, it also connects to the mail server or the URL you entered, only to send those messages.