🛡️ Hardening Proxmox Backup Server: Secure Permissions & Sync Jobs

Standard Proxmox setups often use the root@pam account for everything. This is a massive security risk. If one PVE node is compromised, your entire backup history can be wiped. This guide shows you how to set up a dedicated user, an “Append-Only” API token, and a secure Pull Sync job. I also recommend reading the Proxmox Docs User Management — Proxmox Backup 4.1.2-1 documentation

1. Create the Dedicated Backup User

First, we create a user that is not root. This user will be our “Backup Manager.”

  1. Log into your PBS Web UI.
  2. Navigate to Configuration > Access Control > User Management.
  3. Click Add.
  • User ID: pve-backup-user
  • Realm: pbs
  • Click Create.

2. Generate the “Append-Only” API Token

Instead of giving your PVE node the user’s password, we use an API Token.

  1. Go to Access Control > API Token.
  2. Click Add.
  • User: pve-backup-user@pbs
  • Token ID: pve-node-01 (Use a unique ID for each PVE node).
  • Secret: Copy this immediately! It will only be shown once.

3. Permission Strategy

PBS permission model: A token can never do more than its owner. We must grant permissions to both the User and the Token on your Datastore path.

Step A: Grant User Permissions

This allows you, the human, to manage the backups when you log in.

  1. Go to Datastore > [Your Datastore] > Permissions.
  2. Click Add > User Permission.
  • Path: /datastore/your-ds-name (This limits the user to that datastore)
  • User: pve-backup-user@pbs
  • Choose Role:
    • DatastorePowerUser Can backup, restore, and prune owned backups.
    • DatastoreAdmin Can do anything on existing datastores.

Step B: Grant Token Permissions

This restricts the PVE node to a Read & Write but not Delete style of access.

  1. Click Add > API Token Permission allowing backups/restores, but NOT pruning or deletions
  • Path: /datastore/your-ds-name
  • Token: pve-backup-user@pbs!pve-node-01
  • Role: DatastoreBackup
  • Role: DatastoreReader

Why DatastoreBackup? This role allows the PVE node to create new backup groups and upload data chunks to the datastore. It is the “write” permission required for daily backups, but it does not allow the token to remove existing data or change datastore settings.

Why DatastoreReader? This role allows the PVE node to view the backup index, which is required to perform restores and to “verify” existing data. Crucially, it allows PVE to check which chunks already exist on the server; without it, deduplication efficiency can drop because PVE can’t “see” what it has already backed up.


4. Connecting PVE to PBS

On your Proxmox VE node:

  1. Go to Datacenter > Storage > Add > Proxmox Backup Server.
  2. ID: PBS-Secure
  3. Server: [PBS-IP]
  4. Username: pve-backup-user@pbs!pve-node-01
  5. Password: [Your-Token-Secret]
  6. Fingerprint: (Copy from the PBS Dashboard “Show Fingerprint” button).

5. Setting Up a Secure “Pull” Target

If you have an offsite PBS server that needs to PULL backups from your local server, you should create a dedicated user. This ensures that even if the offsite server is compromised, the attacker only has “Read-Only” access to your local backups.

Step A: Create the “Sync-Pull” User

  1. Go to Configuration > Access Control > User Management.
  2. Click Add.
  • User ID: remote-pull-user
  • Realm: pbs
  1. Create an API Token for this user called offsite-token.

Step B: Assign “Read-Only” Permissions

You want the remote server to be able to see and copy the data, but never modify or delete it.

  1. Go to Datastore > [Your Datastore] > Permissions.
  2. Add the following API Token Permission and User Permission:
  • Path: /datastore/your-ds-name
  • Token: remote-pull-user@pbs!offsite-token
  • Role: DatastoreReader

Why DatastoreReader? This role allows the remote server to view the backup index and download the data chunks. It does not allow the remote server to delete backups (Prune) or upload new data (Backup).

Step C: Provide Credentials to the Remote Admin

To complete the link, provide the following to the administrator of the offsite PBS:

  1. Your Server IP:PORT
  2. The Token ID: remote-pull-user@pbs!offsite-token
  3. The Token Secret
  4. Your Fingerprint (Found on your PBS Dashboard).

Step D: Creating the Sync Job (On the Offsite PBS)

Now, move to the Offsite/Remote PBS and log in as a user that has the permissions RemoteAdmin to configure the pull:

  1. Add the Remote: Go to Configuration > Remotes and use the credentials from Step C.
  2. Create Sync Job: Navigate to Datastore > [Target Datastore] > Sync Jobs.
  3. Configure the Pull:
  • Source Remote: Select the remote you just created.
  • Source Datastore: Type in the name of the datastore on the original server.
  • Local Owner: Set this to your local pve-backup-user@pbs (not root!).
  • Remove Vanished: * Unchecked (Recommended): If a backup is deleted on your local server, the offsite server keeps its copy. This is your safety net against local deletions.
    • Checked: The offsite server will mirror the local server exactly, deleting its own copies to match the source.
  1. Maintenance: Ensure you have Prune & GC jobs scheduled on this offsite server so it doesn’t eventually run out of space as it accumulates data.

:light_bulb: Summary & Housekeeping

Always handle Pruning and Garbage Collection on the PBS side under the “Jobs” tab. Since your PVE node only has DatastoreBackup rights, it cannot be forced to delete its own backups even if it’s compromised! Do the same if you have a remote PBS server pulling backups from your local PBS.

The Strategy: Local PVE → Local PBS → Remote PBS (Pull)

Here is why this specific flow is superior to backing up directly to a remote site

1. Speed and “Reduced Backup Window”

  • Local Speed: Backing up from PVE to a local PBS typically happens over a fast local connection. This keeps your “backup window” (the time your VMs are under snapshot stress) as short as possible.
  • Background Syncing: Once the data is on the local PBS, the Sync Job to the remote site happens in the background. It doesn’t matter if the sync takes 5 hours over a slow WAN; your PVE VMs are already “safe” and running at full speed again.

2. Efficiency Over WAN

  • Chunk-Based Transfer: Because PBS uses chunk-based deduplication and content-addressed storage, the remote datastore only receives chunk hashes it does not already contain. Once common OS blocks are present remotely, they are never sent again.

3.Security Why Use “Pull”

  • The Logic: By having the Remote PBS pull from the local one, the remote site holds only read only credentials.
  • One-Way Traffic: Your production network (Local PVE/PBS) does not need login access to your offsite vault. If a threat actor wipes your local network, they cannot use local credentials to reach out and wipe the remote backups because the local side never had “Write” access to the remote side.

4. Reliability and Integrity

  • Local Verification: You can run “Verify Jobs” locally on PBS to ensure the backup is good before sending it offsite.
  • Network Resilience: If your internet goes out, the local backups still succeed. The Sync Job will simply catch up automatically once the connection is restored.
3 Likes

Ciao @LTS_Tom do you know if it is possible to set different retentions (so different prune jobs) without using different namespaces?

I don’t like the idea to “mount” multiple times the same pbs (but with different namespaces like important, normal, trash) on pve

I have some vm I use for test and I don’t want/dont’ need a daily backup, same for other vms with large disks like windows that I barely use.

Thanks :slight_smile:

Not that I am aware of.

oky thanks I will mount the 3 namespaces :+1: