This commit is contained in:
Mateusz Gruszczyński committed 2026-10-08 11:27:18 +02:00
1 parent d940f9995f
commit 65e082b9d1
61 files changed
+1225 -581

No files matched your search

+20 -29
View File
@@ -1,38 +1,29 @@
# Verification report - RustProxy 0.28.1
# Verification report - RustProxy 0.28.2
## Scope
RustProxy 0.28.1 adds absolute external certificate/key paths for manual certificates while preserving the existing managed filename mode under `<data-dir>/certs`. The intended renewal path is Certbot/acme.sh updating `/etc/letsencrypt/live/...` followed by `POST /api/certificates/{certificate_id}/reload`. External paths are canonicalized on every load/reload so Certbot `live/` symlinks follow the current archive generation, then the final file is opened as a bounded regular file. Mixed managed/external pairs are rejected, certificate/key matching remains mandatory and managed private keys retain owner-only checks, while external keys may be `0640` for a restricted service group but cannot be group-writable, executable or world-accessible.
RustProxy 0.28.2 hardens the 0.28.1 external-certificate workflow. Absolute certificate/key paths are validated across the configured and resolved parent chains, the final file is opened with `O_NOFOLLOW`, POSIX ACL read access is supported without requiring an exact chmod value, private keys may not be world-readable, and external certificate/key files may not be group/world-writable. The packaged systemd service explicitly keeps `/etc/letsencrypt` and `/etc/ssl` read-only while normal Unix permissions/ACLs remain authoritative for access.
The targeted reload path remains revision-stable and republishes one immutable TLS snapshot. New public H1/H2/H3 handshakes use the refreshed material; invalid replacement files leave the previous snapshot active. The deploy endpoint refuses an ID configured with absolute external paths so a renewal wrapper cannot accidentally change storage ownership. Externally referenced files are excluded from RustProxy backups; only their configured paths survive, and the operator must restore or mount the external material separately.
Certificate automation is also narrowed. SQLite schema 9 adds per-Key-ID grants: new Certificate API tokens require explicit certificate IDs, are reload-only by default, cannot call the global all-certificate reload endpoint, and require an explicit deploy grant before `POST /api/certificates/deploy` is accepted. Credentials from earlier releases migrate to reload-only wildcard compatibility grants and should be rotated to explicit IDs.
The certificate UI now distinguishes RustProxy-managed filenames from external absolute paths and provides explicit English/Polish storage guidance for ACME, Import and Existing-files modes. 0.28.1 retains all 0.28.0 GeoIP direct-source/MMDB/hot-swap, listener protocol-badge, ACME runtime-reporting, cache Via/narrow invalidation and Security-editor behavior. SQLite schema 8 and COLD cache format 3 remain unchanged.
The release retains the 0.28.0 GeoIP direct-source/MMDB hot reload, listener protocol badges, cache Via/narrow invalidation, Security-editor layout and ACME runtime reporting. COLD cache format 3 and saved proxy configuration format remain unchanged.
## Verification status in this workspace
Rust/Cargo is not installed in this workspace. Rust-independent release checks can run here; compiler/type/runtime gates and real H2/H3 protocol execution require a Rust-enabled host.
## Release checks
## Verification
| Check | Result |
| --- | --- |
| Rust/source module contracts | PASS |
| GeoIP direct-source/optional-checksum/MMDB/manual endpoint/UI/hot-swap source contracts | PASS |
| Cache Via/narrow invalidation source contracts | PASS |
| Listener protocol-badge/header-editor UI source contracts | PASS |
| ACME startup reporting contract (no speculative banner state; final INFO event) | PASS |
| External certificate path / Certbot-symlink / managed-vs-external source contracts | PASS |
| Documentation and language-pack checks | PASS |
| Web Server, security and dependency source contracts | PASS |
| `tools/checks/check_source.py` | PASS (compiler/runtime explicitly not verified) |
| `tools/checks/release_smoke.py` | PASS |
| Python syntax (`py_compile`) and direct-CSV installer validation checks | PASS |
| Browser Web Service UI regression (`node tools/checks/web_service_ui_test.mjs`) | PASS |
| Docker Agent (`go test ./...`) | PASS |
| `./dev.sh test` static/pre-compiler stages | PASS; command then exits 127 at the Rust/Cargo gate |
| Rust `cargo fmt/check/test`, linking and Rust unit tests (including external-path/Certbot-symlink reload, synthetic standard/sapics/custom-MMDB lookup fixtures, GeoIP hot-swap, cache Via and cache-revision tests) | NOT VERIFIED - Cargo/Rust is not installed in this workspace |
| Live manual/automatic GeoIP direct-source download and real-world MMDB lookup | NOT VERIFIED - requires network access and a compiled 0.28.1 binary |
| Live external Certbot-path reload through `POST /api/certificates/{certificate_id}/reload` | NOT VERIFIED - requires a compiled 0.28.1 binary plus readable external certificate material |
| Live HTTP/2 + HTTP/3 protocol tests | NOT VERIFIED - requires a compiled 0.28.1 binary and QUIC-capable runtime |
|---|---|
| Source/static contracts | PASS - `tools/checks/check_source.py` |
| Documentation/index/link checks | PASS - `tools/checks/docs_check.py` |
| Browser-side JavaScript syntax/UI contracts | PASS - `./dev.sh test` pre-Cargo stages |
| SQLite schema-9 migration and release smoke | PASS - `tools/checks/release_smoke.py`, including legacy-token grant migration |
| Docker Agent Go tests | PASS - `go test ./...` |
| Shell/Python/JSON syntax checks | PASS - release/static checks plus explicit shell/JSON validation |
| `cargo fmt/check/test` | NOT VERIFIED - Rust/Cargo are not installed in this verification environment; `./dev.sh test` exits 127 only after all pre-Cargo gates pass |
| Live Certbot ACL + targeted API reload | NOT VERIFIED - requires a compiled binary and host certificate material |
| Live HTTP/2 + HTTP/3 protocol tests | NOT VERIFIED - requires a compiled binary and QUIC-capable runtime |
`./dev.sh test` is expected to exit with status 127 only when it reaches the Rust toolchain gate; all earlier release/static checks must complete successfully for this report to remain valid.
## Security regression coverage
The source tests include Certbot-style `live/ -> archive/` symlink refresh behavior, acceptance of ACL-style group-mask bits, rejection of group/world-writable or world-readable private-key modes, and rejection of writable non-sticky parent directories. Administration tests cover targeted certificate-ID grants, denial of global reload for Certificate API tokens, rejection of non-allowlisted certificate IDs and independent token revocation.
See [V0.28.2_IMPLEMENTATION.md](V0.28.2_IMPLEMENTATION.md) for the operator ACL example and migration behavior.