SHA256
316 lines
9.6 KiB
Markdown
316 lines
9.6 KiB
Markdown
# pbc
|
|
|
|
A Bash wrapper around Proxmox's `proxmox-backup-client` for Proxmox Backup Server (PBS).
|
|
|
|
It keeps the repository, credentials and the list of paths to back up in a single config
|
|
file, injects the configured namespace (`--ns`) and encryption key (`--keyfile`) into every
|
|
command that needs them, and lets you pick a snapshot group, snapshot and archive from an
|
|
interactive menu instead of typing them out. Any command it does not implement itself is
|
|
passed straight through to `proxmox-backup-client`.
|
|
|
|
## Requirements
|
|
|
|
- A Debian-based host with `bash` and `curl`
|
|
- `jq` and `proxmox-backup-client` — both installed by `pbc install`
|
|
- A reachable PBS with a datastore and an API token
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
curl -fsSL https://git.ccc-rheintal.ch/spacefreak/pbc/raw/branch/master/install.sh | sudo bash
|
|
```
|
|
|
|
This installs the newest tagged version to `/usr/local/bin/pbc`, installs the
|
|
dependencies, and puts an example config at `/etc/pbc/config.example`.
|
|
|
|
### Installing a specific version
|
|
|
|
Set `PBC_GIT_TAG` to install that tag instead of the newest one:
|
|
|
|
```bash
|
|
curl -fsSL https://git.ccc-rheintal.ch/spacefreak/pbc/raw/branch/master/install.sh | sudo PBC_GIT_TAG=v1.0.0 bash
|
|
```
|
|
|
|
`sudo` drops the environment, so set the variable on the `sudo` command itself (or use
|
|
`sudo -E`), not before `curl`. Any Git ref works, e.g. a branch name for testing.
|
|
|
|
### Updating
|
|
|
|
Run the same command again to update `pbc` itself:
|
|
|
|
```bash
|
|
curl -fsSL https://git.ccc-rheintal.ch/spacefreak/pbc/raw/branch/master/install.sh | sudo bash
|
|
```
|
|
|
|
It fetches the newest tag and overwrites `/usr/local/bin/pbc`. Your `/etc/pbc/config` is
|
|
left untouched. `PBC_GIT_TAG` works here too, to pin or roll back to a given version.
|
|
|
|
To update only the `proxmox-backup-client` binary:
|
|
|
|
```bash
|
|
sudo pbc install --update
|
|
```
|
|
|
|
This is skipped when the client is managed by the package manager — use `apt` in that case.
|
|
|
|
## Configuration
|
|
|
|
```bash
|
|
sudo cp /etc/pbc/config.example /etc/pbc/config
|
|
sudo chmod 640 /etc/pbc/config
|
|
sudo editor /etc/pbc/config
|
|
```
|
|
|
|
| Key | Description |
|
|
|---|---|
|
|
| `PBS_SERVER` | PBS host and port |
|
|
| `PBS_USER` | User and API token name, `user@realm:token-name` |
|
|
| `PBS_PASSWORD` | The API token secret |
|
|
| `PBS_DATASTORE` | Datastore to back up to |
|
|
| `PBS_NAMESPACE` | Optional, namespace inside the datastore |
|
|
| `BACKUP` | Array of `archive-name.pxar:/path` entries to back up |
|
|
| `ENCRYPTION_KEYFILE` | Optional, path to the client encryption key — see [Encryption](#encryption) |
|
|
| `PBC` | Optional, path to `proxmox-backup-client` (default `/usr/local/bin/proxmox-backup-client`) |
|
|
|
|
`pbc` never creates the config for you — copy the example and edit it yourself. The file
|
|
has to be readable for the user that runs `pbc`, so if that is not root, hand
|
|
it over:
|
|
|
|
```bash
|
|
sudo chown youruser /etc/pbc/config
|
|
```
|
|
|
|
The config is sourced as Bash and contains your token secret. `pbc` refuses to run if the
|
|
file is writable by group or others, and warns if it is readable by others.
|
|
|
|
Check that it works:
|
|
|
|
```bash
|
|
pbc list
|
|
```
|
|
|
|
Use a different config with `-c`:
|
|
|
|
```bash
|
|
pbc -c ./myconfig list
|
|
```
|
|
|
|
## Encryption
|
|
|
|
Backups can be encrypted client-side, so PBS only ever sees ciphertext. Create a key and
|
|
point `ENCRYPTION_KEYFILE` at it:
|
|
|
|
```bash
|
|
sudo proxmox-backup-client key create /etc/pbc/backup.key --kdf none
|
|
sudo chmod 600 /etc/pbc/backup.key
|
|
```
|
|
|
|
`pbc` errors out if the key is missing or unreadable, and warns if it is readable by
|
|
others. As with the config, the file has to be readable for the user that runs `pbc` —
|
|
`sudo chown youruser /etc/pbc/backup.key` if that is not root.
|
|
|
|
**Back the key up somewhere else.** Without it the backups are unrecoverable, and a key
|
|
stored only on the machine you are backing up is gone exactly when you need it. Print a
|
|
recovery sheet and keep it off-host:
|
|
|
|
```bash
|
|
sudo proxmox-backup-client key paperkey /etc/pbc/backup.key
|
|
```
|
|
|
|
`--kdf none` leaves the key unprotected on disk, which is what makes unattended backups
|
|
possible. With a passphrase-protected key (`--kdf scrypt`) the client prompts on every run
|
|
and `backup-cron` hangs; export `PBS_ENCRYPTION_PASSWORD` in that case.
|
|
|
|
The key is passed to `backup`, `backup-cron`, `mount` and `catalog-shell`. It is *not*
|
|
passed to commands that fall through to `proxmox-backup-client` — `pbc restore` needs both
|
|
flags spelled out:
|
|
|
|
```bash
|
|
pbc restore --ns MyBackups --keyfile /etc/pbc/backup.key \
|
|
host/myhost/2026-08-24T01:00:00Z root.pxar /mnt/restore
|
|
```
|
|
|
|
Setting `ENCRYPTION_KEYFILE` only affects snapshots made from then on. Older unencrypted
|
|
snapshots stay readable, and listing works without the key either way — only reading
|
|
archive contents needs it.
|
|
|
|
## Usage
|
|
|
|
Run `pbc --help` for the synopsis and the list of options, or `pbc -H` to additionally
|
|
list every command of `proxmox-backup-client`. The commands `pbc` implements itself are
|
|
described below.
|
|
|
|
### backup
|
|
|
|
Back up everything listed in `BACKUP` and print the client output:
|
|
|
|
```bash
|
|
pbc backup
|
|
```
|
|
|
|
Extra arguments are forwarded to the client:
|
|
|
|
```bash
|
|
pbc backup --exclude '/mnt/data/cache'
|
|
```
|
|
|
|
### backup-cron
|
|
|
|
Same backup, but output is suppressed unless it fails — so cron only mails you on errors:
|
|
|
|
```cron
|
|
0 3 * * * /usr/local/bin/pbc backup-cron
|
|
```
|
|
|
|
### list
|
|
|
|
List backup groups with their latest snapshot and archives:
|
|
|
|
```bash
|
|
pbc list
|
|
```
|
|
|
|
### snapshot-list
|
|
|
|
List snapshots of a group with sizes and archives. Without an argument you get a menu of
|
|
the available groups:
|
|
|
|
```bash
|
|
pbc snapshot-list
|
|
pbc snapshot-list host/myhost
|
|
```
|
|
|
|
### mount
|
|
|
|
Mount a single archive of a snapshot on a local directory. Anything you leave out is
|
|
asked for interactively:
|
|
|
|
```bash
|
|
pbc mount
|
|
pbc mount host/myhost/2026-08-24T01:00:00Z root.pxar /mnt/restore
|
|
```
|
|
|
|
The target directory is not created for you — create it beforehand and make sure it is
|
|
writable for the user that runs `pbc`. Encrypted archives are decrypted transparently when
|
|
`ENCRYPTION_KEYFILE` is configured. Unmount when done:
|
|
|
|
```bash
|
|
umount /mnt/restore
|
|
```
|
|
|
|
### catalog-shell
|
|
|
|
Open an interactive shell to browse an archive and restore selected files — see below.
|
|
Encrypted archives are decrypted transparently when `ENCRYPTION_KEYFILE` is configured.
|
|
|
|
```bash
|
|
pbc catalog-shell
|
|
pbc catalog-shell host/myhost/2026-08-24T01:00:00Z root.pxar
|
|
```
|
|
|
|
### install
|
|
|
|
Install or update the dependencies. Requires root:
|
|
|
|
```bash
|
|
sudo pbc install
|
|
sudo pbc install --update
|
|
```
|
|
|
|
## Restoring files
|
|
|
|
### Selectively, with `catalog-shell`
|
|
|
|
```bash
|
|
pbc catalog-shell
|
|
```
|
|
|
|
Pick a snapshot and an archive from the menu, then browse the archive as if it were a
|
|
filesystem and mark what you want back:
|
|
|
|
```
|
|
pxar:/ > cd etc
|
|
pxar:/etc > ls
|
|
pxar:/etc > select hosts
|
|
pxar:/etc > find etc/nginx/** --select
|
|
pxar:/etc > list-selected
|
|
pxar:/etc > restore-selected /mnt/restore
|
|
pxar:/etc > exit
|
|
```
|
|
|
|
- `ls`, `cd`, `pwd`, `stat` — browse the archive
|
|
- `select <path>` — mark a single file, relative to the current directory
|
|
- `find <pattern> --select` — mark everything matching a glob
|
|
- `deselect <path>` / `clear-selected` — drop one entry or all of them
|
|
- `list-selected` — show what is currently marked
|
|
- `restore-selected <target>` — restore only the marked entries
|
|
- `restore <target> [pattern]` — restore the current directory and everything below it
|
|
- `help` — list all available shell commands
|
|
- `exit` — leave the shell
|
|
|
|
#### Selecting a directory and everything beneath it
|
|
|
|
`select` marks exactly the entry you give it and nothing else. Marking a directory
|
|
therefore restores an empty directory — its contents are *not* included. Use a glob with
|
|
`find --select` instead:
|
|
|
|
```
|
|
pxar:/ > find etc/nginx/** --select
|
|
pxar:/ > select etc/nginx
|
|
pxar:/ > restore-selected /mnt/restore
|
|
```
|
|
|
|
The `find` line picks up everything below `etc/nginx`; the `select` line adds the
|
|
directory itself, so its own permissions and ownership are restored as well.
|
|
|
|
Note that `find` patterns are always matched against paths relative to the archive root,
|
|
no matter which directory you are in, and that `find` scans the whole archive — expect it
|
|
to take a while on large backups.
|
|
|
|
The target path must not exist yet; the restore creates it. Its parent directory has to be
|
|
writable for the user that runs `pbc`.
|
|
|
|
### Everything, or with normal tools
|
|
|
|
To copy files out with `cp`, `rsync` or a file manager, mount the archive instead:
|
|
|
|
```bash
|
|
mkdir -p /mnt/restore # must exist and be writable for the user running pbc
|
|
pbc mount
|
|
cp -a /mnt/restore/etc/nginx /etc/nginx
|
|
umount /mnt/restore
|
|
```
|
|
|
|
## Running in WSL
|
|
|
|
`pbc` also works inside a Debian-based WSL instance, which makes it a way to back up
|
|
Windows directories: the Windows drives show up under `/mnt`, so they can be listed in
|
|
`BACKUP` like any other path.
|
|
|
|
```bash
|
|
BACKUP=('users.pxar:/mnt/c/Users' 'projects.pxar:/mnt/d/projects')
|
|
```
|
|
|
|
A few things to keep in mind:
|
|
|
|
- Access to files under `/mnt` is governed by Windows, not by the user you are inside the
|
|
WSL instance — `sudo` does not help there. To back up paths your Windows user cannot
|
|
read, start the WSL instance itself as administrator (run the terminal or `wsl.exe` via
|
|
*Run as administrator*), then run `pbc` in it.
|
|
- The owner and permission metadata stored in the archive is the one WSL synthesizes for
|
|
Windows files, not the original Windows ACLs.
|
|
- Cron is not running in a WSL instance by default, so `backup-cron` only fires if you
|
|
enable it — either by starting `cron` yourself, or by triggering `pbc backup-cron` from
|
|
the Windows Task Scheduler with `wsl.exe`:
|
|
|
|
```
|
|
wsl.exe -d Debian -u root /usr/local/bin/pbc backup-cron
|
|
```
|
|
|
|
For the reason above, such a task has to run with highest privileges to reach files that
|
|
are not accessible to your Windows user.
|
|
|
|
## License
|
|
|
|
GPLv3 — see [LICENSE](LICENSE).
|