This commit is contained in:
Mateusz Gruszczyński committed 2026-10-10 20:56:36 +02:00
1 parent f213d853e2
commit 76b8bb7ee2
78 files changed
+7750 -5204

No files matched your search

+21 -2
View File
@@ -7,6 +7,23 @@ certificate and persist a non-loopback bind; plain remote HTTP requires the expl
startup `--allow-remote-admin` gate. Responses carry no-store, CSP and other browser
protection headers.
## Public-vhost HTTP cache invalidation (opt-in)
`PURGE /path?query` and `BAN /prefix` operate on the normal public vhost
listener and **do not** use an admin session. They are independently denied by
default unless the administrator explicitly populates the cache's
`http_invalidation_allowed_cidrs` allowlist in **Settings → Cache**. Authorization
uses the existing trusted client-IP forwarding logic, vhost/host ACL and rate
limits. BAN is a lazy prefix rule; PURGE evicts an exact URL. Both are restricted
to the request scheme (`http` vs `https`), Host and matched vhost. A shared
two-worker maintenance guard also bounds administrator-driven invalidation;
additional requests receive 429. Ambiguous duplicate control headers and
request bodies are rejected. See
[CACHE](CACHE.md#http-ban--purge-from-authorized-client-ips) for request examples,
scoping, confirmation and reverse-proxy requirements, and
[0.31.0 security review](SECURITY_AUDIT_0.31.0.md) for audit findings. The authenticated
`/api/cache/invalidate` endpoint remains unchanged.
## Browser documentation and anonymous surface
Open `/docs` **on the administration listener** after signing in. The default **Reader**
@@ -72,6 +89,8 @@ framework extraction failures are not guaranteed to have that JSON shape.
| `GET /api/backends` | Authenticated per-vhost backend observations and active/desired frontend plans |
| `GET /api/status` | Uptime, active revision, configured counts, listener addresses, feature flags, aggregate metrics, active/desired TCP/UDP streams with per-stream L4 counters, active/desired administration state, TLS policy/cipher inventory and structured-log sink counters |
`GET /api/status?view=live` returns only volatile telemetry suitable for SSE fallback, without the heavy full configuration/OS/runtime objects. `GET /api/system-info` returns cached system diagnostics, host/runtime metadata and memory accounting under `system`, `runtime` and `memory_accounting`. Both are protected by the same cookie/origin admin guard as full status.
`status.streams` contains `active`, `desired`, `restart_required` and a `metrics` map keyed by startup-active stream ID. Stream counters include active/total/completed sessions, rejects, errors, RX/TX bytes and UDP packet counts; the dashboard derives rates from byte-counter deltas.
| `GET /api/logs` | Recent bounded access entries, ring capacity and contention-drop count |
| `GET /api/audit` | Last 100 audit entries; database retention is 10,000 |
@@ -83,9 +102,9 @@ Except for health and authentication/bootstrap routes, these endpoints require a
session. These administrative previews are not anonymous. The separate configurable
exporter uses its own CIDRs and optional bearer token; see the scrape section below.
SSE has eight viewer slots, generates a snapshot approximately every two seconds
SSE has eight viewer slots, generates a snapshot every 1/2/5/10 seconds per authenticated client (via `?interval=`, default 2)
and rechecks session validity. It does not queue an unlimited per-viewer event log
or guarantee replay. The browser falls back to polling. An active dashboard renews
or guarantee replay. The browser falls back to compact status/log polling only after SSE fails and stops polling after its recovery. Invalid SSE intervals are rejected with 422. An active dashboard renews
idle activity, not the absolute session deadline.
Configuration history, introduced in SQLite schema 8 and retained in current schema 9, keeps the newest 512 successful manual/configuration revisions. `GET /api/config/history` is session-protected like the rest of the administration API; `limit` is bounded to 512 and `revision` selects one retained revision for diff/inspection. `POST /api/config/history/restore` also requires the normal CSRF/request-marker protections, rejects stale `expected_revision`, and never rewinds the revision counter: restoring revision 85 while current revision is 120 creates revision 121.