Files
RustProxy/docs/V0.28.1_IMPLEMENTATION.md
T
2026-10-08 10:36:34 +02:00

47 lines
3.8 KiB
Markdown

# RustProxy 0.28.1 implementation note
## Scope
0.28.1 adds first-class support for certificate/key pairs that are managed outside the RustProxy data directory, with Certbot's `/etc/letsencrypt/live/...` layout as the primary operator case. It retains the managed filename mode under `<data-dir>/certs`, all 0.28.0 GeoIP/listener/cache/UI changes, SQLite schema 8 and COLD cache format 3.
## Certificate file modes
Manual certificate entries use the existing `cert_file` and `key_file` fields. Their addressing mode is derived without adding a database/configuration schema field:
- two simple filenames, for example `app.pem` and `app.key`, are resolved inside `<data-dir>/certs`;
- two absolute paths, for example `/etc/letsencrypt/live/example.com/fullchain.pem` and `/etc/letsencrypt/live/example.com/privkey.pem`, are read in place;
- mixed relative/absolute pairs are rejected.
Managed filenames retain the existing traversal protection and `O_NOFOLLOW` open behavior. Absolute external paths are bounded to 4096 bytes. Each external path is canonicalized at load/reload time, which intentionally resolves Certbot `live/` symlinks to the current generation under `archive/`; the resolved final file is then opened with `O_NOFOLLOW`, must be a regular file and remains subject to the 128 KiB PEM bound. Managed private keys remain owner-only. External private keys may grant read-only group access (for example `0640`) so the unprivileged `rustproxy` service can use a restricted TLS group, but they may not be executable, group-writable or world-accessible; every parent directory must also be traversable by the service identity.
The certificate/key pair is still parsed by rustls and must match. Config publication remains atomic: invalid or unreadable replacement material leaves the previous immutable TLS snapshot active.
## Renewal wrapper workflow
For an externally managed certificate, renew the files using Certbot/acme.sh/another issuer and then call:
```text
POST /api/certificates/{certificate_id}/reload
```
The endpoint re-reads configured files and republishes the complete immutable TLS/routing snapshot without changing the saved configuration revision. New HTTP/1.1, HTTP/2 and HTTP/3 handshakes use the refreshed certificate; established TLS sessions are not renegotiated. A selected administration certificate remains startup-fixed and reports that process restart is required.
Scoped Certificate API credentials can call the targeted reload endpoint. `POST /api/certificates/deploy` remains a PEM-body deployment API and deliberately refuses to overwrite an ID that is configured with absolute external file paths; this prevents a renewal owner from silently switching storage models.
## Backups
RustProxy full backups contain managed certificate material under `<data-dir>/certs`. Absolute external certificate/key files are not copied into the backup. Their configured paths remain in SQLite/configuration, so the files or mounts must exist separately on the restored host before TLS can be compiled successfully.
## Administration UI
Certificates -> Generate/Add -> Existing server files now has an explicit file-location selector:
- **RustProxy certificate directory (`<data-dir>/certs`)** accepts filenames only;
- **External files (absolute paths)** accepts complete server paths and shows a Certbot example.
English and Polish provider hints also explain that ACME modes generate/manage their own material, Import copies browser-selected PEM files into RustProxy storage, and Existing files references server-side material. Installed-certificate cards mark absolute-path entries as external.
## Compatibility
No migration is required from 0.28.0. Existing filename-only certificate entries keep their prior meaning. Existing deploy/upload/ACME flows continue to create RustProxy-managed filenames and never place PEM key bytes in configuration responses.