backup: the panel's archive is the command's, private key included
Owner, 2026-10-11: the private key is needed, and a backup from the panel and one from the console have to be the same. The commit that made the panel's backup work skipped a file under certs/ the panel could not open - on the test server the private key, which the certificate hook leaves to root and Postfix's group. That gave an archive with a certificate and no key, and two kinds of archive. - Params.Unprivileged is gone. Nothing is left out on account of who makes the archive; the queue is out for everyone (previous commit). - When the panel cannot read a file under certs/, backup.Check says so before the download and the panel refuses with what to do on the host: chgrp 998 certs/privkey.pem && chmod 640. backup.UnreadableCert tells that case from any other failure. - 998 is the container's selfpost group, which holds the panel and Postfix. Its id was whatever groupadd gave; the Dockerfile now fixes it at the value it has always had, because an operator addresses it by number from the host. - Guide: method 1 is the same archive as method 2, with the permission the key needs and a note for whatever renews the certificate. Help and the box follow the design commit before this one. - e2e: the restore scenario first makes the key unreadable and expects the refusal naming the file and the way out, then takes the backup and expects the key in it; nothing is put back by hand before the restart. go vet ./internal/backup/ ./internal/web/handlers/: ok go test ./internal/backup/ ./cmd/... ./internal/web/...: ok make e2e on the test server: ok Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+16
-8
@@ -560,17 +560,25 @@ instance keeps running, what goes into the archive, and what happens on restore.
|
||||
|
||||
**1. Panel — while the container is running (no downtime).** *Server › Backup*
|
||||
→ *Full backup*. *Encrypt with a password* is ticked; untick it for a plain
|
||||
archive. The archive of the CLI below, less one thing the panel may not read:
|
||||
it runs as its own user, not as root, and **a file in `certs/` it cannot open**
|
||||
is left out — usually the private key (the panel's log names it). Put the key
|
||||
back into `certs/` before starting a restored instance. If anything else
|
||||
cannot be read, the panel says so and downloads nothing.
|
||||
archive. Same archive as the CLI below. The panel runs as its own user, not as
|
||||
root, so **the private key in `certs/` has to be readable by it**: give the
|
||||
file to the container's `selfpost` group, which has the fixed id 998 and holds
|
||||
both the panel and Postfix —
|
||||
|
||||
```sh
|
||||
chgrp 998 certs/privkey.pem && chmod 640 certs/privkey.pem
|
||||
```
|
||||
|
||||
— and have whatever renews the certificate do the same (a certbot deploy hook,
|
||||
for one). A key readable by root alone is enough for Postfix, but then the
|
||||
panel refuses to make a backup and names the file: it does not hand over an
|
||||
archive without the key.
|
||||
|
||||
**2. `selfpost-backup` CLI — while the container is running (no downtime).**
|
||||
The panel button and this command call the same code path: a consistent SQLite
|
||||
snapshot via `VACUUM INTO`, then a gzip tar of `data/` (minus diagnostics) plus
|
||||
deploy files. `docker exec` runs the command as root, so this archive has
|
||||
everything in `certs/`, the private key included.
|
||||
deploy files. `docker exec` runs the command as root, so it reads the private
|
||||
key whatever its permissions.
|
||||
|
||||
```sh
|
||||
docker exec <container> selfpost-backup > selfpost-backup.tar.gz
|
||||
@@ -626,7 +634,7 @@ methods avoid it by stopping first.
|
||||
| SQLite consistency | `VACUUM INTO` snapshot | Safe when stopped | Safe when stopped |
|
||||
| `data/log/` | Excluded | Included (optional exclude) | Included (optional exclude) |
|
||||
| Postfix queue | No | Yes | Yes |
|
||||
| `certs/` private key | CLI: yes. Panel: only if the panel may read it | Yes | No — deploy files separate |
|
||||
| `certs/` private key | Yes (the panel needs it readable by group 998) | Yes | No — deploy files separate |
|
||||
| `data/manifest.json` | Written (version stamp) | Absent | Absent |
|
||||
| Restore version check | Yes — must match image tag | No | No |
|
||||
| Post-restore *Resync* | Yes, on first boot | No | No |
|
||||
|
||||
Reference in New Issue
Block a user