168 lines
5.7 KiB
Markdown
168 lines
5.7 KiB
Markdown
# PBS Backup helper
|
|
|
|
Client-side encrypted backups of a host to a Proxmox Backup Server (PBS)
|
|
that is **outside our control**.
|
|
|
|
Everything lives in `/opt/backup/`. The connection details and credentials
|
|
(server, datastore, namespace, API token, encryption key) are kept in
|
|
`backup.env` (git-ignored); see `backup.env.sample` for the format.
|
|
|
|
## Files
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `backup.env` | Shared config: server, datastore, namespace, token, key (sourced by both scripts) |
|
|
| `backup.env.sample` | Template — copy to `backup.env` and fill in real values |
|
|
| `setup.sh` | Install the client and create the encryption key (run once as root) |
|
|
| `backup.sh` | Full backup of `/` with client-side encryption |
|
|
| `restore.sh` | FUSE-mount the encrypted backup to browse/restore files |
|
|
| `/opt/backup/encryption-key.pem` | Client-side encryption key (store a copy off-host!) |
|
|
| `/opt/backup/exclude` | Paths excluded from the backup |
|
|
|
|
## Setup
|
|
|
|
On a fresh host, as root:
|
|
|
|
```sh
|
|
git clone https://git.workaround.org/chaas/proxmox-backup-helper /opt/backup
|
|
|
|
cd /opt/backup
|
|
|
|
./setup.sh
|
|
cp backup.env.sample backup.env
|
|
vi backup.env # fill in server, datastore, namespace, token
|
|
chmod 600 backup.env
|
|
```
|
|
|
|
## How `backup.sh` works
|
|
|
|
1. Sources `backup.env`, which exports the connection/auth settings (server,
|
|
datastore, port, API token) as separate `PBS_*` component variables. This
|
|
matters: `PBS_AUTH_ID` is only honoured when `PBS_REPOSITORY` is *not* set.
|
|
2. Builds `--exclude` flags from `/opt/backup/exclude`
|
|
(`/proc`, `/sys`, `/dev`, `/run`, `/tmp`, …).
|
|
3. Runs:
|
|
|
|
```
|
|
proxmox-backup-client backup "${HOSTNAME}-root.pxar:/" \
|
|
--keyfile /opt/backup/encryption-key.pem \
|
|
--ns "$BACKUP_NS" \
|
|
--exclude /proc/* ...
|
|
```
|
|
|
|
4. The client encrypts everything locally before uploading. The PBS only ever
|
|
stores ciphertext and cannot read the data.
|
|
|
|
Encryption is client-side. The key file has no password (`kdf: none`), so
|
|
**possession of the key file alone is enough to decrypt** — protect it.
|
|
|
|
## What to store elsewhere (critical)
|
|
|
|
The **encryption key is the only thing that makes the backups readable**. If
|
|
this host and the key are both lost, the backup is unrecoverable — no one at
|
|
the PBS provider can help.
|
|
|
|
- File: `/opt/backup/encryption-key.pem`
|
|
- Fingerprint: `proxmox-backup-client key show /opt/backup/encryption-key.pem`
|
|
|
|
Keep a copy somewhere safe that is **not this machine**:
|
|
- offline USB stick / printed paperkey
|
|
- password manager
|
|
- another trusted host
|
|
|
|
Also record (or be able to re-issue) the API token secret, so you can reach the
|
|
datastore at all. Losing the token costs you access; losing the key costs you
|
|
the data.
|
|
|
|
## How to restore files
|
|
|
|
`restore.sh` has three modes. Pick based on how much you need back.
|
|
|
|
Unless you pass a snapshot explicitly, each mode first lists the available
|
|
snapshots and prompts you to pick one (default: the most recent). You can skip
|
|
the prompt with `--snapshot <ref>` (or the positional snapshot on `mount`).
|
|
|
|
For a few files, the FUSE mount is the fastest option (random access, only
|
|
reads the path you touch). `restore --pattern` is the slowest (streams the
|
|
whole archive); `shell` + `restore-selected` sits in between.
|
|
|
|
### FUSE mount — browse, or restore a few files
|
|
|
|
```
|
|
./restore.sh # mount latest snapshot at /mnt/pbs-restore
|
|
./restore.sh /mnt/restore <snapshot> # mount a specific snapshot
|
|
```
|
|
|
|
Then browse `/mnt/pbs-restore` and copy out what you need. Unmount with:
|
|
|
|
```
|
|
umount /mnt/pbs-restore
|
|
```
|
|
|
|
The mount does random access, so it only downloads the chunks for the files
|
|
you actually read. That's cheap for a handful of files, but slow to walk a
|
|
large tree (each file is a round-trip).
|
|
|
|
### Bulk restore — a whole directory or many files
|
|
|
|
```
|
|
./restore.sh restore /restore/var/vmail "var/vmail/example.com/*"
|
|
```
|
|
|
|
Streams the archive sequentially and extracts the matching paths — the fast
|
|
way to get a large directory or many files back. Patterns are globs against
|
|
paths inside the archive and may be repeated; with none, the whole archive is
|
|
extracted:
|
|
|
|
```
|
|
./restore.sh restore /mnt/full-restore
|
|
```
|
|
|
|
Note: pattern restore always reads the whole archive (it streams and filters),
|
|
so it's wasteful for one or two files — use the mount for those.
|
|
|
|
### Interactive shell — browse and selectively restore
|
|
|
|
```
|
|
./restore.sh shell
|
|
```
|
|
|
|
Drops into an interactive shell that navigates the backup via the catalog
|
|
metadata, so browsing is fast (it doesn't read the archive). Useful commands:
|
|
|
|
```
|
|
ls [path] list the current directory
|
|
cd [path] change directory
|
|
pwd print current directory
|
|
find <pattern> search entries
|
|
select <path> mark an entry for restore
|
|
deselect <path> unmark an entry
|
|
list-selected show what is marked
|
|
restore-selected <target> restore everything marked
|
|
exit quit
|
|
```
|
|
|
|
Note: `restore-selected` is catalog-driven — it reads only matched files'
|
|
data, not the whole archive — but it still walks the entire catalog and fetches
|
|
per-directory pxar metadata from the archive, so it's ~a minute on a large
|
|
tree, not instant. For one or two files, `mount` + `cp` is much faster.
|
|
|
|
### Manual `restore` (advanced)
|
|
|
|
First source the shared config (`source /opt/backup/backup.env`), then:
|
|
|
|
```
|
|
proxmox-backup-client restore host/<hostname>/<time> <hostname>-root.pxar /restore/dir \
|
|
--ns <namespace> \
|
|
--keyfile /opt/backup/encryption-key.pem \
|
|
--pattern "etc/postfix/main.cf"
|
|
```
|
|
|
|
## Snapshots
|
|
|
|
The snapshot reference has the form `<type>/<id>/<UTC-time>`, e.g.
|
|
`host/<hostname>/2026-09-19T10:36:14Z`. List available snapshots with:
|
|
|
|
```
|
|
proxmox-backup-client snapshot list host/<hostname> --ns <namespace>
|
|
```
|