commit 99c716d35b4db23fa0fe68ec81379c0a941fad81 Author: Christoph Haas Date: Sat Sep 19 20:02:15 2026 +0000 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3532a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Secrets — never commit the real env file +backup.env diff --git a/README.backup.md b/README.backup.md new file mode 100644 index 0000000..9038144 --- /dev/null +++ b/README.backup.md @@ -0,0 +1,152 @@ +# 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 | +| `backup.sh` | Full backup of `/` with client-side encryption | +| `restore.sh` | FUSE-mount the encrypted backup to browse/restore files | +| `/etc/proxmox-backup/encryption-key.pem` | Client-side encryption key (store a copy off-host!) | +| `/etc/proxmox-backup/defaults.exclude` | Paths excluded from the backup | + +## 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 `/etc/proxmox-backup/defaults.exclude` + (`/proc`, `/sys`, `/dev`, `/run`, `/tmp`, …). +3. Runs: + + ``` + proxmox-backup-client backup "${HOSTNAME}-root.pxar:/" \ + --keyfile /etc/proxmox-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: `/etc/proxmox-backup/encryption-key.pem` +- Fingerprint: `proxmox-backup-client key show /etc/proxmox-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 ` (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 # 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 search entries +select mark an entry for restore +deselect unmark an entry +list-selected show what is marked +restore-selected 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//