3.8 KiB
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.pemandapp.key, are resolved inside<data-dir>/certs; - two absolute paths, for example
/etc/letsencrypt/live/example.com/fullchain.pemand/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:
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.