v0.25.0
This commit is contained in:
1 parent
2e4aa4df4d
commit
87e571c170
106 files changed
+17952
-6185
No files matched your search
@@ -2,7 +2,7 @@
|
||||
> validated hot deployment. Initial issuance/import remains explicit. Read
|
||||
> [RENEWAL.md](RENEWAL.md) for defaults, retained profiles and opt-out.
|
||||
|
||||
# Certificate providers (0.6.0)
|
||||
# Certificate providers
|
||||
|
||||
Source implementation; real provider/DNS/CA issuance and Rust runtime have not been
|
||||
verified in the packaging environment. Offline tests substitute Certbot, so they
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Basic Let's Encrypt / RFC2136 integration (0.5.0)
|
||||
# Basic Let's Encrypt / RFC2136 integration - historical 0.5.0 record
|
||||
|
||||
> Historical implementation record. For current certificate-provider behavior, use [ACME_PROVIDERS.md](ACME_PROVIDERS.md) and [RENEWAL.md](RENEWAL.md).
|
||||
|
||||
For the multi-provider UI, HTTP-01, Cloudflare and OVH, see ACME_PROVIDERS.md.
|
||||
Managed automatic renewal added in 0.7 is documented in RENEWAL.md.
|
||||
|
||||
+13
-6
@@ -9,12 +9,14 @@ protection headers.
|
||||
|
||||
## Browser documentation and anonymous surface
|
||||
|
||||
Open `/docs` **on the administration listener** after signing in. The OpenAPI JSON,
|
||||
JavaScript, styles and Swagger vendor assets all require the same session. Writes
|
||||
are opt-in and CSRF-protected. See [API_ACCESS.md](API_ACCESS.md).
|
||||
Open `/docs` **on the administration listener** after signing in. The default **Reader**
|
||||
shows the bundled project Markdown documentation; the separate **API** tab renders the
|
||||
OpenAPI/Swagger interface. The documentation bundle, OpenAPI JSON, JavaScript, styles and
|
||||
Swagger vendor assets all require the same session. API writes are opt-in and CSRF-protected.
|
||||
See [API_ACCESS.md](API_ACCESS.md).
|
||||
|
||||
Only GET/HEAD `/`, the panel routes `/overview`, `/vhosts`, `/streams`,
|
||||
`/acl-profiles`, `/configuration`, `/tls`, `/cache`, `/logging`, `/settings`,
|
||||
`/acl-profiles`, `/web-server`, `/configuration`, `/tls`, `/cache`, `/logging`, `/settings`,
|
||||
`/assets/login.js`, `/assets/login-langs.json`, `/assets/style.css`, `/favicon.svg`,
|
||||
`/healthz`, `/api/auth/status`, and POST `/api/auth/setup`, `/api/auth/login` are
|
||||
anonymous. Panel routes serve the same guarded shell as `/`, so a browser refresh
|
||||
@@ -91,14 +93,14 @@ after the detached writer starts does not cancel an accepted write.
|
||||
The document limit is 256 KiB, with an additional 1024-byte request-envelope allowance.
|
||||
For ordinary Settings saves prefer `PUT /api/config/{section}`. Supported sections are
|
||||
`listeners`, `response`, `cache`, `logging`, `forwarding`, `headers`, `prometheus`,
|
||||
`administration`, `tls`, `vhosts`, `redirects`, `not_found_hosts`, `streams`, `acl-profiles` and `host-policies`.
|
||||
`administration`, `tls`, `vhosts`, `web-services`, `redirects`, `not_found_hosts`, `streams`, `acl-profiles` and `host-policies`.
|
||||
Each section write still uses revision CAS, full validation and atomic persistence.
|
||||
Only a change to the derived cache-compatibility identity purges hot/cold cache;
|
||||
unrelated section saves do not.
|
||||
|
||||
## Configuration fields
|
||||
|
||||
The canonical document uses `vhosts`, `redirects`, `listeners`, `administration`, `tls`, `logging`,
|
||||
The canonical document uses `vhosts`, `web_services`, `redirects`, `listeners`, `administration`, `tls`, `logging`,
|
||||
`prometheus`, `cache`, `compression`, `server_header`, `headers`, `host_policies` and other defaulted
|
||||
settings. Unknown fields are rejected. `backends`/`routes` at the top level are
|
||||
input-only legacy migration fields, omitted from saved canonical documents.
|
||||
@@ -204,6 +206,11 @@ The language bundle is generated by build.rs from langs/*.json and embedded into
|
||||
binary; uploading a new file requires recompilation/restart. It exposes public
|
||||
translations only, not filesystem paths, administrator data or credentials.
|
||||
|
||||
|
||||
### Web Services
|
||||
|
||||
`web_services` contains reusable static-file service definitions. Use `PUT /api/config/web-services` to replace that section with revision CAS. A vhost or location selects `{ "type": "web_server", "web_service_id": "..." }`; an omitted `source` remains `{ "type": "reverse_proxy" }` for compatibility. Filesystem settings remain on the Web Service and are not duplicated inside vhosts. See [WEB_SERVER.md](WEB_SERVER.md).
|
||||
|
||||
## 0.2.0 vhosts and backend state
|
||||
|
||||
`vhosts` defaults to an empty array. All models, enum values, defaults and bounds
|
||||
|
||||
+10
-4
@@ -1,4 +1,4 @@
|
||||
# Administration API access - 0.24.10
|
||||
# Administration API access - 0.25.0
|
||||
|
||||
## Sign-in boundary
|
||||
|
||||
@@ -72,9 +72,15 @@ paths instead of browser-side guesses. The object is not available anonymously a
|
||||
not expose credentials, environment values, certificate contents or arbitrary filesystem
|
||||
listings.
|
||||
|
||||
## Swagger UI
|
||||
## Docs Reader and API view
|
||||
|
||||
`/docs/openapi.json` describes the local endpoints and common request schemas; it
|
||||
`/docs` opens an authenticated documentation workspace. The default **Reader** tab loads
|
||||
`/docs/content.json`, a build-time bundle of the project Markdown documentation listed in
|
||||
`docs/README.md`. The bundle contains documentation source text only; it does not contain
|
||||
live configuration, credentials or runtime state. Reader links between bundled Markdown
|
||||
documents stay inside the same authenticated documentation surface.
|
||||
|
||||
The separate **API** tab uses Swagger UI. `/docs/openapi.json` describes the local endpoints and common request schemas; it
|
||||
contains no live configuration, actual credentials, generated keys, user accounts,
|
||||
cache entries or listener addresses. Extensible schemas summarize configuration;
|
||||
the Rust validator remains authoritative for the full configuration model.
|
||||
@@ -109,7 +115,7 @@ CLI authority from the local database and calls the guarded loopback administrat
|
||||
|
||||
The external validator, query-supplied schema/server configuration and persisted
|
||||
Swagger authorization are disabled. Runtime JS/CSS are served from the same admin
|
||||
origin behind its guard. Only the two necessary vendor asset filenames and a plain-text license notice
|
||||
origin behind its guard. Only the two necessary Swagger vendor asset filenames, the documentation bundle and a plain-text license notice
|
||||
(`/docs/licenses.txt`) are routed; all require an administrator session.
|
||||
Swagger's inline layout styles have a document-scoped CSP exception; scripts stay
|
||||
self-only with no unsafe-eval allowance. The ordinary dashboard CSP is unchanged.
|
||||
|
||||
@@ -23,6 +23,7 @@ committed document at startup; this is not one cross-memory/SQLite transaction.
|
||||
| `server` | Bounded listeners, TLS acceptance, HTTP/1.1/HTTP/2 selection, connection leases and shutdown |
|
||||
| `proxy` | Host/authority routing, ACL sequencing, forwarding and streaming instrumentation |
|
||||
| `proxy::websocket` | Handshake validation, upgrade tasks and bounded bidirectional byte transport |
|
||||
| `web_server` | Reusable static-file services, safe document-root traversal, validators/ranges and streamed local file bodies |
|
||||
| `upstream` | Per-backend pools, guarded resolver, connection deadlines and verified HTTPS clients |
|
||||
| `tls` | Local PEM files, generation/import, validation, SNI and loaded certificate snapshots |
|
||||
| `config` | Desired models, normalization, validation and compiled snapshots |
|
||||
@@ -52,9 +53,11 @@ response bodies. HTTP/2 connections share the public TCP cap with HTTP/1.1 and T
|
||||
Upgraded WebSocket tasks retain both the Exchange and TCP lease after Hyper stops
|
||||
managing the HTTP connection, preventing upgrades from escaping limits or counters.
|
||||
|
||||
Routing captures one snapshot. Socket peer identity, host and route ACLs are checked
|
||||
before DNS or upstream connection reuse. Forwarding uses a URI built from a stored
|
||||
backend origin; the public client never supplies an arbitrary destination. Header
|
||||
Routing captures one snapshot. Socket peer identity, host and route ACLs plus configured
|
||||
authentication are checked before source dispatch, DNS or upstream connection reuse. A selected
|
||||
Web Server source opens only its compiled Web Service root and returns through the shared response
|
||||
pipeline; a Reverse Proxy source continues to a stored backend origin. The public client never
|
||||
supplies an arbitrary upstream destination or filesystem root. Header
|
||||
rules cannot change the identity already used by ACL. Ordinary bodies pass through
|
||||
without full aggregation. For an explicitly transform-enabled vhost, eligible bounded
|
||||
static responses use the logical pipeline `origin -> decode supported Content-Encoding
|
||||
@@ -131,8 +134,7 @@ probes outside the data path. DNS and configured-origin policies are shared with
|
||||
normal forwarding; HTTP checks use a dedicated connection and discard the body.
|
||||
Traffic sampling and status snapshots operate on these observations, not SQLite.
|
||||
|
||||
Forwarding order is actual frontend selection -> host/vhost/path ACL -> eligible
|
||||
member selection -> member-isolated cache lookup -> guarded upstream request.
|
||||
Request order is actual frontend selection -> host/vhost/path ACL/auth -> location/source selection. Web Server then performs confined local filesystem handling; Reverse Proxy continues through eligible member selection -> member-isolated cache lookup -> guarded upstream request.
|
||||
Cookie affinity bypasses cache. Cache hits release the selection without recording
|
||||
an actual upstream request. Response protection is applied after cache selection,
|
||||
and per-vhost HSTS is removed on plaintext, including synthetic responses.
|
||||
|
||||
@@ -31,6 +31,9 @@ behavior exactly.
|
||||
| transient_max_bytes | 67108864 | Hard RAM budget for fill buffers and complete bodies moving between HOT/COLD |
|
||||
| cold_queue_max_bytes | 33554432 | Byte ceiling for complete demoted objects waiting for the COLD writer; at most `transient_max_bytes` |
|
||||
| hot_eviction_max_objects | 64 | 1..4096 LRU removals attempted for one HOT admission before the new object passes uncached |
|
||||
| hot_auto_trim_enabled | true | Periodically trim sufficiently idle HOT objects only while HOT usage is above the target waterline |
|
||||
| hot_auto_trim_after_seconds | 300 | 5..86400; minimum idle age before an object can be removed by automatic HOT trim |
|
||||
| hot_auto_trim_target_percent | 80 | 10..95; automatic trim stops once HOT usage reaches this percentage of `max_bytes` |
|
||||
| cold_enabled | false | Enable persistent disk tier; never implied by hot-cache enable |
|
||||
| cold_path | cache/cold | Relative path under the private RustProxy data directory |
|
||||
| cold_max_bytes | 4294967296 | 64 KiB..1 TiB disk budget |
|
||||
@@ -67,6 +70,8 @@ behavior exactly.
|
||||
|
||||
The hot tier enforces `max_bytes` and `max_entries` before publication. HOT accounting uses the retained body allocation (the fill buffer capacity transferred into `Bytes`) plus directly owned entry metadata and a conservative per-entry charge for the HOT hash/LRU/variant indexes, while `hot_logical_bytes` reports only visible body lengths. Rust container/allocator APIs do not expose every bucket/node allocation exactly, so `hot_allocated_bytes` is intentionally a conservative charged estimate rather than a promise that it equals process RSS. In-progress fills reserve a separate bounded transient budget before growing their buffers. When HOT pressure would exceed the budget plus a small allocator-rounding headroom (roughly 1/64 of HOT, capped at 1 MiB), RustProxy removes LRU objects first; if admission still cannot be made safe within `hot_eviction_max_objects`, the response continues normally without being cached. `max_object_bytes` is checked incrementally before every body-buffer growth, so an oversized response is not fully accumulated before rejection.
|
||||
|
||||
Automatic HOT trim is a separate low-pressure maintenance path. Every maintenance pass first checks whether HOT allocation is above `hot_auto_trim_target_percent` of `max_bytes`; if so, only least-recently-used objects that have been idle for at least `hot_auto_trim_after_seconds` are eligible. One pass is capped by `hot_eviction_max_objects`. Active/recent objects are never removed by this mechanism. Eligible objects follow the existing COLD-on-LRU policy when enabled; otherwise they are evicted. This is intended to release stale working-set memory after traffic bursts without periodically purging the cache or reloading vhosts.
|
||||
|
||||
When cold storage is enabled,
|
||||
`cold_on_lru`, `cold_on_idle` and `cold_on_age` independently choose which hot objects are demoted.
|
||||
`cold_after_seconds` measures time since the last access. `cold_max_hot_seconds` measures total
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Cache diagnostics and behavior in 0.22.3
|
||||
# Cache diagnostics and behavior
|
||||
|
||||
This describes implemented source, not a verified Rust runtime. See
|
||||
[TEST_REPORT.md](TEST_REPORT.md).
|
||||
@@ -158,6 +158,17 @@ This explains why, for example, a process RSS around 630 MiB can coexist with on
|
||||
|
||||
The existing Linux/glibc allocator-release path remains in place: large cache demotion/purge paths call `malloc_trim(0)` through `release_allocator_memory()`. Since 0.24.5, HOT allocation, active fills and bodies moving to/from COLD are explicitly budgeted. COLD queue admission is byte-bounded as well as count-bounded. RSS is still a process-wide view containing the same cache memory plus TLS/QUIC/Hyper/Tokio, stacks and allocator retention, so cache gauges must not be added to RSS. Long-running acceptance should verify that HOT stays within `hot_limit_bytes`, transient stays within `transient_limit_bytes`, demotion drains transient bytes, and process RSS reaches a practical plateau under representative traffic.
|
||||
|
||||
### Sustained traffic, vhost saves and RSS
|
||||
|
||||
A vhost configuration save can make RSS fall abruptly for two independent reasons. First, the current cache compatibility identity includes vhost configuration; when that identity changes, publication performs a cache purge so representations created under the old origin/configuration contract cannot survive incorrectly. Second, publishing the newly compiled routing snapshot retires the previous snapshot and its upstream clients; once outstanding references finish, idle connection-pool state and related buffers can be released. A visible RSS drop after saving a busy vhost is therefore a useful diagnostic clue, but saving/reloading a vhost is not a memory-maintenance requirement.
|
||||
|
||||
The 0.25.0 development runtime adds two maintenance mechanisms that do not reload configuration:
|
||||
|
||||
- every 60 seconds on Linux/glibc, RustProxy calls `malloc_trim(0)` from a blocking maintenance task; this can return allocator pages that are already free, but cannot and does not evict live Rust objects;
|
||||
- HOT cache maintenance trims only least-recently-used entries that have been idle for the configured delay and only while HOT allocation is above the configured target waterline. The pass is bounded by `hot_eviction_max_objects`; recent/active entries are not purged.
|
||||
|
||||
Upstream HTTP keep-alive is not reset on a timer. It is already bounded per backend by `max_idle_per_host` and `idle_timeout_seconds`, so forcing periodic client/snapshot replacement would trade memory symptoms for connection churn and lower proxy efficiency. If RSS remains high while HOT/transient usage and connection-pool bounds are stable, the remaining resident pages may still be active runtime/TLS/QUIC/Hyper/Tokio working set rather than reclaimable cache memory.
|
||||
|
||||
## Hot and cold tiers
|
||||
|
||||
HOT RAM is bounded by allocated/charged `max_bytes` and `max_entries`; `hot_logical_bytes` separately exposes payload length. Fill and COLD handoff/read memory are bounded by `transient_max_bytes`, and queued demotions also obey `cold_queue_max_bytes`. Optional cold storage demotes LRU
|
||||
@@ -165,10 +176,11 @@ or sufficiently idle hot objects asynchronously. Cold hits verify the body diges
|
||||
promote the object back to RAM. Version 0.11.5 uses cold metadata format 2 to persist
|
||||
Vary identity and resident age; old-format metadata is not reused.
|
||||
|
||||
Cold is not required for normal hot-cache stability. Disabling cold must not cause hot
|
||||
objects to disappear on a timer. With cold disabled, hot objects leave RAM only because
|
||||
of expiry, hot capacity/LRU pressure, explicit purge, configuration generation changes,
|
||||
or replacement of the same logical representation.
|
||||
Cold is not required for normal hot-cache stability. With cold disabled, hot objects leave
|
||||
RAM because of expiry, hot capacity/LRU pressure, explicit purge, configuration generation
|
||||
changes, replacement of the same logical representation, or the optional HOT auto-trim
|
||||
waterline. Auto-trim is not a blind TTL: it acts only when HOT is above its configured target
|
||||
and only on entries idle longer than the configured threshold; it can be disabled independently.
|
||||
|
||||
## Cache panel and API
|
||||
|
||||
|
||||
@@ -0,0 +1,862 @@
|
||||
# Historical developer-level changelog archive
|
||||
|
||||
> Archived during the 0.25 documentation cleanup. This file preserves the pre-cleanup
|
||||
> detailed release record, including compiler fixes, source refactors, regression notes and
|
||||
> packaging details. It is historical technical evidence, not the operator-facing changelog.
|
||||
> Use [`../CHANGELOG.md`](../CHANGELOG.md) for user/operator-visible release changes.
|
||||
|
||||
# Changelog
|
||||
|
||||
## 0.25.0
|
||||
|
||||
- Add reusable Web Services with document root, index-file list and optional directory listing, managed from the new **Web Server** dashboard section.
|
||||
- Add `Reverse Proxy` / `Web Server` source selection for vhosts and custom locations, including mixed static/proxy routing in one vhost and reuse of one Web Service by multiple vhosts.
|
||||
- Add static `GET`/`HEAD`, streaming responses, MIME/length headers, directory index/redirect/listing behavior, HTTP validators and single-range requests (`206`/`416`).
|
||||
- Enforce document-root confinement for Web Server paths, reject ambiguous/encoded traversal forms and prevent symlink escape by not following symlinks during Unix filesystem traversal.
|
||||
- Reuse the existing vhost ACL/authentication/header/error/TLS/HTTP pipeline for local files without adding a separate router, error-page system or object cache.
|
||||
- Add an authenticated **Docs Reader** for bundled project documentation alongside the existing API/OpenAPI view, and separate the current documentation index, release audit and open TODO material.
|
||||
- Fix the 0.25 Docs Reader source embedding so compilation does not require a generated `OUT_DIR/docs-content.json`; Markdown sources are now direct compiler inputs and the JSON bundle is serialized from embedded strings.
|
||||
|
||||
## 0.24.10
|
||||
|
||||
- Keep Error File inside the existing revisioned `logging` configuration section while retaining its own Settings form; both access-log and error-file forms save atomically through `/api/config/logging`, so enabled/path/format persist without introducing a special endpoint.
|
||||
- Preserve backward compatibility for historical `/api/config/logging` clients that send only the access-logging object.
|
||||
- Keep the Error File panel free of the redundant ERROR/logrotate help sentence.
|
||||
- Remove collapsing from Response time history and add an accessible information control explaining the cumulative mean metric.
|
||||
- Update package/source/UI/OpenAPI/release identity to 0.24.10.
|
||||
|
||||
## 0.24.9
|
||||
|
||||
- Added composite Settings > Logging support for `error_log.enabled`, path and format while retaining legacy `/api/config/logging` payload compatibility.
|
||||
- Removed the Error Log help sentence from the panel while keeping the existing controls and behavior unchanged.
|
||||
|
||||
- Fix Rust type inference for zeroizing ACME/Base64 and AEAD buffers so the new Secret Store and encrypted backup code compile with the pinned dependency set.
|
||||
- Fix the secret-redaction KV regex literal so 0.24.9 compiles correctly; the redaction behavior itself is unchanged.
|
||||
- Harden the built-in release checker for FreeBSD/OPNsense and other Unix platforms: supplement bundled Mozilla roots with common system CA bundles/`SSL_CERT_FILE`/`CURL_CA_BUNDLE`, follow bounded non-downgrading HTTP(S) redirects, and report failed checks as normal application `ERROR` events without changing dashboard behavior.
|
||||
- Add a central AES-256-GCM encrypted Secret Store with private local master-key storage and migration of existing ACME DNS-provider credentials.
|
||||
- Add encrypted full backup/restore with Argon2id, authenticated encryption, explicit manifests/checksums, staging validation and rollback-safe activation.
|
||||
- Add an optional ERROR-only JSON/RAW file sink with bounded asynchronous writes, central secret redaction and system `logrotate` integration.
|
||||
- Extend source/release regressions and update release identity to 0.24.9.
|
||||
|
||||
## 0.24.8
|
||||
|
||||
- Expand the overview Cache RAM diagnostics with HOT usage against limit, transient RAM history for total/fill/COLD queue/COLD I/O, and COLD storage occupancy against its disk budget.
|
||||
- Hide the long RSS/cache accounting explanation behind an accessible information control in the Process heading.
|
||||
- Keep COLD disk occupancy explicitly separate from transient process RAM accounting.
|
||||
- Update release identity to 0.24.8.
|
||||
|
||||
## 0.24.7
|
||||
|
||||
- Make the transform temporary-memory ceiling configurable from Settings and preserve a 128 MiB default for existing configurations.
|
||||
- Add a configurable process-wide transform concurrency ceiling; excess work fails open unchanged rather than waiting behind transformation work.
|
||||
- Add persisted RAM saver, Recommended, Performance and Uber performance transform resource presets without changing enabled transform formats or extension allow-lists.
|
||||
- Show transform-resource warnings when the selected budget cannot fit the worst-case buffers for one maximum compressed body or exceeds half of detected host/cgroup RAM.
|
||||
- Add live dashboard resource accounting: current transform RAM reservation/budget and active slots, HOT/transient cache RAM, non-cache process RSS, plus COLD disk occupancy and object limits.
|
||||
- Include global transform representation/eligibility settings in cache compatibility identity while excluding resource-only preset/budget/concurrency controls.
|
||||
- Map bounded transform-body collection failures explicitly into `anyhow::Error`, avoiding the `anyhow::Context` trait-bound compile failure for Axum/HTTP body boxed errors.
|
||||
- Clean compiler warnings in cache transient leases and CSS minification without suppressing lints: make RAII-only lease ownership explicit, keep COLD read reservations intentionally alive, and remove dead CSS state assignments.
|
||||
- Extend SQLite/OpenAPI/offline memory/release regressions and update release identity to 0.24.7.
|
||||
|
||||
## 0.24.6
|
||||
|
||||
- Persist the selected memory and COLD cache preset identities in the SQLite-backed cache configuration and restore their selected/custom state in Settings.
|
||||
- Add a Recommended COLD policy preset with bounded queue sizing and conservative demotion/GC defaults while preserving operator-selected disk path, disk budget and object limit.
|
||||
- Add a 128 MiB process-wide transform temporary-memory budget, bounded body aggregation independent of claimed Content-Length, and bounded decompression growth.
|
||||
- Validate/compact JSON without a full DOM tree, remove routine HTML raw-tag string allocations and avoid repeated CSS output scans.
|
||||
- Cap stale-while-revalidate background work at 8 keys and proactive sleeping refresh tasks at 256; keep COLD cleanup single-flight and candidate memory proportional to the requested deletion limit.
|
||||
- Bound COLD delete fallback tasks and deletion metadata, and add Rust-independent regression checks for memory/task bounds across background workers.
|
||||
- Update release identity to 0.24.6.
|
||||
|
||||
## 0.24.5
|
||||
|
||||
- Normalize actually empty, length-unknown HTTP/3 request bodies before HTTP/1.1 upstream forwarding so Hyper emits a zero-length request instead of chunked framing for methods such as DELETE.
|
||||
- Keep non-empty HTTP/3 bodies streaming by replaying the inspected first frame, leave declared `Content-Length` requests untouched, and do not alter HTTP/2 upstream framing.
|
||||
- Add focused regression coverage for empty/non-empty H3 DELETE and generic empty H3 methods forwarded to HTTP/1.1.
|
||||
- Keep the source package consistent with its existing release contracts by dropping the stale unreferenced `src/system_stats/bsd.rs` file and updating the offline container check to the already-shipped Debian 13/Trixie base images.
|
||||
- Harden cache RAM admission without changing the HOT -> COLD storage model: HOT now has a 256 MiB allocation-aware default budget, fills reserve memory before buffer growth, and a small bounded allocator headroom replaces max-object-sized overshoot.
|
||||
- Add a separate 64 MiB transient RAM budget plus a 32 MiB byte ceiling for the COLD writer queue; demoted bodies stay charged until persistence drops the `ColdDraft`, while persisted `ColdEntry` values retain only disk paths/metadata.
|
||||
- Preserve body backing-allocation accounting across fill, revalidation and COLD promotion, expose HOT logical vs allocated bytes and the HOT/transient/COLD-queue limits, and add memory-pressure/LRU-admission counters.
|
||||
- Make global cache disable authoritative over per-vhost enablement, remove the artificial 1 GiB HOT/object configuration ceiling, and hot-apply reduced HOT capacity with bounded LRU demotion/eviction.
|
||||
- Add Settings memory sizing based on effective host/cgroup RAM with conservative, recommended and performance presets, a live recommended profile, host/cgroup headroom warnings, and controls for transient RAM, COLD queue RAM and bounded LRU admission. Automatic presets are disabled below 256 MiB effective RAM.
|
||||
- Update release identity to 0.24.5.
|
||||
|
||||
## 0.24.4
|
||||
|
||||
- Disable Linux Transparent Huge Pages for the RustProxy process with `prctl(PR_SET_THP_DISABLE)` before the Tokio runtime is created, avoiding a host-wide THP policy change while preventing 2 MiB anonymous huge pages from amplifying allocator RSS retention.
|
||||
- Treat the process-local THP operation as best-effort: unsupported/rejected kernels emit a startup warning and RustProxy continues to run.
|
||||
- Update release identity to 0.24.4.
|
||||
|
||||
## 0.24.3
|
||||
|
||||
- Add a per-certificate reload operation for manual/file-backed certificate IDs and authorize it through the scoped Certificate API as well as the normal administrator session.
|
||||
- Allow multiple Certificate API tokens (bounded to 32), operator comments, individual revocation and revoke-all while continuing to persist token hashes only.
|
||||
- Replace the overview Core State block with a live connection/activity chart, move uptime into the Process block below process start, add RX/TX-style upload/download detail under Payload transferred, and persist per-browser hidden network-interface charts.
|
||||
|
||||
- Add `MALLOC_ARENA_MAX=2` to managed Linux/systemd service units to reduce glibc arena growth and long-running RSS retention while retaining the environment-file override.
|
||||
- Remove an identity-body copy from the transformation pipeline, remove `Vec<char>` plus final output-copy allocations from the JavaScript/CSS minifiers, release successful-transform temporary buffers earlier, and use a throttled `malloc_trim(0)` after large Linux/glibc transforms.
|
||||
- Make HTTP/2 lifecycle tuning listener-scoped like HTTP/3: keep H2/H2C and H3 enablement in **Settings -> Listeners**, expose per-listener H2 GOAWAY/lifetime limits under **HTTP connections -> HTTP/2**, retain per-listener QUIC limits under **HTTP/3**, and link listener rows to the matching tuning page. Existing top-level `http2` values remain a compatibility fallback for listeners without explicit H2 settings.
|
||||
- Rename **Proxy process** to **Process** and dynamically hide unsupported process diagnostics and history charts instead of showing unknown values.
|
||||
- Remove the stale, unreferenced legacy `src/system_stats/bsd.rs` parser file from the source package; shared library collectors remain the only BSD statistics implementation.
|
||||
- Update release identity to 0.24.3.
|
||||
|
||||
## 0.24.2
|
||||
|
||||
- Version-only release bump from 0.24.1; no functional, configuration or protocol changes.
|
||||
|
||||
## 0.24.1
|
||||
|
||||
- Restore system network interface discovery and RX/TX counters after the shared-statistics refactor: use the cross-platform `sysinfo::Networks` API as the primary network inventory/counter source, merge `systemstat` as a library-level supplement/fallback for missing or partial inventory, preserve per-interface rate calculation, and stop silently truncating the interface list.
|
||||
- Fix the compiler error in portable uptime collection by using the `systemstat` duration API correctly, and remove the now-unused `Future` import in the H2 server module.
|
||||
- Remove RustProxy's artificial hostname-count ceilings from certificate SNI bindings, local certificate generation/import validation, ACME domain validation, vhost/redirect/404 hostnames, administration allowed hosts, host ACL policies and Docker aliases. Input validity and bounded control-plane/resource limits remain enforced.
|
||||
- Replace per-BSD command/parsing statistics code with shared library collectors: `systemstat` for host metrics, `sysinfo::Networks` for network inventory/counters, and `metrics-process` for process metrics, using the documented dummy process fallback on targets without a native collector.
|
||||
- Preserve Linux `/proc` and cgroup-specific details as additive compatibility metrics while using the common library API for portable host/process values.
|
||||
- Add portable swap, system uptime, process virtual memory/limit, descriptor limit and process start-time diagnostics where the libraries support them.
|
||||
- Add authenticated runtime metadata for platform, statistics source, resolved data directory and exact SQLite database path.
|
||||
- Make local CLI data-directory discovery understand both `/var/lib/rustproxy` and the BSD/OPNsense `/var/db/rustproxy` convention.
|
||||
- Move Logging into **Settings -> Logging** while retaining legacy `/logging` navigation compatibility.
|
||||
- Update release identity to 0.24.1.
|
||||
|
||||
## 0.24.0
|
||||
|
||||
- Replace abrupt downstream H2 idle termination with a GOAWAY-based graceful shutdown that rechecks current activity and waits for accepted streams.
|
||||
- Add independent H2 idle timeout, maximum connection lifetime and drain timeout settings; lifetime may be disabled with `0`.
|
||||
- Bound H2 draining so stalled streams cannot keep a retiring connection open indefinitely.
|
||||
- Keep H2 Extended CONNECT/WebSocket streams under the same active-stream accounting and graceful drain path.
|
||||
- Extract system statistics into platform backends while preserving Linux metric names, units and behavior; add native FreeBSD/OpenBSD/NetBSD sampling where available and explicit nulls otherwise.
|
||||
- Add runtime platform to Proxy Process and Prometheus platform info.
|
||||
- Add Settings UI/API/OpenAPI/language-pack support plus H2 lifecycle/configuration regressions.
|
||||
- Reorganize **Settings -> HTTP connections** into HTTP/2 and HTTP/3 sub-tabs; move listener-scoped H3/QUIC enablement and limits out of the Listeners editor while preserving restart semantics and the existing listener configuration model.
|
||||
- Update release identity to 0.24.0.
|
||||
|
||||
## 0.23.3
|
||||
|
||||
- Make external certificate deployment convergent: create missing manual certificate ids, rotate existing manual ids, no-op identical RustProxy-owned generations, and keep managed ACME ids protected from external ownership.
|
||||
- Make the OPNsense os-acme-client hook reconcile on every run so RustProxy remains the source of truth and deleted/drifted external certificate entries self-heal.
|
||||
- Add per-vhost **Enable WebSocket legacy support** for older appliance/embedded WebSocket implementations.
|
||||
- Force legacy-mode WebSocket upstream handshakes to HTTP/1.1 and force the WebSocket `Host` to the configured backend authority and align `Origin` to the matching backend scheme + authority.
|
||||
- Tolerate legacy `101 Switching Protocols` response framing while keeping `Sec-WebSocket-Accept` and subprotocol validation strict.
|
||||
- Add UI/OpenAPI/translations, documentation and regression contracts for the compatibility mode.
|
||||
- Update package/source/UI identity and release verification contracts to 0.23.3.
|
||||
|
||||
## 0.23.2
|
||||
|
||||
- Add selectable 60/120/300/600-sample history windows to the Cache and Transformation live charts, with bounded per-workspace browser persistence.
|
||||
- Fix `rust-proxy --livelogs` on HTTPS administration listeners by detecting the HTTP 308 redirect and reconnecting over TLS instead of looping.
|
||||
- Pin local CLI HTTPS to leaf certificates present in the private `data-dir/certs` directory and reuse the HTTP/HTTPS-aware client for config and certificate CLI API calls.
|
||||
- Update package/source/UI identity and release verification contracts to 0.23.2.
|
||||
|
||||
## 0.23.1
|
||||
|
||||
- Add default-collapsed, full-width live activity charts to the Cache and Transform workspaces.
|
||||
- Plot Cache HIT/MISS/BYPASS rates for the selected scope using deltas from the existing cache runtime counters.
|
||||
- Plot Transform applied/cache-HIT/skipped/error rates for the selected scope using the existing transform metrics endpoint.
|
||||
- Reuse the administration dashboard SVG/grid/legend visual language, keep the existing 3-second live refresh, and add English/Polish language-pack labels.
|
||||
- Update package/source/UI identity and release verification contracts to 0.23.1.
|
||||
|
||||
## 0.23.0
|
||||
|
||||
- Bound inactive inbound HTTP/2 connections to five minutes so idle TLS/H2 sessions cannot accumulate indefinitely toward the process connection limit; export `rust_proxy_http2_active_connections` for direct diagnosis.
|
||||
- Account hot-cache response-body backing allocation capacity rather than only visible body length, preventing `BytesMut` growth slack from bypassing the configured RAM budget and under-reporting resident cache memory.
|
||||
- Fix the `--livelogs` stdin reader to send owned `String` values from the match body rather than a pattern guard, resolving Rust `E0507` during binary compilation.
|
||||
- Add a scoped external Certificate API credential managed from a new **Settings → Certificate API** tab. RustProxy stores only the token hash plus a non-secret Key ID; the cleartext token is returned only on rotation.
|
||||
- Allow the scoped Key ID + Bearer Token only on `POST /api/certificates/deploy` and `POST /api/certificates/reload`, require HTTPS for non-loopback token use, track last use, support immediate revoke, and retain normal administrator-session/CSRF access as an alternative.
|
||||
- Keep production certificate operations available directly from the installed binary (`rust-proxy tls deploy` / `rust-proxy tls reload`) without requiring `dev.sh`.
|
||||
- Add `rust-proxy --livelogs`: an interactive varnishlog-style all-vhost live access stream with structured filters (`host`, `vhost`, `backend`, `route`, `client`, `method`, `transport`, `cache`, status classes, path prefix, errors and slow requests), pause/resume, per-request JSON inspection and detailed error/WebSocket/H3/cache fields.
|
||||
- Back live logs with a bounded non-blocking broadcast stream and authenticated SSE endpoint; slow consumers receive an explicit `gap` event with the dropped-entry count instead of silent loss.
|
||||
- Split the large **Settings → Cache** form into **General**, **Resilience**, **Cold cache**, and **Static & diagnostics** sub-tabs while retaining one atomic cache-policy save.
|
||||
- Add SQLite schema v5 for the scoped certificate credential, OpenAPI/security schemes, UI translations, audit events and 0.23.0 regression/release documentation.
|
||||
|
||||
## 0.22.3
|
||||
|
||||
- Add downstream HTTP/1.1 `Upgrade: h2c` on listeners that explicitly enable cleartext HTTP/2, preserving the existing prior-knowledge path and rejecting malformed/body-bearing upgrade attempts before protocol switch.
|
||||
- Reconstruct the accepted H1 upgrade request as HTTP/2 stream 1 and hand subsequent framing/streams to the existing Hyper H2 server path; include raw-TCP interoperability regression source.
|
||||
- Add authenticated `POST /api/certificates/reload` and `tls reload` to re-read configured public certificate/key files and hot-publish a fresh TLS/H2/H3 snapshot without changing the desired configuration revision.
|
||||
- Add `tls deploy --id ... --cert ... --key ...` and authenticated `POST /api/certificates/deploy` for externally issued local certificates such as Certbot. The CLI performs bounded local reads while the running service owns pair/SAN validation, immutable generation staging, revision-CAS publication and rollback on failure, avoiding root-owned staged PEMs when Certbot hooks run as root.
|
||||
- Keep all vhosts assigned to one manual certificate id synchronized during external rotation; reject RustProxy-managed ACME ids to avoid dual renewal ownership and report the administration-TLS restart caveat explicitly.
|
||||
- Add Certificates-panel reload UX, OpenAPI contracts, audit events, translations and 0.22.3 audit/test documentation.
|
||||
|
||||
## 0.22.2
|
||||
|
||||
- Fix the 0.22.2 backend diagnostics build failure by replacing the oversized recursive `serde_json::json!` member payload with explicit `serde_json::Map` construction; the administration JSON schema is unchanged.
|
||||
- Add bounded replay-safe backend failover retry for body-free GET/HEAD/OPTIONS requests, including retry policy controls, passive-health integration, logs and per-backend retry counters.
|
||||
- Correct ordinary explicit-HTTP/2 upstream requests and add a real Hyper h2c prior-knowledge regression path.
|
||||
- Add per-backend request-concurrency limits with bounded capacity waiting, `503` rejection and capacity/queue-timeout metrics. This limits full proxy exchanges, not TCP socket count.
|
||||
- Add detailed upstream failure classes, last failure detail/timestamp, and backend health ejection/recovery timestamps to runtime diagnostics and Prometheus.
|
||||
- Expand the backend administration table with concurrency capacity, last failure and last recovery columns.
|
||||
- Parse public X.509 leaf metadata for issuer, SANs, validity, remaining days and expiry warning state, and surface ACME renewal status/last attempt/error in certificate inventory.
|
||||
- Extend OpenAPI, language packs, source regressions, audit/TODO and release documentation for the expanded 0.22.2 scope.
|
||||
|
||||
## 0.22.1
|
||||
|
||||
- Vhost UX: replaced separate WebSocket/H2 RFC 8441/H3 RFC 9220 checkboxes with one transport selector; H2/H3 modes keep HTTP/1.1 Upgrade as an explicit fallback and unavailable transports are disabled from listener capabilities.
|
||||
|
||||
- UI polish: replaced the overview TLS listener tile with compact HTTP protocol and WebSocket protocol mini charts; Target and Cache key/tags cells remain copyable with full values.
|
||||
|
||||
- Keep the overview metrics in one shared stats grid so the WebSocket/H2/H3/TLS row uses exactly the same card geometry as the primary metrics, without a transport-specific dashboard layout. Make Cache **Target** and **Cache key / tags** cells copy their full untruncated value on click/keyboard activation.
|
||||
- Polish the 0.22.1 administration UI: move **Active tunnels** into the WebSocket dashboard card, flatten the H1/H2/H3 tunnel breakdown to match the standard transport-card styling, and align Cache modal close actions with the vhost modal header pattern.
|
||||
- Fix Rust ownership in tunnel registration by releasing the client-IP mutex guard before moving the shared exchange into the active tunnel, and remove an unnecessary mutable H2 upstream reader binding.
|
||||
- Move selective cache PURGE/BAN and the active BAN list into dedicated Cache modals, keep their launch actions beside **Purge selected scope**, and use null-safe inline operation feedback consistent with login errors.
|
||||
- Add opt-in RFC 8441 WebSocket Extended CONNECT for HTTP/2, with per-vhost controls beside RFC 9220, listener-scoped SETTINGS advertisement, H2-to-H1 bridging, explicit H2 upstream forwarding, cancellation/idle timeout and transport-specific metrics.
|
||||
- Add opt-in cleartext HTTP/2 prior-knowledge (`h2c`) listeners. Legacy HTTP/1.1 `Upgrade: h2c` remains deliberately unsupported because the current Hyper integration cannot safely reconstruct the required HTTP/2 stream 1 bootstrap.
|
||||
- Add stable active-tunnel IDs, authenticated tunnel inventory/kill API, operator-supplied close reasons, audit records, RX/TX/duration metadata and an administration modal.
|
||||
- Consolidate active WebSocket/tunnel visibility on the main dashboard as total plus H1 / H2 RFC 8441 / H3 RFC 9220 counters while retaining ordinary H2/H3 request statistics separately.
|
||||
- Preserve `Accept-Ranges` from origins and synthesize it only for RustProxy-generated cached range responses; transformed/compressed representations continue to remove incompatible range advertising.
|
||||
- Update source/package/UI/OpenAPI/Debian/Grafana/tooling identity to 0.22.1.
|
||||
|
||||
|
||||
## 0.22.0
|
||||
|
||||
- Fix a Rust ownership regression in the upstream request path: retain a cloned origin URI for proactive refresh after the request URI is assigned.
|
||||
- Add per-cache-key request collapsing for foreground MISS/fill traffic with bounded wait, configurable timeout fallback, cancellation-safe leader release and collapse metrics.
|
||||
- Add single `Range: bytes=...` handling from complete cached objects, including `206`, `416`, `Content-Range`, `Accept-Ranges` and `If-Range`; multipart/unsupported ranges remain origin pass-through and are not cached as separate objects.
|
||||
- Extend stale-if-error with configurable transport failure classes and an explicit 5xx status allowlist while preserving the previous default behavior.
|
||||
- Add bounded proactive cache refresh with pre-expiry scheduling, deterministic sampling, concurrency limits and reuse of the existing validator revalidation path.
|
||||
- Add selective cache PURGE by exact URL, prefix, tag, regex or cache key, including query/Vary handling, RAM + Cold Cache invalidation and a publication barrier preventing pre-PURGE fills from republishing stale data.
|
||||
- Add lazy BAN rules with lookup-time enforcement, bounded rule count/TTL, incremental garbage collection, rule deletion and metrics.
|
||||
- Add authenticated administration API and Cache panel controls for PURGE/BAN, broad-operation confirmation, per-object Purge URL actions, BAN listing/removal and audit entries.
|
||||
- Extend cache diagnostics, OpenAPI, translations and regressions for the 0.22 cache behavior.
|
||||
- Update package/source/UI/OpenAPI/Debian/Grafana/tooling identity to 0.22.0.
|
||||
- Preserve the resolved dependency graph; compiler/live acceptance remains an explicit release-host gate when Cargo/Rust are unavailable in the packaging workspace.
|
||||
|
||||
## 0.21.0
|
||||
|
||||
- Fix browser refresh on the dedicated **Transform** route by serving the dashboard document at `/transform` and covering it in the panel-route regression.
|
||||
- Align the Cache **Transformed** marker with the dashboard geometry by replacing the capsule outline with the standard badge border and a 3px corner radius.
|
||||
- Give the Live traffic **Transformed** series a dedicated violet chart token in dark/light themes so it remains distinct from HTTP/2 green.
|
||||
- Add a dedicated Transform administration workspace with global/per-vhost runtime counters for applied/skipped/error transformations, transformed cache HITs, byte savings, reduction, transform time, kind breakdown and bounded skip reasons.
|
||||
- Add a transformed-response series to **Live traffic** (fresh transformations plus transformed cache HITs) and render **Core state** uptime in compact human-readable units.
|
||||
- Rename the proxy-owned backend timing diagnostic to `X-RustProxy-Backend-Time`; the legacy lookalike `X-Rust-Proxy-Backend-Time` is stripped but is no longer emitted.
|
||||
- Fix Docker-vhost Passive Backend Health checkbox sizing so enabling the expanded editor cannot make fields overlap.
|
||||
- Remove the unused mutable `origin` binding from the background revalidation path.
|
||||
- Replace the monolithic `src/cache.rs` with the responsibility-based `src/cache/` module (`model`, lifecycle, cold storage, dashboard, tickets, lookup, policy, fill and tests) and update source/package gates for the new layout.
|
||||
- Fix the cache split so method groups are emitted from module-scope `include!` files wrapped in their own `impl Cache` blocks; this avoids the Rust compiler error caused by `include!` directly in impl-item position.
|
||||
- Persist transformed-representation metadata through hot/Cold Cache, mark transformed objects in the Cache dashboard, and append `transformed` to standardized RFC 9211 `Cache-Status` diagnostics; origin `X-Cache-Status` lookalikes are stripped rather than emitted.
|
||||
|
||||
- Shard Cold Cache storage and add bounded asynchronous garbage collection plus selective manual cleanup.
|
||||
- Add RFC 5861 stale windows, request `max-stale`, age-aware request `max-age=N`, and correct `must-revalidate` / `proxy-revalidate` behavior while preserving `s-maxage` priority.
|
||||
- Harden transformed cache fills so transformed Content-Length is authoritative, incomplete streams cannot publish partial objects, and canonical transformed identity representations do not fragment on origin `Vary: Accept-Encoding`.
|
||||
- Add the static-response transformation pipeline before cache/client compression, with strict `no-transform`, separate origin/representation validators and JS/CSS plus optional conservative HTML/SVG and parsed JSON transforms.
|
||||
- Keep route cache overrides tri-state and add effective route/cache/transform diagnostics.
|
||||
- Make Passive Backend Health explicit opt-in (default OFF) for ordinary and Docker vhosts, independent from active TCP/HTTP health, with per-error-class policy, separate counters and persisted Docker assignment settings.
|
||||
- Extend administration UI/OpenAPI and regression coverage for Cold Cache cleanup, transform settings, passive health and cache semantics.
|
||||
- Keep release/package/UI/OpenAPI/Debian/Grafana/tooling identity at 0.21.0.
|
||||
- Close the 0.21.0 feature scope for release packaging. Parser-backed JS/CSS minifiers are deferred; compiler/live acceptance still has to be executed on a Rust-enabled release host.
|
||||
|
||||
## 0.20.0
|
||||
|
||||
- Rebuild **Certificates** into Installed / Renewal / Generate tabs using the same accessible keyboard tab pattern as Settings.
|
||||
- Keep certificate issuance, PEM import and existing-file registration inline in the Generate tab; successful imports and edits return to Installed.
|
||||
- Add explicit ACME operation state cards and include the exact private Certbot log directory in failed issuance/renewal messages.
|
||||
- Expose per-managed-certificate Certbot log directories from the authenticated ACME status endpoint so persisted renewal failures remain actionable after refresh/restart.
|
||||
- Rework renewal entries into readable cards with provider/environment, last check, next check, expiry and grouped actions.
|
||||
- Update release/package/UI/OpenAPI/Debian/Grafana/tooling identity to 0.20.0.
|
||||
|
||||
## 0.19.4
|
||||
|
||||
- Align the Docker-vhost Aliases editor with the standard 38px Docker form controls and remove the inherited `host-chip-field` label margin that created an extra visual line below `Aliases`.
|
||||
- Preserve backend traffic display semantics: idle renders as `0.0 KiB/s`, and positive rates below 0.1 KiB/s render as `<0.1 KiB/s` in both backend rows and aggregate vhost traffic.
|
||||
- Add a presentation filter to **Cache -> Domains and effectiveness** with All / Cache enabled / Cache disabled choices, using each vhost's resolved cache settings while leaving aggregate statistics unchanged.
|
||||
- Update release/package/UI/OpenAPI/Debian/Grafana/tooling identity to 0.19.4.
|
||||
|
||||
## 0.19.3
|
||||
|
||||
- Fix the compiler error in the release checker body collector by converting Hyper/http-body-util boxed collection errors explicitly into `anyhow::Error` instead of calling `anyhow::Context` on an unsupported boxed error type.
|
||||
- Simplify the dashboard footer to API latency and dropped-log count, and add a fail-soft built-in release checker using embedded `UPDATE_CHECK.toml` defaults. The checker reads the official Cargo manifest immediately and then hourly, exposes a newer-version link in the footer, and never performs automatic upgrades.
|
||||
- Allow runtime release-check overrides through `--update-repository-url`, `--update-version-url` and `--update-check-interval-secs` (plus matching `RUST_PROXY_*` environment variables); interval `0` disables checks.
|
||||
- Fix the remaining oversized Live Logs column checkboxes by excluding checkbox/radio inputs from both broad `.log-tools input` text-field sizing blocks that were overriding the shared 15px checkbox rules.
|
||||
- Add an account-scoped light/dark administration theme stored in the existing SQLite `admin_preferences` document; dark remains the default and the last authenticated choice is cached locally only to avoid login/dashboard first-paint theme flicker.
|
||||
- Refactor theme-sensitive UI colors into shared CSS variables and keep checkbox/radio controls out of generic text-input sizing/density rules.
|
||||
- Rework the Live Logs column picker into a compact scrollbar-free list with standard-size checkboxes; short viewports use two columns instead of an internal scroll area.
|
||||
- Keep expired-session re-authentication on the exact panel and Settings sub-tab, use the minimal public login document without flashing the authenticated shell, and show embedded login errors inline instead of as global toasts.
|
||||
- Canonicalize the legacy `/configuration` shortcut to `/settings?tab=manual-config` and keep later Settings tab switches in the URL so F5 restores the exact page.
|
||||
- Add one shared saving-state helper for settings/security/certificate forms: disable the active submit button, show `Saving…`, restore its translated label, and prevent duplicate submissions while a save is in flight.
|
||||
- Highlight and focus the actual invalid control for local validation failures in Logging JSON, named listeners, Docker-agent listener selection, TLS policy, ACL profiles, manual JSON and certificate forms.
|
||||
- Preserve selected certificate/key files after a failed certificate import/save so the administrator can correct the problem without reselecting both files.
|
||||
- Mark Settings tabs with a subtle unsaved-change dot, including Manual config, and keep dirty values from being overwritten by live config refreshes.
|
||||
- Update release/package/UI/OpenAPI/Debian/Grafana/tooling identity to 0.19.3.
|
||||
|
||||
## 0.19.2
|
||||
|
||||
- Restore the vhost local-listener risk control for administration backends when the administration socket is startup-locked or otherwise reported only by live status; treat `localhost`, `127.0.0.0/8` and `::1` as equivalent loopback forms for the same administration port.
|
||||
- Make **Discard changes** reload the persisted vhost being edited instead of replacing the editor with a new blank/default vhost.
|
||||
- Add descriptive HTTP reason phrases to the default-response status selectors and headings.
|
||||
- Add a temporary, continuously updated 4096-entry Live-log buffer that resets when the log window closes.
|
||||
- Align inline checkbox labels and compact Docker-vhost alias controls.
|
||||
- Stop backend traffic EWMA tails on an idle sampling window, show idle consistently as `0.0 KiB/s`, and render positive sub-0.1 KiB/s traffic as `<0.1 KiB/s` instead of a rounded zero.
|
||||
- Make the Live Logs column picker substantially smaller with subtle 11px checkboxes; let the menu escape the log-dialog clipping boundary and open upward on short viewports.
|
||||
- Default newly created vhosts to the standard HTTP `:80` listener when available; HTTPS listeners are selected explicitly.
|
||||
- Left-align the Settings -> Docker agents save action to match the other settings forms.
|
||||
- Suppress dashboard/login first-paint flicker and preserve the active Settings sub-tab across F5, including a re-login redirect back to `/settings?tab=...` and `/docker-vhosts`.
|
||||
- Replace native browser confirmations with application-styled confirmation dialogs and add panel-area context to API error messages.
|
||||
- Present login failures as an inline styled error below the form, including invalid-credential responses.
|
||||
- Install a login-shell PATH profile for the managed `current` release directory on first install; updates check and warn about the profile without changing it.
|
||||
- Enforce `no-store` and suppress cache diagnostics/validators for local placeholder/static/default pages.
|
||||
- Allow vhost-ID renames with duplicate protection, confirmation and an explicit runtime-identity warning.
|
||||
- Update source, UI, OpenAPI, regressions and package identity to 0.19.2.
|
||||
|
||||
## 0.19.1
|
||||
|
||||
- Fix Default responses section saves by passing the normal `{expected_revision, value}` payload to `/api/config/pages` and add server-side `pages` section handling/regression coverage.
|
||||
- Add frontend scheme to the primary cache hash so otherwise identical HTTP and HTTPS requests cannot reuse one object.
|
||||
- Retain 4096 completed access-log entries while keeping the 256-entry live window; add one-shot on-demand history loading and document the API limit.
|
||||
- Render backend traffic with KiB/s as the minimum unit, simplify the Live Logs column picker, align generic checkboxes and move Docker-vhost Advanced switches beside Backend protocol on desktop; remove the redundant alias help line.
|
||||
- Remove stale simulated dashboard screenshots, retain only two explicitly labelled legacy references and add a documentation index for historical/version-labelled material.
|
||||
- Restore the integration-test sources and independent Argon2id fixture required by release/source checks so compiler-enabled test builds no longer reference files missing from the supplied source archive.
|
||||
- Update source, UI, OpenAPI, regressions and package identity to 0.19.1.
|
||||
|
||||
## 0.19.0
|
||||
|
||||
- Persist per-administrator Live Logs column visibility in SQLite schema v4 without changing the revisioned proxy configuration; JSON export remains complete regardless of visible columns.
|
||||
- Keep the Live Logs column selector visually consistent with the existing compact `check vh-check` controls instead of rendering oversized standalone checkbox widgets.
|
||||
- Add authenticated `GET/PUT /api/preferences` endpoints for dashboard-only account preferences, protected by the existing session/CSRF control-plane guards.
|
||||
- Remove the duplicate version badge from the top-right dashboard toolbar while keeping the footer release identity.
|
||||
- Retain the full disabled-verification legacy X.509 fix and expanded upstream connector diagnostics introduced during the 0.18.8 follow-up.
|
||||
- Update release/package identity to 0.19.0.
|
||||
|
||||
## 0.18.8
|
||||
|
||||
- Make backend `tls_verify=false` a complete certificate-authentication bypass instead of delegating TLS CertificateVerify to webpki. This restores compatibility with legacy appliance certificates such as X.509 v1 while keeping TLS encryption and all backend address/DNS/loop protections in force; `tls_verify=true` is unchanged.
|
||||
- Expand upstream connection diagnostics with the full nested Hyper/rustls/io error chain, backend/TLS context, 2 KiB UTF-8-safe detail storage and warning-level journal entries for connect failures.
|
||||
- Replace Docker-vhost alias comma input with hostname-style chips for add/remove/paste workflows.
|
||||
- Add per-Docker-vhost HTTP-to-HTTPS redirect, WebSocket and cache controls; new compatible assignments default HTTP-to-HTTPS redirect on while legacy assignments retain their prior redirect-off behavior until explicitly saved.
|
||||
- Align Docker-vhost boolean controls with the application's standard checkbox classes and keep checkbox inputs from inheriting full-width text-input sizing.
|
||||
- Add a Docker-agent default ACL-profile selector. Generated Docker vhosts inherit it unless the application selects its own ACL profile; existing per-app inline ACL configuration is unchanged.
|
||||
- Remove the compression-codec negotiation explainer from the Overview dashboard.
|
||||
- Update release/package identity to 0.18.8.
|
||||
|
||||
## 0.18.7
|
||||
|
||||
- Collapse **Response time history** by default on the Overview dashboard while keeping live sampling active.
|
||||
- Restyle per-interface RX/TX histories to use the same chart geometry and visual treatment as the aggregate RX/TX history, without nested panel backgrounds.
|
||||
- Align expanded Docker-vhost routing and ACL controls with uniform field blocks; Preserve Host and per-app ACL switches now occupy the same label/control rhythm as neighboring inputs, and ACL selects no longer stretch to textarea height.
|
||||
- Update release/package identity to 0.18.7.
|
||||
|
||||
## 0.18.6
|
||||
|
||||
- Add bounded per-interface RX/TX diagnostics from `/proc/net/dev` to the administration status payload and render separate live interface histories without adding per-interface Prometheus labels.
|
||||
- Strengthen compression negotiation regressions with explicit `q=` preference cases for gzip, Brotli, Zstd and deflate; clarify that dashboard counters track the codec actually selected per response.
|
||||
- Align Docker-agent settings inputs/actions, keep Enabled/status/remove controls on one stable row, and add spacing between listener selection and the Add Docker agent action.
|
||||
- Update release/package identity to 0.18.6.
|
||||
|
||||
## 0.18.5
|
||||
|
||||
- Make compression accounting follow an explicit RustProxy-applied codec marker instead of re-reading `Content-Encoding`; add independent gzip/br/zstd/deflate counter regression coverage.
|
||||
- Add an explicit HTTP/1.1 request counter and render total + HTTP/1.1 + HTTP/2 + HTTP/3 request-rate series on the Overview chart.
|
||||
- Add an Open app action to published Docker vhosts, using the assigned frontend listener and expanded proxied hostname.
|
||||
- Label Docker-generated pools in the Backends view with their primary proxied domain.
|
||||
- Remove the global Open proxy shortcut from the page header.
|
||||
- Make Compact density materially tighter than Dense across cards, controls, tables, Docker rows and charts.
|
||||
- Default vhost/Docker proxy timeout controls to explicit 10/120/60/60-second connect/header/read/send limits instead of blank inherited values.
|
||||
- Replace free-form Docker-agent listener-ID entry with the configured named-listener selector; move Enabled left of the centered connection-status badge.
|
||||
- Update release/package identity to 0.18.5.
|
||||
|
||||
## 0.18.4
|
||||
|
||||
- Default backend health checks to TCP for newly created or otherwise defaulted ordinary and Docker vhosts; explicit existing HTTP/off health modes are preserved.
|
||||
- Replace the dense Docker-vhost service editor with summary-first rows. Publish state, service identity, backend runtime health and Hide/Show stay visible; routing, ACL, timeouts and health tuning are expanded only for the selected service.
|
||||
- Collapse secondary Docker-agent inventory metadata behind Agent details while keeping host, service count, last observation and base domain immediately visible.
|
||||
- Rework Settings -> Security into focused account/session and host-policy cards with on-demand password and policy editors.
|
||||
- Move Administration audit into a dedicated modal and stop fetching audit entries merely by opening the Security settings tab.
|
||||
- Update release/package identity and EN/PL UI copy to 0.18.4.
|
||||
|
||||
## 0.18.3
|
||||
|
||||
- Add Docker-vhost search plus persistent per-browser Hide/Show Hidden view controls, and allow each Docker agent to select a configured frontend certificate inherited by its generated vhosts.
|
||||
- Keep Docker inventory polling driven by each agent's configured 5..3600 second interval; the 5-second dashboard refresh reads cached observations only.
|
||||
- Move redirect HTTP/2 and HTTP/3 toggles below listener selection and keep Cache `Updated` + `Live` together at the right side of the toolbar.
|
||||
- Remove the unused `config::yes` helper warning.
|
||||
- Add an Open-in-browser action beside each vhost Enabled state; wildcard-only hosts open the wildcard base domain, while mixed host lists prefer the first non-wildcard name.
|
||||
- Restore the documented HTTP/1.1 backend default for newly created ordinary and Docker vhosts: preserve the public `Host`; existing explicit backend settings are not rewritten.
|
||||
- Write HTTP/1 upstream header names in conventional title case for compatibility with legacy/custom origins that incorrectly treat header names as case-sensitive; HTTP/2 is unaffected.
|
||||
- Add bounded `upstream_error` diagnostics to access logs/live logs so TCP/TLS/HTTP-client failures that previously appeared only as 503 with no upstream status can be distinguished.
|
||||
- Restrict local/error response selectors to supported error statuses; application-style 404 hosts offer only bundled 401/403/404/429/503/504 templates, including a new dedicated 404 template.
|
||||
- Make Docker Publish/Unpublish an immediate per-service configuration action, add per-service Apply, and replace unconditional UI rerendering with an operator-controlled Live view that reads only RustProxy's in-memory state.
|
||||
- Add per-agent Docker inventory polling intervals (5..3600 seconds), while manual refresh still polls immediately.
|
||||
- Add reusable ACL-profile plus inline IP/CIDR ACL controls per Docker application, and protect referenced profiles from deletion.
|
||||
- Add per-vhost proxy connect/response-header/read/send timeout controls for ordinary and Docker-backed vhosts.
|
||||
- Print the Docker-agent bearer token after installation alongside the certificate fingerprint.
|
||||
- Improve 404 Hosts response UX with supported error-status selectors, application-style built-in status pages, cache-diagnostic suppression and protocol toggles beside listener selection.
|
||||
- Add optional per-vhost JSONL access-log files under a configurable directory while retaining the combined-file mode, Logstash and Loki sinks.
|
||||
- Lock HTTP/HTTPS/admin listener addresses that are supplied explicitly by systemd/CLI/environment so the control plane cannot remove, disable or rewrite process-owned binds; listeners not supplied at startup remain editable.
|
||||
- Remove the separate remote-admin risk-acknowledgement requirement; plain remote administration now requires only `--allow-remote-admin`, while legacy `--accept-remote-admin-risk` is accepted as a hidden no-op so older systemd units still start.
|
||||
- Tighten Compact/Dense dashboard density, rename the Shared RAM cache surface to **Cache**, expose redirect targets directly on cards, and keep 404 Hosts aligned with the application error-code set.
|
||||
- Clarify that TLS Policy is inherited globally and show currently effective cipher suites alongside all available rustls suites.
|
||||
- Treat ACME-issued certificates as managed/read-only in the custom-file editor, require certificates to be unassigned (including the administration panel/default binding) before deletion, and default new ACME issuance to the production CA environment.
|
||||
- Make classic HTTP/1.1 Upgrade the default WebSocket path; RFC 9220 Extended CONNECT over HTTP/3 is now an explicit experimental per-vhost opt-in and is advertised only on QUIC listeners with an opted-in vhost.
|
||||
- Split Docker discovery/vhost observability into dedicated `rust_proxy_docker_vhost_*` and `rust_proxy_docker_backend_*` Prometheus metric families; Docker pools no longer appear in ordinary vhost/backend series.
|
||||
- Add a separate live **Docker vhosts** Prometheus collector group, enabled by default, with configured agent/assignment/domain gauges plus Docker vhost traffic/status/duration and full backend health/probe/runtime metrics.
|
||||
- Extend Prometheus/OpenAPI/UI documentation and regression coverage for the Docker metric boundary.
|
||||
- Extend the bundled Grafana operations dashboard with a dedicated Docker-vhost section and per-agent/service filters using only the separate Docker metric families.
|
||||
- Fix Docker discovery compilation against the locked HTTP/body stack by mapping limited-body collection errors explicitly and logging `ApiError` via its `Debug` representation.
|
||||
|
||||
## 0.18.2
|
||||
|
||||
- Secure Docker-agent transport by default with a persistent self-signed ECDSA certificate and SHA-256 certificate pinning in RustProxy; public-CA HTTPS remains available without a pin and plain HTTP is compatibility-only.
|
||||
- Add certificate lifecycle helpers, hardened systemd state storage, installer fingerprint output and TLS regression tests for the standalone Docker agent.
|
||||
- Enable per-Docker-vhost HTTP/TCP backend health checks using the same bounded backend-pool health machinery as ordinary vhosts, with live checking/up/down, latency, probe, request, active and error diagnostics in Docker vhosts.
|
||||
- Rework Docker-agent and Docker-vhost UX around connection security, last observation, detected addresses, route controls and collapsible health-check tuning while retaining per-agent domains, aliases and per-service IP selection.
|
||||
|
||||
## 0.18.1
|
||||
|
||||
- Extend the Docker agent inventory with all usable host addresses (interfaces, routed address, public lookup and optional advertised address) and preserve every published binding per service.
|
||||
- Add per-service Docker backend-IP selection, per-agent default backend IP, arbitrary FQDNs and multiple aliases while retaining short-name expansion below each agent's own base domain.
|
||||
- Support many Docker agents with independent domains such as `docker1.lab.local` and `docker2.lab.local`, plus operator-controlled custom domains.
|
||||
- Remove all special `X-Rust-Proxy-Revision` response-header behavior; the name is no longer inserted, stripped, protected or accepted as a legacy diagnostic setting.
|
||||
- Keep cache-Live placement, production password recovery and Settings navigation improvements from 0.18.0.
|
||||
|
||||
## 0.18.0
|
||||
|
||||
- Add a standalone Go Docker discovery agent with a hardened systemd unit, token authentication, published TCP-port inventory and host/public-IP detection.
|
||||
- Add per-agent Docker configuration, in-memory observations and dynamic Docker vhosts with operator-controlled service/subdomain assignments.
|
||||
- Add Docker vhost/admin UI and OpenAPI endpoints for cached observations and explicit refresh.
|
||||
- Move the cache Live toggle to the action-toolbar edge.
|
||||
- Remove configurable `X-Rust-Proxy-Revision` response exposure and always strip the header.
|
||||
- Use the installed `rust-proxy admin reset-password` command in production recovery guidance.
|
||||
- Update EN/PL strings, documentation, release checks and package identity to 0.18.0.
|
||||
|
||||
## 0.17.0
|
||||
|
||||
- Add Debian packaging assets, a hardened systemd unit, `rustproxy` service user/state/log directories, three-day maximum-gzip log rotation, local `.deb` build tooling and signed APT-repository generation suitable for `rustproxy.linuxiarz.pl`.
|
||||
- Expand Prometheus coverage across all current bounded process/OS diagnostics plus GeoIP, certificate renewal, backend health-probe detail, stream, logging and frontend inventory metrics; add explicit token-free scraping for trusted actual-peer CIDRs.
|
||||
- Add a Grafana operations dashboard under `grafana/`.
|
||||
- Add dedicated listener/certificate-aware local-response / 404 hosts with built-in placeholder, empty/status-only and custom-HTML modes.
|
||||
- Keep the default `RustProxy is running` placeholder uncacheable and intentionally free of optional proxy/cache/backend/diagnostic/security/compression headers.
|
||||
- Reuse vhost-style hostname chips for Redirect source domains.
|
||||
- Update OpenAPI, EN/PL UI, release checks and package identity to 0.17.0.
|
||||
|
||||
## 0.16.1
|
||||
|
||||
- Remove internal configuration revision numbers from successful save feedback in dashboard editors/manual configuration while retaining revision-based CAS and stale-write protection internally.
|
||||
- Update source, UI, OpenAPI, release tooling and packaging identity to 0.16.1.
|
||||
|
||||
## 0.16.0
|
||||
|
||||
- Decouple Custom locations from the main vhost backend fallback. Unmatched paths now use the main pool even when custom rules exist; untouched legacy synthetic root routes are normalized automatically.
|
||||
- Fix same-process public administration login by allowing `rustproxy_session` across only a guarded HTTPS self-admin backend that directly targets the configured administration listener and whose public host is explicitly allowed.
|
||||
- Make RFC 9220 bootstrap wait for the backend HTTP/1.1 upgrade before downstream H3 success, and extend access logging with transport/WebSocket phase/error/reset/upstream status diagnostics.
|
||||
- Add cache transient-memory gauges and procfs RSS/data/swap breakdowns to the dashboard and Prometheus. Existing allocator trimming/release behavior is unchanged; no new transient-memory throttle is introduced.
|
||||
- Reorganize the Vhost editor around clearer backend cards, Authentication subcards and compact protocol controls. New vhosts select standard HTTP :80 plus HTTPS :443 together when available; Redirects reuse the same listener selector; disabled vhost cache hides its subordinate controls and new vhost drafts default cache to off.
|
||||
- Show the local-listener risk acceptance only when the entered backend URL directly targets the configured administration listener. Add protected opt-in `X-RustProxy-Backend` and `X-RustProxy-Backend-Time` response diagnostics for selected member identity and origin response-header latency.
|
||||
- Bump source, UI, OpenAPI and packaging identity to 0.16.0.
|
||||
|
||||
## 0.15.1
|
||||
|
||||
- Fix Custom locations EN/PL translation loading by keeping all UI strings inside the language-pack `translations` map and add a regression check that rejects stray top-level translation keys.
|
||||
- Make visual header rules easier to edit with numbered cards, clear field grouping, empty-state guidance and localized help.
|
||||
- Add a live per-location behavior preview for matching, action, rewrite, cache, ACL and header rules, and reorganize the inline documentation with common examples.
|
||||
- Add one live three-series HIT/MISS/BYPASS activity chart to the RAM cache card and CPU/RSS history charts to the Proxy process card.
|
||||
- Extend offline source/release checks for the new location UX and dashboard charts; package identity is 0.15.1.
|
||||
|
||||
## 0.15.0
|
||||
|
||||
- Expand vhost Custom locations with Nginx-style exact/prefix/`^~`/regex/regex-insensitive matching, upstream path preserve/strip/replace/regex rewrites and backend-free custom responses.
|
||||
- Replace the location header JSON-only workflow with a visual request/response header builder, keep Advanced JSON as an escape hatch, add in-panel documentation and reorganize the location editor into compact functional sections.
|
||||
- Add `nagios/` API checks for administration response time, unavailable/checking backends, backend latency and dropped logging/cold-cache work, with reusable protected session cookies and Nagios performance data.
|
||||
- Move per-vhost `Server-Timing` and verified Cloudflare client-IP diagnostics into the main frontend/details configuration.
|
||||
- Add compact dashboard history charts for RAM-cache residency, network RX/TX and mean response latency, plus administration API RTT and low-priority queue/drop information in the footer.
|
||||
- Add independent cold-cache age policy controls: demote by time since last access, by total hot-tier residency, by LRU pressure and on graceful shutdown.
|
||||
- Add verified effective client/source IP to live logs and logging field mappings; early responses still record at least the transport peer.
|
||||
- Remove the runtime legacy renewal-observation JSON importer. Stopped source upgrades remove the obsolete sidecar as the final upgrade step without importing it or retaining a second legacy copy; SQLite remains the only live renewal-observation store.
|
||||
- Normalize repeated literal path separators for routing/ACL decisions, matching Nginx `merge_slashes` behavior, while preserving the original request target to the backend when no rewrite is configured. URLs such as `/static/js//events.js?v=...` are therefore accepted without weakening encoded-separator/dot-segment protections.
|
||||
- Bump source, panel, OpenAPI, upgrade tooling and package identity to 0.15.0 and extend offline regression contracts for the new controls.
|
||||
|
||||
## 0.14.0
|
||||
|
||||
- Fix administration reverse-proxy Host/Origin handling: explicit DNS allowlist entries describe the external authority instead of the private admin socket port; direct IP/localhost access remains bound to the actual admin port.
|
||||
- Trust forwarded administration host/scheme only from loopback or configured trusted proxy peers, use the external scheme for Origin/CSRF checks, and set/clear Secure session cookies consistently behind HTTPS termination.
|
||||
- Implement RFC 9220 WebSocket over HTTP/3 Extended CONNECT, including `SETTINGS_ENABLE_CONNECT_PROTOCOL`, `:protocol=websocket` validation, HTTP/1.1 backend Upgrade translation, downstream 200 bootstrap, bidirectional H3 DATA transport and FIN/reset cancellation handling.
|
||||
- Replace the separate `h3`/`h3-quinn` pair with `hpx-h3 2.5.19` and its integrated Quinn feature to expose the RFC 9220 protocol extension through the HTTP/3 stack.
|
||||
- Rename dashboard backend, health, security, error-page and recommended-preset labels in English and Polish.
|
||||
- Update release/static checks, HTTP/3 documentation and package identity. The source contains no `certificates.json` certificate metadata path.
|
||||
|
||||
## 0.13.2
|
||||
|
||||
- Fix authenticated dashboard refresh/back-forward session restoration so valid cookies are honored on every panel document route instead of briefly rendering the login shell.
|
||||
- Make managed software updates force a bounded hot-to-cold cache handoff whenever the cold tier is enabled, independent of the ordinary `cold_on_shutdown` preference, and extend the managed systemd stop budget.
|
||||
- Persist non-secret automatic-certificate-renewal observations in SQLite schema v3, preload them before administration listeners are exposed, and import the older `certs/renewals.json` sidecar once for upgrade continuity.
|
||||
- Move the raw full-document editor from primary navigation into **Settings -> Manual config** while retaining `/configuration` as a compatibility browser route.
|
||||
- Update OpenAPI, EN/PL help, cache/renewal/API documentation, migration/backup checks and release identity for 0.13.2.
|
||||
|
||||
## 0.13.1
|
||||
|
||||
- Make administrator browser sessions configurable from 7 to 30 days (30 days by default), replacing the previous short browser lifetime/idle behavior while preserving explicit logout/password/revoke invalidation.
|
||||
- Refresh authenticated cookies only to the remaining absolute server-side expiry so session persistence cannot become an unbounded sliding session.
|
||||
- Add per-backend `accept_local_listener_risk` with a dashboard confirmation and validation path for deliberate local-listener targets such as `127.0.0.1:9090`; `allow_private` and special-address protections remain independent.
|
||||
- Update OpenAPI, transport/security/admin-session documentation, EN/PL strings and release regressions for 0.13.1.
|
||||
|
||||
## 0.13.0
|
||||
|
||||
- Add first-class redirect hosts with dedicated dashboard navigation, named listeners/certificates, exact/prefix and scheme matching, URL/host/path targets, 301/302/303/307/308, path/query policies and redirect cache controls.
|
||||
- Resolve redirect traffic locally before proxy routes while preserving listener ownership and global host ACLs.
|
||||
- Change omitted backend `tls_verify` to default false and update UI/API/documentation accordingly.
|
||||
- Compact TLS certificate cards: show DNS SAN coverage as the same policy-style badges used on vhosts, collapse bindings/files/assigned-vhost details, and inspect older/manual public PEM files when persisted coverage metadata is missing.
|
||||
- Extend OpenAPI, English/Polish translations, regressions and release tooling for 0.13.0.
|
||||
|
||||
## 0.12.1
|
||||
|
||||
- Add revisioned per-section configuration PUT endpoints and move ordinary dashboard forms to them, retaining full-document updates only where multiple sections must publish atomically.
|
||||
- Decouple cache compatibility from the SQLite configuration revision so logging, administration, TLS inventory, metrics and other unrelated saves do not purge hot/cold objects.
|
||||
- Add explicit dashboard subpage routes plus History API navigation so browser refresh preserves the selected panel.
|
||||
- Add independent cold-tier policies for idle objects, LRU evictions and graceful shutdown, reduce the cold-write body queue, flush remaining hot objects before process exit, and trim released allocator memory on glibc/Linux.
|
||||
- Expose certificate DNS SubjectAltName coverage separately from active SNI bindings for uploaded and ACME-managed certificates.
|
||||
- Preserve secure-by-default backend TLS verification when omitted; keep the explicit debug-origin verification bypass and improve corrective validation/help text.
|
||||
- Extend regression/OpenAPI/release checks and bump source/package identity to 0.12.1.
|
||||
|
||||
## 0.12.0
|
||||
|
||||
- Move raw TCP/UDP stream management from Settings to a dedicated **Streams** main-navigation page directly below Vhosts.
|
||||
- Add vhost-style searchable stream cards and a modal editor with Details, Listener & upstream, and Limits tabs plus an explicit **Add TCP/UDP listener** action.
|
||||
- Add fixed-cardinality runtime telemetry per active stream: connections/sessions, completed sessions, active sessions, rejects, errors, RX/TX bytes and UDP packet counters.
|
||||
- Add per-stream live RX/TX rate charts in the dashboard while keeping desired stream changes visibly pending until the process restarts and the listener is actually active.
|
||||
- Change named HTTP/HTTPS listener bind-address editing from a textarea to chip-style addresses matching the Vhost hostname interaction, preserving existing multi-address validation.
|
||||
- Keep stream forwarding as raw Layer 4 with no HTTP vhost, ACL, cache, headers, compression or authentication envelope.
|
||||
- Extend authenticated-asset and offline release/source regressions for the new Streams page and telemetry contracts; bump Cargo, panel, OpenAPI and upgrade/package identity to 0.12.0.
|
||||
- Extend the Debian 13+ one-line bootstrap with `auto`/`install`/`update` modes; managed updates build the new source as an unprivileged user and delegate to the existing backup/health-check/rollback update path while preserving saved listeners and private data.
|
||||
|
||||
## 0.11.5
|
||||
|
||||
- Accept percent-encoded spaces (`%20`) in otherwise unambiguous request paths while preserving rejection of encoded separators, double-decoding hazards, controls and dot-segment ambiguity.
|
||||
- Avoid the `h3-quinn 0.0.10` `stop_sending()` panic path when an HTTP/3 request body is dropped while a receive read is pending.
|
||||
- Add raw layer-4 TCP/UDP stream hosts on dedicated listeners with bounded TCP connections / UDP client sessions and restart-bound configuration in the admin panel.
|
||||
- Add a Debian 13+ source bootstrap that installs build dependencies and Rust, clones/builds the repository and installs the systemd service with the explicitly requested public admin profile.
|
||||
|
||||
- Match Varnish built-in request-method behavior for the shared cache: `GET`/`HEAD` participate in lookup while successful POST/PUT/PATCH/DELETE/OPTIONS/TRACE requests no longer trigger an implicit global purge.
|
||||
- Replace the conservative per-request-header/backend-member cache identity with a Varnish-style Host + URL primary identity, isolated by RustProxy vhost/config scope, and use response `Vary` as the secondary representation selector.
|
||||
- Share cached objects across load-balanced members and across GET/HEAD, reducing avoidable MISSes while retaining Cookie/Authorization pass behavior and response privacy guards.
|
||||
- Preserve `X-Cache-Resident-Age` across backend 304 revalidation and hot/cold tier movement. Cold metadata format 2 stores variant identity and resident age explicitly.
|
||||
- Add cache regressions for Vary variants/schema changes, Host/URL hashing, explicit ports, HEAD eligibility and resident-age continuity; update release/package/API/UI metadata to 0.11.5.
|
||||
|
||||
## 0.11.4
|
||||
|
||||
- Fix Force SSL frontend validation and messaging: require an actual non-TLS listener for the incoming redirect, prefer HTTPS port 443 when multiple TLS listeners are selected, and reject only ambiguous non-standard HTTPS target ports.
|
||||
- Add a visual reusable ACL-profile rule editor with add/remove/action/CIDR rows. Keep bulk paste/import as an advanced path, normalize invisible Unicode whitespace and report malformed rules with their source line.
|
||||
- When a vhost disables cache, strip and suppress RustProxy `X-Cache`, `X-Cache-Hits`, `Cache-Status`, `X-Cache-Reason` and `X-Cache-Resident-Age` diagnostics for that response.
|
||||
- Render backend pools belonging to disabled vhosts as muted `Disabled` rows in the main dashboard instead of classifying them as unavailable.
|
||||
- Add source/offline regression coverage and bump release/package/UI/OpenAPI/update metadata to 0.11.4. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.11.3
|
||||
|
||||
- Add per-vhost control over forwarding the effective client IP to the application. Disabling it removes `Forwarded`, `X-Forwarded-For` and `X-Real-IP` only on the backend request; ACLs, GeoIP, rate limiting and Tinyauth continue to use the real client identity.
|
||||
- Add a compact Vhost search/filter for vhost IDs, hostnames/wildcards and backend IDs/URLs.
|
||||
- Fix the invalid `quinn = 0.11.22` manifest requirement to the resolved `0.11.12` and stop `dev.sh` from rewriting a valid checked-in `Cargo.lock`.
|
||||
- Fix JSONL access logging under the hardened systemd unit by provisioning `/var/log/rustproxy` as a writable service log directory while keeping `ProtectSystem=strict`.
|
||||
- Add source/offline regression coverage and bump release/package/UI/OpenAPI/update metadata to 0.11.3. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.11.2
|
||||
|
||||
- Fix administration HTTPS access negotiated over HTTP/2. The admin guard now derives the effective authority from H2/H3 `:authority` (via the request URI) when no legacy `Host` header is present.
|
||||
- Preserve strict HTTP/1.x Host handling and reject conflicting HTTP/2 `Host` versus `:authority` values to avoid ambiguous authority validation.
|
||||
- Add per-vhost Force SSL beside frontend selection. Cleartext requests receive a non-cacheable HTTP 308 to the same hostname/path/query on the vhost's unique selected TLS port; ambiguous multi-port TLS selections are rejected.
|
||||
- Map NPM `ssl_forced` (and migrator `--force-https`) to RustProxy `force_ssl`, retaining HTTP+HTTPS listener bindings when available instead of importing forced hosts as TLS-only.
|
||||
- Add unit/integration regression coverage for HTTP/2 administration authority, `/healthz`, Force SSL redirect construction/validation and NPM `ssl_forced`; bump release/package/UI/OpenAPI/update metadata to 0.11.2. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.11.1
|
||||
|
||||
- Fix release update health checks when the administration panel uses persisted HTTPS or a persisted bind different from the install-time CLI address. The check now resolves the active admin listener/scheme from `config.sqlite3` and honors the admin Host allowlist.
|
||||
- Add a standard-library-only Nginx Proxy Manager SQLite migrator. It reads `proxy_host`, creates RustProxy vhosts/backends, preserves wildcard names/WebSocket/enabled/H2 intent, uses the RustProxy default certificate for imported TLS hosts unless a named certificate is selected, and keeps unsupported NPM policy/custom-config items as explicit review warnings.
|
||||
- Make NPM migration dry-run by default, emit `npm-migration-plan.json`, detect hostname conflicts, split source records above RustProxy's 16-host limit and use revisioned authenticated API writes only with explicit `--apply`.
|
||||
- Add offline regression coverage and bump release/package/UI/OpenAPI/update metadata to 0.11.1. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.11.0
|
||||
|
||||
- Add reusable ACL Profiles with optional IP/CIDR ACL and country allow/block rules. Vhost profile, inline vhost ACL and route ACL enforcement remains cumulative.
|
||||
- Add an ACL Profiles navigation page and per-vhost profile selection without removing individual vhost policy controls.
|
||||
- Add chip-style hostname editing and validated leading `*.` wildcard domains. Exact hosts win before the longest matching wildcard on the same listener.
|
||||
- Add compact browser-session request-rate history charts to vhost cards, with progressive compaction of older samples.
|
||||
- Add the built-in HTTP 401 page and classify normal WebSocket tunnel EOF/reset/abort/broken-pipe termination after a successful 101 upgrade as `websocket_closed` rather than a body/proxy error.
|
||||
- Redirect plaintext requests received on the HTTPS administration socket to HTTPS while keeping application content unavailable over plaintext. Permit valid DNS Host values when the HTTPS admin hostname allowlist is empty; explicit allowlists remain strict.
|
||||
- Extend named listeners to up to 16 explicit local addresses under one protocol policy. Multiple-address configurations reject unspecified `0.0.0.0`/`::` binds.
|
||||
- Align the Logging field-builder dialog with the Vhost configuration modal and reposition the Configure fields action next to the format preset.
|
||||
- Make source ZIP generation deterministic and verify byte-identical archives in release smoke tests.
|
||||
- Bump Cargo, panel, OpenAPI, installer/update metadata and package identity to 0.11.0. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.10.0
|
||||
|
||||
- Add an optional persistent cold cache tier under the private data directory. Hot LRU/idle objects demote through a bounded asynchronous queue; fresh cold hits are SHA-256 checked and promoted back into the bounded RAM tier.
|
||||
- Add hot/cold object, byte, promotion, demotion, cold-hit, eviction/error and queue-drop observability to the Cache API, panel and Prometheus output.
|
||||
- Add cold-tier path, byte/object budgets and idle demotion settings; purge/config publication invalidates both tiers and startup rebuilds the same-revision cold index.
|
||||
- Document browser hard-reload revalidation behavior and add translations for the exact `request_no_cache`, `request_max_age`, `request_min_fresh` and `request_pragma_no_cache` reasons.
|
||||
- Add structured-log Standard, Nginx-style, ECS-style and Minimal presets plus a visual field picker/renamer with JSON preview; preserve advanced raw JSON mappings.
|
||||
- Reuse the shared application card component for Logging sinks and remove release-specific fieldset border styling.
|
||||
- Add baseline multi-stage Docker/OCI packaging with an unprivileged runtime user and persistent data volume. Docker discovery remains deferred.
|
||||
- Bump Cargo, panel, OpenAPI, installer/update metadata and package identity to 0.10.0. Rust compilation/runtime acceptance remains open in this packaging environment.
|
||||
|
||||
## 0.9.0
|
||||
|
||||
- Redesign the vhost list as readable cards with listener/protocol/TLS/cache identity and live pool health, request, active, error, latency and traffic metrics.
|
||||
- Add bounded asynchronous structured access-log sinks for JSONL files, Logstash TCP and Loki HTTP(S), with configurable JSON field mapping/static fields and sink delivery/drop/error counters.
|
||||
- Expand cache object inspection with body bytes, resident bytes and metadata overhead; add optional `X-Cache-Resident-Age`.
|
||||
- Add administration HTTPS with either the application-managed default certificate or a selected inventory certificate. Persisted non-loopback administration binds are accepted when HTTPS is enabled.
|
||||
- Keep loopback HTTP as the default and retain the explicit legacy risk gate for plain remote HTTP. Secure session cookies are marked `Secure` on HTTPS administration.
|
||||
- Add global TLS 1.2/1.3 and rustls cipher-suite policy plus per-vhost TCP TLS overrides. HTTP/3 vhosts must use the global TLS 1.3 policy.
|
||||
- Add dedicated Logging navigation and full-width Settings tabs with new Administration and TLS policy pages.
|
||||
- Complete roadmap items for remote HTTPS administration and `X-Cache-Resident-Age`; bump release identity, OpenAPI and packaging metadata to 0.9.0.
|
||||
- Rust compilation/runtime acceptance remains unverified in this packaging environment.
|
||||
|
||||
## 0.8.1
|
||||
|
||||
- Enable the shared RAM cache by default.
|
||||
- Replace blanket conditional-request bypass with local conditional HITs for fresh `If-None-Match` / `If-Modified-Since` requests.
|
||||
- Add validator-based backend revalidation: request `no-cache`, freshness constraints and legacy `Pragma: no-cache` can revalidate a stored representation; backend 304 refreshes metadata and reuses the cached body.
|
||||
- Keep request `no-store` as a hard bypass. Allow response `Cache-Control: no-cache` with ETag/Last-Modified to be stored only for mandatory validation; `no-store` and `private` still forbid shared storage.
|
||||
- Retain expired validator-bearing objects for a bounded one-hour revalidation keep window without stale delivery.
|
||||
- Raise the configurable object ceiling from 8 MiB to 1 GiB, still bounded by the global 1 GiB resident budget.
|
||||
- Grow fill buffers incrementally and serialize very large fills through the existing fill semaphore to avoid preallocating the configured object ceiling.
|
||||
- Exclude cache-control/Pragma and conditional/precondition headers from representation-key hashing because they govern reuse rather than representation identity.
|
||||
- Add cache diagnostics and regressions for conditional HIT, revalidation, no-cache/no-store semantics and the 1 GiB configuration ceiling.
|
||||
- Bump Cargo, panel, OpenAPI, installer/update metadata and package identity to 0.8.1.
|
||||
|
||||
## 0.8.0
|
||||
|
||||
- Global static-cache defaults now include common image, stylesheet/script, font, media and download extensions, with request Cookie ignored for matching assets by default. The global and per-vhost controls are visible in the cache UI; `Set-Cookie`, `private`/`no-store` and `Vary: Cookie` still prevent shared caching.
|
||||
- HTTP/2 and HTTP/3 are per-vhost frontend opt-outs next to listener selection. Controls are enabled only when a selected named listener supports the protocol; TLS H2 ALPN is narrowed by SNI per vhost.
|
||||
- Settings -> Listeners uses normal page scrolling instead of an extra nested scrollbar.
|
||||
|
||||
- Add per-vhost request throttling with graphical request/window/burst controls, country-specific limits and country block/allow-only policies. Return built-in HTML 429/403 responses while preserving custom error-page overrides.
|
||||
- Download the PDDL `sapics/ip-location-db` user-country IPv4/IPv6 data during first installation over HTTPS and verify publisher SHA-256 checksums; expose load status without exposing client data.
|
||||
- Verify the installed GeoIP database against current publisher SHA-256 files on every managed update and download only stale/missing assets before downtime.
|
||||
- Make managed updates regenerate the systemd unit and restore it together with code/private data on failure; preserve and report the original failure reason and add a development-only `--reset-config` recovery path for intentionally incompatible saved vhost/settings documents.
|
||||
- Add an opt-in per-vhost Cloudflare client-IP mode that accepts `CF-Connecting-IP` only when the direct peer belongs to Cloudflare's published edge CIDRs.
|
||||
- Add Server-Timing response diagnostics. Disabled per-vhost H3 removes `Alt-Svc` and rejects HTTP/3 requests for that vhost.
|
||||
- Move vhost listener binding exclusively to named listener selection. Listener addresses are configured under Settings; remove the pre-production inline/global listener compatibility importer and reject the old vhost format instead of migrating it.
|
||||
- Make health-check mode `off` fully disable active probes and passive health classification instead of quietly learning health from production requests.
|
||||
- Add a new-origin debugging preset for HTTPS-by-IP origins: default pool/private-origin/HTTP1/preserve-host enabled and backend TLS verification disabled for newly created panel backends, with explicit warnings about the certificate-verification risk and mismatched settings.
|
||||
- Keep per-vhost inherit/override controls for static-cookie cache behavior while the global defaults cover common static extensions. Cookie is ignored only for the cache key/request bypass decision.
|
||||
- Fix cache `Age` calculation to retain sub-second response delay and apply RFC 9111 corrected received age before adding response delay.
|
||||
- Bump Cargo, panel, OpenAPI, installer/update metadata and package identity to 0.8.0.
|
||||
- Rust compilation/runtime acceptance remains unverified in this packaging environment.
|
||||
|
||||
## 0.7.3
|
||||
|
||||
- Generate the one-time administrator setup token from the release CLI even before
|
||||
the first server start; retain the rule that it is invalid after setup completes.
|
||||
- Add explicit remote-panel opt-in for `0.0.0.0`/`::`, requiring both
|
||||
`--allow-remote-admin`; keep plain-HTTP risk visible.
|
||||
- Make Linux/systemd install defaults listen on HTTP 80 and HTTPS 443; add
|
||||
`--no-https` for explicit HTTP-only installation.
|
||||
- Add deployment and admin-host regressions and bump release/package/UI/schema
|
||||
identifiers to 0.7.3.
|
||||
- Hotfix backend HTTPS-by-IP with optional `tls_server_name`: TLS SNI and hostname
|
||||
verification may use a DNS name while the validated TCP target stays pinned to
|
||||
the configured backend URL.
|
||||
- Add an explicit per-backend `tls_verify` switch, secure by default. Administrators
|
||||
may turn verification off for an HTTPS origin without weakening DNS/address/self-loop
|
||||
policy. Add matching 503/504 HTML gateway pages while preserving custom-page overrides.
|
||||
- Rust compilation/runtime acceptance remains unverified in this packaging environment.
|
||||
|
||||
## 0.7.2
|
||||
|
||||
- Publish a distinct patch release; keep both previous 0.7.1 deliveries historical.
|
||||
- Remove the build.rs panic on absent SWAGGER_UI_DOWNLOAD_URL. The asset preparer
|
||||
defaults to pinned Swagger UI 5.32.11 independently of Cargo config discovery.
|
||||
- Remove the independently downloading utoipa-swagger-ui adapter and embed the
|
||||
prepared JS/CSS directly, for debug and release. Existing admin guards stay in place.
|
||||
- Prepare assets with the existing Python 3.10+ tool requirement, now also needed
|
||||
for direct Cargo builds. Support absolute local tag ZIPs, optional archive SHA-256,
|
||||
bounded exact-member reads, validated download caching and retained license notices.
|
||||
- Resolve build input paths from CARGO_MANIFEST_DIR, track local sources and outputs,
|
||||
and report missing tools/assets explicitly instead of silently changing UI versions.
|
||||
- Add executable synthetic-archive regression tests and protected license notices.
|
||||
- Update release identifiers, packaging/update metadata and migration/build notes.
|
||||
- Rust compilation and actual Swagger rendering remain unverified in this environment.
|
||||
|
||||
## 0.7.1
|
||||
|
||||
- Add visual request/response header editing to each custom vhost location, with
|
||||
set/append/remove, validation, isolation and synchronized optional JSON.
|
||||
- Split anonymous sign-in from the operational document and module/language bundles.
|
||||
Remove the login tagline; preserve the original brand and compact square style.
|
||||
- Reduce public health to `status` and auth discovery to `setup_required` only.
|
||||
Make the public allowlist exact by method and path; private/unknown requests are
|
||||
denied before body/query extraction, including method mismatches and aliases.
|
||||
- Keep Origin/Host/CSRF/session guards; reject duplicate CSRF/marker headers and
|
||||
hide login/setup JSON parser details. Clear UI data across tabs and on revocation.
|
||||
- Add authenticated `/docs` and OpenAPI with pinned, build-embedded Swagger UI,
|
||||
same-session authorization, read-only execution by default and CSRF-confirmed writes.
|
||||
- Replace updater reliance on a public version with local MainPID/executable checks.
|
||||
- Add source contracts, browser script regressions, actual-router Rust tests and a
|
||||
read-only anonymous-access probe. Rust/build/vendor-renderer acceptance not completed.
|
||||
|
||||
## 0.7.0
|
||||
|
||||
- Renew managed ACME profiles automatically with shared worker bounds, jitter,
|
||||
backoff, private observations and validated CAS hot deployment; expose opt-out,
|
||||
check-now and dry-run controls. Keep previous certificates active on failure.
|
||||
- Add install.sh/update.sh for Linux/systemd, root-owned release switching,
|
||||
stopped full-data backups and code/data rollback on failed startup/version checks.
|
||||
- Add per-vhost Basic Auth with Argon2id-only storage, optional verified upstream
|
||||
credentials and cumulative graphical IP ACLs. Keep protected content out of cache.
|
||||
- Add WebSocket toggles and graphical custom path locations, including explicit
|
||||
exclusion of dedicated path origins from normal pool/sticky selections.
|
||||
- Replace the sample welcome page with neutral information, make the protocol
|
||||
fixture opt-in, unify square modal and Settings-tab styling, preserve branding.
|
||||
- Add renewal/deployment helper tests and Rust/browser regressions. Rust compilation,
|
||||
live CA renewal and real systemd deployment remain unverified in this environment.
|
||||
|
||||
|
||||
## 0.6.0
|
||||
|
||||
- Replace separate legacy routes with vhosts and a one-way, validated compatibility importer; preserve path-pinned origins, ACLs and existing listener scope.
|
||||
- Add HTTP-01 webroot domain validation, Cloudflare DNS-01 and OVH DNS-01 alongside RFC2136 using private Certbot workers.
|
||||
- Unify certificate creation/import in a provider-picker modal; record optional issuer metadata in the library and keep secrets outside exported configuration.
|
||||
- Add an independently configurable Prometheus endpoint with actual-peer CIDRs, optional environment-sourced bearer token, bounded scrapes and collector switches.
|
||||
- Export application/admin/listener/vhost/backend/cache/system data and full-exchange vhost histograms with bounded configured labels.
|
||||
- Split Settings into functional switching cards; preserve dirty values, keyboard access and translation discovery; remove Security and legacy routing sidebar entries.
|
||||
- Add offline provider/browser regression tests and Rust tests for migration, ACME challenge isolation and scrape authorization. Rust compilation/runtime and actual CA/provider integrations remain unverified.
|
||||
- Preserve the original brand assets. Automatic certificate renewal, Cloudflare Tunnel and Docker discovery remain deferred.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
- Add a compact dedicated cache panel with vhost/domain counters, object pagination,
|
||||
TTL/Age/hits, memory/fill diagnostics and authenticated selective purge.
|
||||
- Fix reserved administrator-cookie ordering and empty terminating DATA frames;
|
||||
emit fixed cache decision reasons without exposing request secrets.
|
||||
- Replace special X-Mock-Origin hiding with the explicit global/vhost revision
|
||||
switch; ordinary response rules still handle arbitrary removable headers.
|
||||
- Default HTTP/3 on TLS bindings, retain explicit null opt-outs, and explain
|
||||
overlapping sockets with ownership and concrete protocol/limit differences.
|
||||
- Return 503 for upstream connection/unavailability, 502 for invalid responses
|
||||
and 504 for header timeouts; generated errors use no-store.
|
||||
- Add basic asynchronous Certbot DNS-01/RFC2136 issuance, staging-first consent,
|
||||
private TSIG/account profiles, output validation and explicit library import.
|
||||
No automatic renewal scheduler or real CA validation is claimed.
|
||||
- Add offline helper and UI checks plus Rust regression source. Rust/Cargo remain
|
||||
unavailable in the packaging environment; compilation/runtime unverified.
|
||||
|
||||
|
||||
## 0.4.0
|
||||
|
||||
- Rebuild standard Forwarded and X-Forwarded metadata at an explicit trusted-proxy boundary; use verified client IP for ACL/affinity, never for destination routing.
|
||||
- Add per-vhost Tinyauth subrequests, identity header allowlists, safe same-login-origin redirects and fail-closed checks before origin/static/cache/WebSocket use.
|
||||
- Move certificate upload into an independent inventory; assign certificates by ID per vhost and expose metadata-only inventory reads. ACME is not implemented.
|
||||
- Add named multiple-IP listeners with descriptive scope, opt-in legacy routes, reusable vhost references and actual/desired plans.
|
||||
- Add Quinn/h3-based HTTP/3 UDP transport, TLS 1.3/SNI, Alt-Svc, per-endpoint connection and per-connection stream/idle limits, shared proxy policies and bounded shutdown. Preserve TCP HTTP/2 plus HTTP/1.1.
|
||||
- Hide request-ID/revision headers by default; add individual overrides and optional mock-origin stripping. Apply effective Server policy across all response paths, including extra sockets.
|
||||
- Partition cache by actual frontend IP/port and safely probe unknown-length empty requests; preserve nonempty body frames instead of discarding them.
|
||||
- Raise toast above active dialogs without making it inert under the modal; retain the logo, compact UI and discovered language packs.
|
||||
- Add a loopback-only fake-auth development peer and Rust integration sources for forwarding, auth, extra-socket cache, listener ownership and real QUIC/TCP fallback.
|
||||
- Execute frontend/helper/static checks documented in TEST_REPORT.md. Rust/Cargo are unavailable: no passing compilation, real proxy run or full RFC-conformance claim.
|
||||
|
||||
|
||||
## 0.3.0
|
||||
|
||||
- Split the large status JSON macro into small objects and an explicit feature map;
|
||||
preserve response fields without increasing Rust's macro recursion limit.
|
||||
- Add optional per-vhost certificate inventory selection and PEM file upload.
|
||||
Validate key/certificate pairing and names, write private immutable files, and
|
||||
activate only through the existing revisioned configuration update.
|
||||
- Add per-vhost cache overrides and selective invalidation, including stale
|
||||
in-flight fill cancellation while leaving other host entries intact.
|
||||
- Add administrator-authored, bounded global/vhost error pages, static vhost and
|
||||
missing-path responses, direct-IP and unknown-host responses. Retain ACL checks,
|
||||
HEAD handling and authentication challenges; never execute HTML in the admin UI.
|
||||
- Move access logs into a separate modal/docked viewer with fixed filters,
|
||||
vhost identity, pause, scoped search/status/method/cache controls and JSON export.
|
||||
- Add a compact vhost list, tabbed dialog, live health/latency summaries and visual
|
||||
per-host response/request headers; keep the original logo and favicon.
|
||||
- Add density preferences and a Settings shortcut to Security.
|
||||
- Add a Python-only mock origin with random data, cache/no-store/private/cookie
|
||||
paths, compression-size payloads, controllable delay/health and error statuses.
|
||||
- Add Rust regression source for pages, cache scoping, TLS staging and API guards.
|
||||
- Rust compilation/runtime acceptance remains unverified: toolchain unavailable.
|
||||
Executed checks and their exact limitations are recorded in TEST_REPORT.md.
|
||||
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Replace SizeAbove(u16) with a custom u64 predicate; add >64 KiB threshold regressions.
|
||||
- Add IP/port/TLS-bound virtual hosts with frontend(s), backend pool and path policies.
|
||||
- Enforce real accepted destination matching; isolate legacy routes from extra sockets.
|
||||
- Add weighted round-robin, least-connections, least-traffic, adaptive and IP hashing.
|
||||
- Add bounded TCP/HTTP health checks, separate passive failures, recovery and slow start.
|
||||
- Add connection keepalive controls, backup members, drain and opaque cookie/IP affinity.
|
||||
- Preserve compatible observations/tokens across hot edits; recheck changed/re-enabled members.
|
||||
- Keep leases through full uploads/responses/tunnels; never replay failed requests.
|
||||
- Add per-vhost TLS-only HSTS, nosniff, frame/referrer/CSP/permissions headers.
|
||||
- Retain HTTP/1.1 ALPN with HTTP/2 for TLS frontends and HTTPS origins.
|
||||
- Separate cache identities by selected member; bypass cookie-affine pools.
|
||||
- Add compact vhost editor, atomic legacy migration, backend observations/API/metrics/log IDs.
|
||||
- Extend discovered English/Polish translations; preserve original logo and favicon.
|
||||
- Add Rust regression source and a real-binary vhost/keepalive/health acceptance suite.
|
||||
- Execute 63 simulated-API UI, 24 SQLite, 21 upgrade, 4 language-mirror, 10 protocol-peer
|
||||
and 7 backend-fixture checks. None is a passing Rust build or runtime test.
|
||||
- Rust/Cargo remain unavailable in the packaging environment; compilation/runtime
|
||||
acceptance and a resolved Cargo.lock remain mandatory before deployment.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
Development source advancing directly from 0.0.6. Cloudflare is deferred.
|
||||
|
||||
### Added
|
||||
|
||||
- Persisted public listener addresses/ports, 80/443 presets, startup defaults and restart status.
|
||||
- Bounded streaming shared RAM cache, TTL/Age, LRU, privacy/Vary protections, per-route bypass, optional HIT/MISS headers and audited purge.
|
||||
- Streaming gzip, Brotli, Zstandard and deflate controls, final Server policy and a global client-response header editor.
|
||||
- Compact dashboard with system/process/cache diagnostics, log filters and export.
|
||||
- Compile-time language discovery, JSON packs, metadata/RTL/fallback, and preservation of extra packs during upgrade.
|
||||
- Example unprivileged low-port service and cache/settings real-binary integration test source.
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow ordinary remote-origin 80/443 while guarding local proxy/admin listener targets.
|
||||
- Keep original logo/favicon; reduce panel spacing and improve data density.
|
||||
- Invalidate cache and older fills on config changes, explicit purge and successful unsafe methods.
|
||||
- Expand source/SQL/upgrade/language/frontend checks; actual execution scope is in docs/TEST_REPORT.md.
|
||||
|
||||
### Verification boundary
|
||||
|
||||
Rust/Cargo and real Rust integration were unavailable. This is a source candidate,
|
||||
not a successfully compiled or production-certified binary. No lockfile is fabricated.
|
||||
|
||||
## 0.0.6
|
||||
|
||||
Cumulative development source release. The planned 0.0.3, 0.0.4 and 0.0.5 scopes
|
||||
are included here, not represented as separately published archives.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Explicitly select `src/auth/mod.rs` to prevent the reported flat/folder module
|
||||
conflict when obsolete 0.0.1 source remains in an existing checkout.
|
||||
- Detect mixed source layouts and preserve the known legacy auth file; refuse to
|
||||
delete unrecognized local changes.
|
||||
- Support interactive username input for `admin init`.
|
||||
- Replace managed source directories with rollback on copy failure rather than
|
||||
encouraging overlay extraction.
|
||||
|
||||
### Added
|
||||
|
||||
- DNS and HTTPS manual backends with per-backend pools, bounded DNS workers,
|
||||
validated DNS answers, optional CIDR allowlists and additional PEM trust anchors.
|
||||
- rustls public TLS listener, persistent development default certificate, exact SNI
|
||||
bindings, local generate/import commands and explicit hot reload.
|
||||
- Public HTTP/2 over TLS ALPN and HTTP/2/auto backend protocol options.
|
||||
- Validated HTTP/1.1 WebSocket handshakes and bounded bidirectional tunnels,
|
||||
including TLS on either side, connection leases and a separate idle timeout.
|
||||
- Transport metrics, WebSocket lifetime logging, TLS editor and advanced backend
|
||||
controls in the English/Polish panel.
|
||||
- Backup of configured/default certificate files alongside the SQLite snapshot.
|
||||
- Upgrade regression tests, transport configuration tests, real protocol test
|
||||
scripts and CI steps. Test execution limits are recorded in TEST_REPORT.md.
|
||||
|
||||
### Changed
|
||||
|
||||
- Public TLS is enabled by default by `dev.sh`; direct binary startup keeps it optional.
|
||||
- Listener ports are protected across HTTP, HTTPS and administration.
|
||||
- All Markdown documentation is maintained in English.
|
||||
- The roadmap identifies the combined transport release and upcoming Docker stages.
|
||||
|
||||
## 0.0.2
|
||||
|
||||
- Introduced RustProxy naming, administrator setup, Argon2id passwords, sessions,
|
||||
CSRF checks, login throttling, password recovery and credential revocation.
|
||||
- Added host/route ACLs, generic request/response header policies, administration
|
||||
audit, SSE dashboard updates and security controls in the bilingual panel.
|
||||
- Added an additive SQLite migration, offline validation and online database backup.
|
||||
- Rust build/runtime verification was unavailable for the source package.
|
||||
|
||||
## 0.0.1
|
||||
|
||||
- Initial manual-backend HTTP/1.1 proxy, streaming and keep-alive.
|
||||
- SQLite configuration, dynamic host/alias/path routing and local token control plane.
|
||||
- English/Polish interface, bounded access log, counters, CLI, demo backend and dev.sh.
|
||||
- Rust build/runtime verification was unavailable for the source package.
|
||||
@@ -38,7 +38,7 @@ Encoded separators (`%2f`, `%5c`), encoded `%`, dot segments and other ambiguous
|
||||
|
||||
## Actions
|
||||
|
||||
A location can either proxy to a backend or return a local response.
|
||||
A location can proxy to a backend, serve an existing Web Service, or return a local response.
|
||||
|
||||
### Proxy
|
||||
|
||||
@@ -51,7 +51,11 @@ Supported path transformations:
|
||||
- **Replace prefix** — replace the matched prefix with another normalized path prefix.
|
||||
- **Regex rewrite** — available for regex locations; Rust regex captures can be referenced as `$1` or `${1}` in the replacement.
|
||||
|
||||
The query string is preserved. Rewrites change only the upstream path; cache identity remains based on the public client URL.
|
||||
The query string is preserved. Rewrites change only the selected source path; reverse-proxy cache identity remains based on the public client URL.
|
||||
|
||||
### Web Server
|
||||
|
||||
`Web Server` selects one reusable service previously created in the **Web Server** workspace. The location stores only the Web Service ID; document root, index list and directory-listing policy remain in that shared service. Existing location matching and path rewriting are reused, but backend pinning and reverse-proxy object-cache controls do not apply to local files. See [WEB_SERVER.md](WEB_SERVER.md).
|
||||
|
||||
### Local response
|
||||
|
||||
@@ -93,4 +97,4 @@ Authentication, vhost rate limits, country policy, security headers, compression
|
||||
|
||||
## What is intentionally not an Nginx parser
|
||||
|
||||
Custom locations do **not** execute arbitrary Nginx directives or configuration snippets. RustProxy does not currently implement location-level `try_files`, filesystem aliases/roots, embedded scripting, arbitrary `if` expressions or arbitrary module directives. Use the explicit UI controls and the documented JSON schema instead; unknown fields are rejected on save.
|
||||
Custom locations do **not** execute arbitrary Nginx directives or configuration snippets. RustProxy does not currently implement location-level `try_files`, per-location filesystem aliases/roots, embedded scripting, arbitrary `if` expressions or arbitrary module directives. Static roots are defined only by reusable Web Services. Use the explicit UI controls and the documented JSON schema instead; unknown fields are rejected on save.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# HTTP/3 transport (0.22.3)
|
||||
# HTTP/3 transport
|
||||
|
||||
**Uncompiled development source in this environment.** This release adds an actual
|
||||
QUIC/HTTP/3 adapter, not only an Alt-Svc header. It does not claim independent full-RFC
|
||||
|
||||
+6
-5
@@ -1,4 +1,4 @@
|
||||
# Installing and updating RustProxy 0.24.10
|
||||
# Installing and updating RustProxy 0.25.0
|
||||
|
||||
The scripts prepare a Linux/systemd installation. This source archive is **not a
|
||||
verified production build**: Rust/Cargo, real CA operations, live systemd startup
|
||||
@@ -20,10 +20,11 @@ clones `https://git.linuxiarz.pl/gru/RustProxy` and builds with `cargo build --r
|
||||
Its default `auto` mode calls `install.sh` only when no managed installation exists. When
|
||||
`/opt/rustproxy/install.json` exists it calls `update.sh`, which uses the saved installation record,
|
||||
backs up private state, switches the release, verifies health/version and rolls code/data/unit back
|
||||
on failure. First install intentionally starts the admin listener on `0.0.0.0:9090` over plain HTTP
|
||||
using `--allow-remote-admin`; updates preserve the saved admin/listener
|
||||
settings. Firewall/private-network restriction is therefore required. The normal `install.sh`
|
||||
default remains loopback-only.
|
||||
on failure. First install keeps administration on `127.0.0.1:9090` over HTTP, matching the normal
|
||||
`install.sh` loopback-safe default. Updates preserve the saved admin/listener settings. For initial
|
||||
remote access use an SSH tunnel, then enable Administration HTTPS before persisting a non-loopback bind.
|
||||
Plain remote HTTP requires both an explicit non-loopback `RUSTPROXY_ADMIN_LISTEN` and
|
||||
`RUSTPROXY_ALLOW_REMOTE_ADMIN=1`, and should be limited to a trusted private network.
|
||||
|
||||
Equivalent prerequisite commands are:
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# RustProxy 0.4.0 - forwarding, Tinyauth, listeners and certificate library
|
||||
# RustProxy 0.4.0 integrations - historical implementation record
|
||||
|
||||
> Historical context. This document records the 0.4.0 integration milestone and is retained
|
||||
> for traceability. Current behavior is documented in the functional/technical guides linked
|
||||
> from [README.md](README.md).
|
||||
|
||||
This is source implementation, not a verified binary. Read TEST_REPORT.md before deployment.
|
||||
The admin panel remains local; public frontend TLS does not make the admin listener remote-safe.
|
||||
|
||||
@@ -17,6 +17,12 @@ This fixes the previous reconnect loop where `--livelogs` treated the TLS listen
|
||||
|
||||
The live path is separate from configured file/syslog sinks. Request processing publishes into a bounded Tokio broadcast channel without waiting for viewers. A slow viewer receives an explicit `gap` event with the number of entries lost from that viewer's live queue. The CLI also consults the retained history after connecting/reconnecting and de-duplicates entries by request id.
|
||||
|
||||
## User-Agent, country and Traffic analytics
|
||||
|
||||
Structured access entries expose `user_agent` and `country` as selectable source fields in addition to the standard entry. User-Agent capture is enabled by default and is bounded before it enters retained logging/analytics state. Country capture is disabled by default because it requires a GeoIP lookup. With country capture disabled, GeoIP is kept off the normal request path unless a configured country access rule or country rate-limit already requires the lookup; in those policy cases the lookup still occurs for enforcement, but the country is not retained in access logs unless capture is enabled.
|
||||
|
||||
The authenticated **Traffic** workspace aggregates completed requests per vhost without database writes. The request path uses a bounded non-blocking queue, and high-cardinality dimensions use fixed-capacity approximate top tables. The page shows aggregate requests, 5xx errors, request/response bytes and mean duration plus top countries, User-Agents, effective client IPs, paths, routes, methods, status classes and cache outcomes. Donut charts summarize countries, User-Agents, client IPs, methods, status classes and cache outcomes while the bounded tables retain exact displayed labels/counts from the approximate TOP state. The lists are process-lifetime diagnostics, are not persisted across restart, and may drop analytics samples under overload rather than applying backpressure to proxy traffic. Country rankings are populated only while country capture is enabled. Client-IP rankings use the same verified effective client identity used by ACL/logging after trusted-proxy processing.
|
||||
|
||||
## Interactive commands
|
||||
|
||||
No regex language is required. Type commands while the stream is running:
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
# Vhost management (updated for 0.4.0)
|
||||
# Vhost management - historical 0.4-era implementation record
|
||||
|
||||
> Historical context. This document is retained for implementation traceability and must not
|
||||
> be used as the current vhost/operator guide. Use [VHOSTS.md](VHOSTS.md),
|
||||
> [CUSTOM_LOCATIONS.md](CUSTOM_LOCATIONS.md), [VHOST_ACCESS.md](VHOST_ACCESS.md) and
|
||||
> [WEB_SERVER.md](WEB_SERVER.md) for current behavior.
|
||||
|
||||
This guide describes implemented source behavior. Read TEST_REPORT.md before
|
||||
acceptance: the packaging environment did not compile or run the Rust backend.
|
||||
|
||||
+14
-1
@@ -1,4 +1,17 @@
|
||||
# 0.7.3 -> 0.8.0 deployment changes
|
||||
# Deployment and configuration migration history
|
||||
|
||||
## 0.24.10 -> 0.25.0
|
||||
|
||||
There is no SQLite schema migration for the first Web Server stage. `web_services` is an
|
||||
additive collection inside the existing revisioned configuration document, and missing
|
||||
vhost/location `source` fields continue to deserialize as Reverse Proxy. Existing 0.24.10
|
||||
configurations therefore remain valid without manual conversion.
|
||||
|
||||
A Web Service must be created separately before a vhost/location can reference it. Document
|
||||
root, index files and directory-listing settings belong to that reusable Web Service and are
|
||||
not migrated into individual vhosts.
|
||||
|
||||
## Historical deployment changes
|
||||
|
||||
## 0.15.1 -> 0.16.0
|
||||
|
||||
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
# PHP-FPM / FastCGI for the Web Server
|
||||
|
||||
RustProxy 0.25 can execute configured PHP extensions through a long-running PHP-FPM pool while preserving the reusable Web Service architecture.
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
Request
|
||||
-> existing listener / vhost / location / ACL / auth
|
||||
-> Web Server -> Web Service
|
||||
|- static file
|
||||
`- configured PHP extension -> FastCGI -> PHP-FPM
|
||||
-> existing error/header/logging/metrics/transport pipeline
|
||||
```
|
||||
|
||||
Vhosts and locations still reference only a Web Service. PHP settings remain part of that reusable service.
|
||||
|
||||
## Runtime model
|
||||
|
||||
RustProxy implements the FastCGI protocol directly. It does not spawn `php`, `php-cgi` or shell processes for individual requests.
|
||||
|
||||
Supported endpoint syntax:
|
||||
|
||||
```text
|
||||
unix:/run/php/php-fpm.sock
|
||||
tcp:127.0.0.1:9000
|
||||
tcp:[::1]:9000
|
||||
```
|
||||
|
||||
Use the `unix:` prefix for a Unix-domain socket. Use `tcp:` followed by a literal loopback IP address and port for TCP. Hostnames and non-loopback addresses are rejected. Unix sockets are preferred for a local PHP-FPM installation; exposing FastCGI directly to an untrusted network is not supported by this configuration.
|
||||
|
||||
## Web Service configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"index": ["index.html", "index.php"],
|
||||
"try_files": ["$uri", "$uri/", "/index.php?$query_string"],
|
||||
"php": {
|
||||
"enabled": true,
|
||||
"extensions": ["php"],
|
||||
"endpoint": "unix:/run/php/php-fpm.sock",
|
||||
"connect_timeout_ms": 1000,
|
||||
"request_timeout_ms": 30000,
|
||||
"max_concurrent_requests": 64,
|
||||
"pass_authorization": true,
|
||||
"max_request_body_bytes": 0,
|
||||
"max_response_header_bytes": 65536,
|
||||
"stderr_log_bytes": 4096,
|
||||
"custom_params": {
|
||||
"APP_ENV": "production"
|
||||
},
|
||||
"php_values": {
|
||||
"memory_limit": "256M",
|
||||
"upload_max_filesize": "64M",
|
||||
"post_max_size": "64M"
|
||||
}
|
||||
},
|
||||
"symlink_policy": "deny"
|
||||
}
|
||||
```
|
||||
|
||||
The normal ordered `index` list handles `index.php`; there is no separate PHP-index option.
|
||||
|
||||
### Additional PHP/FastCGI options
|
||||
|
||||
- `pass_authorization`: forwards the inbound `Authorization` header as `HTTP_AUTHORIZATION`. Disable it when the application does not need that header.
|
||||
- `max_request_body_bytes`: streaming request-body limit enforced before/during FastCGI forwarding. `0` means no additional RustProxy-side limit. A request exceeding the configured value receives `413 Payload Too Large`.
|
||||
- `max_response_header_bytes`: maximum bytes accepted before the CGI response-header terminator. The allowed range is 4096..1048576 bytes.
|
||||
- `stderr_log_bytes`: maximum PHP-FPM stderr bytes retained for one diagnostic request entry. `0` disables stderr capture; maximum 65536.
|
||||
- `custom_params`: trusted static FastCGI parameters supplied by the operator.
|
||||
- `php_values`: php.ini-style overrides encoded into one validated FastCGI `PHP_VALUE` parameter.
|
||||
|
||||
### Custom FastCGI parameter syntax
|
||||
|
||||
In the administration UI use one entry per line:
|
||||
|
||||
```text
|
||||
APP_ENV = production
|
||||
APP_DEBUG = 0
|
||||
TENANT = main
|
||||
```
|
||||
|
||||
Names are normalized to uppercase and are limited to letters, digits and `_` (the first character must be a letter). Values are static: there is no request-variable interpolation in this field. RustProxy rejects core CGI parameters, `HTTP_*`, `PHP_VALUE` and `PHP_ADMIN_VALUE`, so custom values cannot replace `SCRIPT_FILENAME`, routing data, HTTP-derived fields or PHP control parameters. Up to 64 custom FastCGI parameters and 64 PHP INI overrides are accepted, with at most 128 KiB of combined custom parameter/value data.
|
||||
|
||||
### PHP INI (`PHP_VALUE`) syntax
|
||||
|
||||
Use one `directive = value` entry per line:
|
||||
|
||||
```text
|
||||
memory_limit = 256M
|
||||
upload_max_filesize = 64M
|
||||
post_max_size = 64M
|
||||
max_execution_time = 30
|
||||
```
|
||||
|
||||
RustProxy validates the lines and combines them with newline separators into the FastCGI `PHP_VALUE` parameter. PHP-FPM/PHP still decides whether a directive is changeable at this scope. `PHP_ADMIN_VALUE` is intentionally not exposed. Control characters/newlines inside names or values are rejected.
|
||||
|
||||
These custom parameters are stored as normal Web Service configuration. Do not put secrets there unless normal configuration storage is an acceptable location for them.
|
||||
|
||||
## `try_files` front controller
|
||||
|
||||
A typical application can use:
|
||||
|
||||
```text
|
||||
$uri
|
||||
$uri/
|
||||
/index.php?$query_string
|
||||
```
|
||||
|
||||
Existing static files/directories are used first. The final path becomes the fallback and can therefore reach `index.php`. This resolution remains inside the already-selected Web Service and does not introduce a second vhost router.
|
||||
|
||||
## Bounded execution
|
||||
|
||||
Each compiled Web Service owns a bounded PHP concurrency semaphore. `max_concurrent_requests` limits simultaneous FastCGI requests. RustProxy does not create an unbounded wait queue: if no execution slot is immediately available it returns `503 Service Unavailable` with `Retry-After`.
|
||||
|
||||
Connection establishment and complete FastCGI request execution have independent configured time limits. A connect failure produces a gateway error; a request timeout produces a gateway timeout. The outer normal RustProxy error-page processing remains able to replace these responses.
|
||||
|
||||
Request bodies are split into bounded FastCGI records rather than collected into one large buffer. When `max_request_body_bytes` is non-zero, the limit is checked both from `Content-Length` when available and while streaming chunked/unknown-length bodies. PHP-FPM stdout is parsed and delivered through a bounded response channel so application output can stream to the client.
|
||||
|
||||
## Secure script selection
|
||||
|
||||
Only configured extensions are executable. Before PHP is selected, RustProxy resolves the request/`try_files`/index path using the Web Server filesystem confinement rules and verifies that it is a regular file below the document root.
|
||||
|
||||
When PHP handling was selected:
|
||||
|
||||
- PHP source is never returned as a fallback;
|
||||
- an unavailable PHP-FPM endpoint produces 502/504 behavior rather than source disclosure;
|
||||
- encoded traversal/separators and `..` remain rejected;
|
||||
- the current implementation requires `symlink_policy=deny`.
|
||||
|
||||
The last restriction is deliberate: PHP-FPM opens `SCRIPT_FILENAME` independently, so RustProxy does not claim an `inside_root` symlink guarantee that the external process cannot enforce atomically.
|
||||
|
||||
## FastCGI parameters
|
||||
|
||||
RustProxy supplies a controlled CGI/FastCGI parameter set including:
|
||||
|
||||
- `REQUEST_METHOD`
|
||||
- `SCRIPT_FILENAME`
|
||||
- `SCRIPT_NAME`
|
||||
- `QUERY_STRING`
|
||||
- `REQUEST_URI`
|
||||
- `DOCUMENT_ROOT`
|
||||
- `SERVER_PROTOCOL`
|
||||
- `SERVER_NAME`
|
||||
- `SERVER_PORT`
|
||||
- `REMOTE_ADDR`
|
||||
- `REMOTE_PORT` when available
|
||||
- `HTTPS`
|
||||
- `GATEWAY_INTERFACE`
|
||||
- `SERVER_SOFTWARE`
|
||||
- `REDIRECT_STATUS`
|
||||
- `CONTENT_TYPE`
|
||||
- `CONTENT_LENGTH`
|
||||
- selected request headers as `HTTP_*`
|
||||
|
||||
Request headers cannot become FastCGI `PHP_VALUE` or `PHP_ADMIN_VALUE` parameters. Operator-defined `custom_params` are allowed only through the validated Web Service configuration and cannot override core CGI/HTTP-derived fields. Operator-defined `php_values` are the only path that creates `PHP_VALUE`; `PHP_ADMIN_VALUE` is never generated.
|
||||
|
||||
An inbound `Proxy` header is **never** translated into FastCGI `HTTP_PROXY` (httpoxy mitigation), regardless of the optional Web Service hardening switch. The **Block common attack probes** option additionally blocks high-confidence sensitive/probe paths before PHP-FPM dispatch. FastCGI output cannot control downstream `Content-Length`, transfer framing, connection headers or `Proxy-*` transport headers; RustProxy owns downstream response framing.
|
||||
|
||||
`PATH_INFO` script/path splitting is not implemented in the current 0.25 development stage; applications should route explicitly to a real script, normally through `try_files`.
|
||||
|
||||
## Response parsing
|
||||
|
||||
The FastCGI stdout parser understands standard CGI response headers, including `Status`. Hop-by-hop transport headers are stripped before returning the response through RustProxy.
|
||||
|
||||
For `HEAD`, PHP-FPM can still execute normally but the client response body is empty. GET/POST/PUT and other methods can reach a PHP script once routing resolves to a configured executable extension.
|
||||
|
||||
PHP stderr is bounded by `stderr_log_bytes` and written to the RustProxy diagnostic log; it is not sent to the client as page content. CGI response headers are separately bounded by `max_response_header_bytes`.
|
||||
|
||||
## Caching
|
||||
|
||||
PHP output does not use static file validators or the static-file OS representation path. Application response headers and the normal vhost/location response-header pipeline control client/intermediary caching.
|
||||
|
||||
The Web Service static `cache_rules` apply to local static file responses, not to PHP stdout. RustProxy does not silently place PHP responses into a new Web Server object cache.
|
||||
|
||||
## PHP installation
|
||||
|
||||
RustProxy does not bundle PHP. Install and maintain PHP-FPM using the operating system/package ecosystem and enable only the extensions required by the application.
|
||||
|
||||
Operational requirements:
|
||||
|
||||
- a running PHP-FPM 8.x service supported by the operator's platform;
|
||||
- a dedicated Unix socket or loopback TCP listener reachable by the RustProxy service account;
|
||||
- document-root permissions usable by both RustProxy and the PHP-FPM worker identity as intended;
|
||||
- correct socket owner/group/mode when using Unix sockets;
|
||||
- PHP-FPM limits such as `pm.max_children`, application execution timeout and upload/body limits sized consistently with the RustProxy concurrency limit.
|
||||
|
||||
Extensions such as PDO drivers, mbstring, intl, gd, curl or opcache are application dependencies, not RustProxy dependencies.
|
||||
|
||||
## Example PHP-FPM pool concept
|
||||
|
||||
The exact paths/users depend on the operating system. For production, use a **separate PHP-FPM worker identity per site/application**. Never run PHP-FPM as `root` or as the `rustproxy` service account. A compromised CMS/plugin then must not inherit access to RustProxy's SQLite database, Secret Store, certificate private keys or backups.
|
||||
|
||||
A local pool can expose a socket such as:
|
||||
|
||||
```ini
|
||||
user = site_example
|
||||
group = site_example
|
||||
listen = /run/php/rustproxy-example.sock
|
||||
listen.owner = www-data
|
||||
listen.group = rustproxy
|
||||
listen.mode = 0660
|
||||
```
|
||||
|
||||
The exact socket owner may differ by distribution; the important properties are that the PHP worker user is **not** `rustproxy`, and only RustProxy plus the pool manager can reach the socket. Configure the Web Service endpoint as:
|
||||
|
||||
```text
|
||||
unix:/run/php/rustproxy-example.sock
|
||||
```
|
||||
|
||||
Keep `/var/lib/rustproxy` mode/private ownership inaccessible to every PHP pool. Prefer separate writable upload/data directories from executable PHP source, and prevent the application from creating executable PHP files in upload areas. A CMS-level arbitrary file upload or vulnerable plugin can otherwise become PHP code execution even when the reverse proxy itself is correct.
|
||||
|
||||
Do not expose a PHP-FPM TCP listener to the public network.
|
||||
|
||||
## Verification targets
|
||||
|
||||
The implementation includes source/unit coverage for:
|
||||
|
||||
- PHP front-controller resolution through `try_files`;
|
||||
- request body delivery to a FastCGI fixture;
|
||||
- FastCGI response parsing;
|
||||
- connection failure returning a gateway error without PHP source disclosure;
|
||||
- bounded endpoint/time/concurrency configuration validation.
|
||||
|
||||
Release-host acceptance should additionally exercise a real PHP-FPM runtime over Unix socket and loopback TCP and verify ACL/auth/custom errors/headers plus H1/H2/H3 client transports.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Dedicated Prometheus endpoint (0.22.3)
|
||||
# Dedicated Prometheus endpoint
|
||||
|
||||
RustProxy exposes Prometheus text exposition 0.0.4 on a dedicated read-only
|
||||
listener. It is independent from administrator browser sessions and does not
|
||||
|
||||
+62
-42
@@ -1,51 +1,71 @@
|
||||
# Documentation index
|
||||
# RustProxy documentation index
|
||||
|
||||
This index separates current operational documentation from historical/version-labelled material. A version in an older document title describes the milestone that introduced or last audited that topic; it is not the current RustProxy release identity.
|
||||
This is the canonical index for the current project documentation. The authenticated administration documentation page at `/docs` embeds these Markdown files in its **Reader** tab and keeps OpenAPI/Swagger in a separate **API** tab.
|
||||
|
||||
## Current operational entry points
|
||||
## Project and release
|
||||
|
||||
- [INSTALL.md](INSTALL.md) - installation and managed updates.
|
||||
- [SETTINGS.md](SETTINGS.md) - listeners, response defaults and administration settings.
|
||||
- [API.md](API.md) and [API_ACCESS.md](API_ACCESS.md) - administration API and access controls.
|
||||
- [VHOSTS.md](VHOSTS.md), [VHOST_ACCESS.md](VHOST_ACCESS.md), [CUSTOM_LOCATIONS.md](CUSTOM_LOCATIONS.md) - HTTP routing and access behavior.
|
||||
- [DOCKER_DISCOVERY.md](DOCKER_DISCOVERY.md) - Docker discovery agent and generated vhosts.
|
||||
- [CACHE.md](CACHE.md) and [CACHE_DIAGNOSTICS.md](CACHE_DIAGNOSTICS.md) - cache semantics and diagnostics.
|
||||
- [PROMETHEUS.md](PROMETHEUS.md), [HTTP3.md](HTTP3.md), [STREAMS.md](STREAMS.md) - monitoring and transport features.
|
||||
- [SECURITY.md](SECURITY.md) - current security model and limitations.
|
||||
- [SECRET_STORE_BACKUP.md](SECRET_STORE_BACKUP.md) - encrypted credentials and password-protected full backup/restore.
|
||||
- [ERROR_LOGGING.md](ERROR_LOGGING.md) - optional asynchronous ERROR-only file sink and external log rotation.
|
||||
- [TEST_REPORT.md](TEST_REPORT.md) - release verification status and explicit environment limitations.
|
||||
- [0.24.8 dashboard cache-memory audit](V0.24.8_AUDIT.md) - overview HOT/transient/COLD occupancy histories and compact RSS accounting help.
|
||||
- [0.24.7 transform resource-control audit](V0.24.7_AUDIT.md) - configurable transformation memory/concurrency budgets and resource presets.
|
||||
- [0.24.6 memory/preset audit](V0.24.6_AUDIT.md) - persisted cache presets, transformation memory bounds and background-worker memory/task review.
|
||||
- [0.24.5 specification audit](V0.24.5_AUDIT.md) - HTTP/3 empty-request-body normalization for HTTP/1.1 upstreams and DELETE regression matrix.
|
||||
- [0.24.4 specification audit](V0.24.4_AUDIT.md) - process-local Linux THP mitigation and memory-retention verification matrix.
|
||||
- [0.24.3 specification audit](V0.24.3_AUDIT.md) - memory-retention, H3 settings placement and dynamic diagnostics source-vs-spec matrix.
|
||||
- [0.24.1 specification audit](V0.24.1_AUDIT.md) - current shared-statistics/runtime-metadata/Settings navigation source-vs-spec matrix.
|
||||
- [0.24.0 specification audit](V0.24.0_AUDIT.md) - historical H2 graceful-shutdown/system-statistics source-vs-spec matrix.
|
||||
- [0.23.3 specification audit](V0.23.3_AUDIT.md) - historical legacy WebSocket compatibility source-vs-spec matrix.
|
||||
- [0.23.2 specification audit](V0.23.2_AUDIT.md) - adjustable live-chart history and HTTPS local-CLI/live-log source-vs-spec matrix.
|
||||
- [0.23.1 specification audit](V0.23.1_AUDIT.md) - historical initial Cache/Transform live-chart source-vs-spec matrix.
|
||||
- [0.23.0 specification audit](V0.23.0_AUDIT.md) - historical certificate API/live-logs/cache-UX source-vs-spec matrix.
|
||||
- [Interactive live logs](LIVE_LOGS.md) - `rust-proxy --livelogs`, structured filters, detail view, bounded stream/gap semantics.
|
||||
- [0.22.3 specification audit](V0.22.3_AUDIT.md) - historical h2c Upgrade/external-certificate audit.
|
||||
- [0.22.2 specification audit](V0.22.2_AUDIT.md) - historical retry/H2/concurrency source-vs-spec matrix.
|
||||
- [0.22.1 specification audit](V0.22.1_AUDIT.md) - historical UI/RFC8441/h2c/tunnel source-vs-spec matrix.
|
||||
- [0.21.0 specification audit](V0.21.0_AUDIT.md) - historical 0.21 source-vs-spec matrix.
|
||||
- [Project README](../README.md) - product overview, installation entry points and current release notes.
|
||||
- [ROADMAP](../ROADMAP.md) - planned and completed release scope.
|
||||
- [CHANGELOG](../CHANGELOG.md) - user/operator-visible changes by release.
|
||||
- [TODO](TODO.md) - open work only; completed work is not retained as TODO.
|
||||
- [0.25.0 specification audit](V0.25.0_AUDIT.md) - point-by-point implementation status and remaining release-host gates.
|
||||
- [0.25.0 pre-production security audit](V0.25.0_SECURITY_PREPROD_AUDIT.md) - threat-oriented source/configuration review, fixes made in-session and mandatory runtime security gates.
|
||||
- [TEST_REPORT](TEST_REPORT.md) - verification commands, results and environment limitations.
|
||||
|
||||
## Functional documentation
|
||||
|
||||
- [WEB_SERVER](WEB_SERVER.md) - reusable Web Services, static-file behavior, ranges/validators and document-root security.
|
||||
- [PHP_FPM](PHP_FPM.md) - implemented FastCGI/PHP-FPM integration, security model and runtime requirements.
|
||||
- [VHOSTS](VHOSTS.md) - vhosts and backend/source behavior.
|
||||
- [CUSTOM_LOCATIONS](CUSTOM_LOCATIONS.md) - location matching, rewrites and local responses.
|
||||
- [VHOST_ACCESS](VHOST_ACCESS.md) - access rules applied to vhosts and locations.
|
||||
- [CACHE](CACHE.md) - cache behavior and policy.
|
||||
- [TRANSFORM](TRANSFORM.md) - response transformation.
|
||||
- [STREAMS](STREAMS.md) - stream proxying.
|
||||
- [REDIRECTS](REDIRECTS.md) - redirect hosts and rules.
|
||||
- [NOT_FOUND_HOSTS](NOT_FOUND_HOSTS.md) - local 404 host handling.
|
||||
- [DOCKER_DISCOVERY](DOCKER_DISCOVERY.md) - Docker discovery and generated vhosts.
|
||||
- [ACME_PROVIDERS](ACME_PROVIDERS.md) and [RENEWAL](RENEWAL.md) - certificate automation.
|
||||
- [LIVE_LOGS](LIVE_LOGS.md) and [ERROR_LOGGING](ERROR_LOGGING.md) - request/error observability, User-Agent/optional-country capture and bounded per-vhost Traffic analytics.
|
||||
|
||||
## Administration and operations
|
||||
|
||||
- [INSTALL](INSTALL.md) - installation and managed updates.
|
||||
- [SETTINGS](SETTINGS.md) - listeners, administration and response defaults.
|
||||
- [API](API.md) - administration API overview.
|
||||
- [API_ACCESS](API_ACCESS.md) - API authentication, CSRF and `/docs` security model.
|
||||
- [SECRET_STORE_BACKUP](SECRET_STORE_BACKUP.md) - encrypted secret storage and backup/restore.
|
||||
- [PROMETHEUS](PROMETHEUS.md) - monitoring endpoint and metrics.
|
||||
- [CONTAINER](CONTAINER.md) - container deployment.
|
||||
- [NPM_MIGRATION](NPM_MIGRATION.md) and [MIGRATION](MIGRATION.md) - migration tooling and historical migration notes.
|
||||
|
||||
## Development and testing
|
||||
|
||||
- [MOCK_SERVER](MOCK_SERVER.md) - local Python mock origin used by development/integration checks.
|
||||
- [MOCK_AUTH](MOCK_AUTH.md) - local fake Tinyauth peer for development only.
|
||||
|
||||
## Technical documentation
|
||||
|
||||
- [ARCHITECTURE](ARCHITECTURE.md) - process and request architecture.
|
||||
- [SECURITY](SECURITY.md) - current security model and limitations.
|
||||
- [HTTP3](HTTP3.md) - HTTP/3 transport behavior.
|
||||
- [TRANSPORT](TRANSPORT.md) - transport background/contract notes.
|
||||
- [CACHE_DIAGNOSTICS](CACHE_DIAGNOSTICS.md) - cache diagnostics and interpretation.
|
||||
- [REFERENCES](REFERENCES.md) - implementation references.
|
||||
|
||||
## Historical or version-labelled context
|
||||
|
||||
These files are retained because they document migrations, original feature contracts or past audits, but their version labels and conclusions must not be treated as a fresh 0.24.1 audit:
|
||||
Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone; they are not current-release documentation. The current audit is [V0.25.0_AUDIT.md](V0.25.0_AUDIT.md).
|
||||
|
||||
| File | Historical marker | Use |
|
||||
|---|---|---|
|
||||
| `INTEGRATIONS_040.md` | 0.4.0 | Original integration/forwarding milestone. |
|
||||
| `MANAGEMENT.md` | updated for 0.4.0 | Early vhost-management behavior and terminology. |
|
||||
| `SECURITY_AUDIT.md` | 0.7.1 | Historical limited administration-exposure audit; not a current security certification. |
|
||||
| `MIGRATION.md` | 0.7.3 -> 0.8.0 | Version-specific deployment migration notes. |
|
||||
| `ACME_RFC2136.md` | 0.5.0 | Original RFC2136 integration notes; current renewal behavior is also documented in `RENEWAL.md`. |
|
||||
| `TRANSPORT.md` | early transport contract | Background contract; current HTTP/3-specific behavior is in `HTTP3.md`. |
|
||||
Older context documents such as [INTEGRATIONS_040](INTEGRATIONS_040.md), [MANAGEMENT](MANAGEMENT.md), [SECURITY_AUDIT](SECURITY_AUDIT.md), [ACME_RFC2136](ACME_RFC2136.md) and older version audits remain available for traceability but should not override the current functional/technical documents above.
|
||||
|
||||
## Screenshots
|
||||
The pre-cleanup developer-level changelog is retained as [CHANGELOG_TECHNICAL_ARCHIVE](CHANGELOG_TECHNICAL_ARCHIVE.md) when low-level historical detail is needed. The root `CHANGELOG.md` remains the operator-facing release record.
|
||||
Completed roadmap history is retained separately as [ROADMAP_HISTORY](ROADMAP_HISTORY.md); the root `ROADMAP.md` contains only the active 0.25 milestone, release gate and future direction.
|
||||
|
||||
See [screenshots/README.md](screenshots/README.md). Only two explicitly labelled legacy simulated references remain; stale simulated UI captures were removed in 0.19.1.
|
||||
## Maintenance rules
|
||||
|
||||
- Put user/operator-visible release changes in `CHANGELOG.md`.
|
||||
- Put future release scope in `ROADMAP.md` and unresolved work in `docs/TODO.md`.
|
||||
- Keep detailed implementation evidence in technical documents or version audits, not in CHANGELOG.
|
||||
- When functionality changes, update the functional document, this index, Reader coverage and cross-links in the same change.
|
||||
- Remove obsolete or duplicated documents when they no longer provide historical or technical value; retain useful audits with an explicit historical label.
|
||||
@@ -0,0 +1,735 @@
|
||||
# Historical roadmap archive
|
||||
|
||||
> Archived during the RustProxy 0.25 documentation cleanup. This file preserves completed historical roadmap entries. The active roadmap is [`../ROADMAP.md`](../ROADMAP.md); unresolved work is tracked in [`TODO.md`](TODO.md).
|
||||
|
||||
# RustProxy roadmap
|
||||
|
||||
## 0.25.0
|
||||
|
||||
Current direction: 0.24.10 -> 0.25.0
|
||||
|
||||
- [x] Add independent reusable Web Service configuration with name, document root, index list and directory-listing switch.
|
||||
- [x] Add Web Service CRUD through the dashboard/API and persist it through the existing revisioned configuration store.
|
||||
- [x] Add `Reverse Proxy` / `Web Server` source selection to vhost fallback and custom locations without storing Web Server filesystem settings in vhosts.
|
||||
- [x] Allow one Web Service to be referenced by multiple vhosts and one vhost to mix Web Server and Reverse Proxy locations.
|
||||
- [x] Add `GET`, `HEAD`, MIME, `Content-Length`, streaming, index lookup, directory slash redirect and optional directory listing.
|
||||
- [x] Add metadata-based `ETag`/`Last-Modified`, conditional `304`, single `Range`/`If-Range`, `206` and `416`.
|
||||
- [x] Enforce decoded-path validation and document-root confinement; Unix traversal uses `openat` + `O_NOFOLLOW` and does not serve symlinks.
|
||||
- [x] Keep Web Server inside the existing routing, ACL/auth, custom-header/error-page/security and H1/H2/H3 response pipeline; do not create separate routing/error/cache subsystems.
|
||||
- [x] Add unit/source-contract coverage, OpenAPI/UI language coverage and Web Server documentation.
|
||||
- [x] Clean 0.25 README/Docs/CHANGELOG release material so current user-facing changes are separated from historical audits.
|
||||
- [x] Add an authenticated `/docs` Markdown Reader with a separate API/OpenAPI tab, canonical docs index, 0.25 specification audit and open-work TODO.
|
||||
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` plus live H1/H2/H3/static-file acceptance on the release host.
|
||||
|
||||
## 0.24.10
|
||||
|
||||
Current direction: 0.24.9 -> 0.24.10
|
||||
|
||||
- [x] Make Error File a first-class revisioned configuration section and persist enabled/path/format across database reopen.
|
||||
- [x] Remove the redundant Error File help sentence while retaining JSON/RAW controls and live apply.
|
||||
- [x] Keep response-time history permanently expanded and add an accessible information popover matching Process.
|
||||
- [x] Extend UI/API/source regressions and update release identity to 0.24.10.
|
||||
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and browser acceptance on the release host.
|
||||
|
||||
## 0.24.9
|
||||
|
||||
Current direction: 0.24.8 -> 0.24.9
|
||||
|
||||
- [x] Add the encrypted Secret Store and migrate ACME Cloudflare/OVH/RFC2136 credentials away from persistent plaintext files.
|
||||
- [x] Add password-encrypted full backup/restore with manifest validation, integrity checks, staging and rollback-safe activation.
|
||||
- [x] Add the optional bounded asynchronous ERROR file sink with JSON/RAW formats, shared secret redaction and external logrotate integration.
|
||||
- [x] Extend offline source/release contracts and update release identity to 0.24.9.
|
||||
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and end-to-end backup/restore/error-log acceptance on the release host.
|
||||
|
||||
## 0.24.8
|
||||
|
||||
Current direction: 0.24.7 -> 0.24.8
|
||||
|
||||
- [x] Expand Cache RAM overview history with HOT usage/limit and transient total/fill/COLD queue/COLD I/O series.
|
||||
- [x] Add COLD storage occupancy history without mixing disk bytes into process RAM.
|
||||
- [x] Move the RSS/cache accounting caveat behind an accessible information control.
|
||||
- [x] Extend offline UI/release contracts and update release identity to 0.24.8.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test` and browser/live-cache acceptance on the release host.
|
||||
|
||||
## 0.24.7
|
||||
|
||||
Current direction: 0.24.6 -> 0.24.7
|
||||
|
||||
- [x] Make the transform temporary-memory budget configurable and persisted with the normal SQLite-backed transform settings.
|
||||
- [x] Add a process-wide maximum concurrent transformation limit with fail-open pressure behavior.
|
||||
- [x] Add persisted RAM saver / Recommended / Performance / Uber performance resource presets while keeping transform types/extensions independent.
|
||||
- [x] Add UI budget safety warnings and manual-edit -> Custom preset behavior.
|
||||
- [x] Expose live transform RAM/concurrency, process/cache RAM accounting and COLD disk occupancy in the dashboard.
|
||||
- [x] Clean externally reported cache/CSS compiler warnings without lint suppression.
|
||||
- [x] Rotate cache compatibility identity for global transform representation/eligibility changes but not resource-only capacity metadata.
|
||||
- [x] Extend OpenAPI, SQLite persistence, memory-contract and release/source regressions and update release identity to 0.24.7.
|
||||
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and sustained RSS/heap acceptance for every resource preset on the release host.
|
||||
|
||||
## 0.24.6
|
||||
|
||||
Current direction: 0.24.5 -> 0.24.6
|
||||
|
||||
- [x] Persist selected HOT/COLD cache preset intent in the SQLite-backed configuration and restore it in Settings.
|
||||
- [x] Add a Recommended COLD policy preset without overriding disk capacity/path choices.
|
||||
- [x] Bound transform aggregation/decompression/concurrency memory and remove avoidable JSON/HTML/CSS allocation churn.
|
||||
- [x] Bound stale revalidation, proactive refresh scheduling, COLD cleanup selection/concurrency and delete fallback tasks.
|
||||
- [x] Audit the remaining long-lived/background workers for queue/task cardinality and cancellation ownership.
|
||||
- [x] Add Rust-independent memory contract regression checks and update release identity to 0.24.6.
|
||||
- [ ] Run compiler-enabled `./dev.sh fmt`, `./dev.sh check`, `./dev.sh test` and sustained RSS/heap acceptance on the release host.
|
||||
|
||||
## 0.24.5
|
||||
|
||||
Current direction: 0.24.4 -> 0.24.5
|
||||
|
||||
- [x] Resolve unknown-length, actually empty HTTP/3 bodies before HTTP/1.1 upstream framing.
|
||||
- [x] Preserve streaming for non-empty H3 bodies and declared `Content-Length` requests.
|
||||
- [x] Add source-level regression coverage for DELETE and other body-capable methods.
|
||||
- [x] Bound HOT by allocation-aware admission, enforce `max_object_bytes` during fill, and add a separately bounded transient/COLD-queue memory model.
|
||||
- [x] Preserve HOT -> COLD ownership semantics while charging demoted payloads until persistence drops them; expose logical/allocated/transient telemetry.
|
||||
- [x] Make global cache disable authoritative over vhost overrides and remove the artificial 1 GiB HOT/object ceiling.
|
||||
- [x] Add host/cgroup-aware conservative/recommended/performance cache presets and non-blocking memory/headroom warnings in Settings.
|
||||
- [x] Update source/package/UI/OpenAPI identity and offline release checks to 0.24.5.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, the H1/H2/H3 method matrix, and cache RSS/HOT/COLD stress acceptance on the release host.
|
||||
|
||||
## 0.24.4
|
||||
|
||||
Current direction: 0.24.3 -> 0.24.4
|
||||
|
||||
- [x] Make the Linux THP mitigation process-local with `PR_SET_THP_DISABLE` before Tokio worker creation.
|
||||
- [x] Preserve the existing glibc arena limit and allocator-trim behavior.
|
||||
- [x] Add source/release regression coverage for THP opt-out ordering and release identity.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and a sustained production RSS comparison with host THP returned to its normal policy.
|
||||
|
||||
## 0.24.3
|
||||
|
||||
Current direction: 0.24.2 -> 0.24.3
|
||||
|
||||
- [x] Reduce Linux/glibc arena retention by adding `MALLOC_ARENA_MAX=2` to managed systemd units.
|
||||
- [x] Remove redundant identity-body and JavaScript/CSS transformation allocations; release successful-transform temporaries earlier and trim large glibc transform churn at a bounded cadence.
|
||||
- [x] Move HTTP/3 enablement to listener editing while keeping HTTP/3 tuning under HTTP connections.
|
||||
- [x] Rename Proxy Process to Process and hide unsupported platform diagnostics dynamically.
|
||||
- [x] Remove the stale unreferenced per-BSD parser source from the release archive.
|
||||
- [x] Update source/package/UI/OpenAPI identity and Rust-independent release gates to 0.24.3.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and sustained cache/transform RSS acceptance on the release host.
|
||||
|
||||
## 0.24.2
|
||||
|
||||
Current direction: 0.24.1 -> 0.24.2
|
||||
|
||||
- [x] Bump package/source/UI/OpenAPI release identity to 0.24.2 without functional changes.
|
||||
|
||||
## 0.24.1
|
||||
|
||||
Current direction: 0.24.0 -> 0.24.1
|
||||
|
||||
- [x] Replace the duplicated BSD statistics implementation with shared cross-platform library APIs.
|
||||
- [x] Preserve Linux-specific `/proc`/cgroup diagnostics as additive compatibility fields.
|
||||
- [x] Populate additional portable system/process metrics exposed by the selected libraries where available.
|
||||
- [x] Expose low-risk runtime metadata through the authenticated status API, including the resolved data/database path.
|
||||
- [x] Make CLI installed-data discovery use Linux and BSD/OPNsense conventions without hardcoding the path in the browser.
|
||||
- [x] Move Logging into Settings and retain legacy `/logging` navigation compatibility.
|
||||
- [x] Fix the release-host compiler error in portable uptime sampling and remove the stale H2 import warning.
|
||||
- [x] Remove artificial hostname-count ceilings from certificate bindings/issuance and hostname-list configuration while retaining syntax, payload and resource-safety bounds.
|
||||
- [x] Update source/package/UI/OpenAPI identity and source-side regression contracts to 0.24.1.
|
||||
- [ ] Generate and commit a resolver-produced `Cargo.lock`, then run compiler-enabled `cargo fmt --all`, `cargo check --locked --all-targets` and `cargo test --locked --all-targets` on the release host.
|
||||
- [ ] Run native FreeBSD/OpenBSD/NetBSD diagnostics acceptance and final H2/H3/WebSocket/proxy-statistics regression.
|
||||
|
||||
See [the 0.24.1 specification audit](V0.24.1_AUDIT.md).
|
||||
|
||||
## 0.24.0
|
||||
|
||||
Current direction: 0.23.3 -> 0.24.0
|
||||
|
||||
- [x] Graceful H2 idle retirement with activity/stream recheck, GOAWAY and bounded drain.
|
||||
- [x] Independent H2 maximum connection lifetime and drain timeout settings.
|
||||
- [x] Settings API/UI/OpenAPI contracts for all three H2 lifecycle limits.
|
||||
- [x] Extract system statistics into platform backends without changing Linux metric semantics.
|
||||
- [x] Add FreeBSD/OpenBSD/NetBSD native best-effort sampling and explicit unsupported/null metrics.
|
||||
- [x] Surface platform in Proxy Process and Prometheus metadata.
|
||||
- [x] Update source/package/UI identity and source-side regression contracts to 0.24.0.
|
||||
- [ ] Run compiler-enabled `cargo fmt --all`, `cargo check --locked --all-targets` and `cargo test --locked --all-targets` on the release host.
|
||||
|
||||
See [the 0.24.0 specification audit](V0.24.0_AUDIT.md).
|
||||
|
||||
## 0.23.3
|
||||
|
||||
Current direction: 0.23.2 -> 0.23.3
|
||||
|
||||
- [x] Add opt-in per-vhost legacy WebSocket compatibility without changing ordinary HTTP behavior.
|
||||
- [x] Force legacy-mode upstream WebSocket handshakes to HTTP/1.1 and force legacy WebSocket `Host` to the configured backend authority and align `Origin` with it.
|
||||
- [x] Tolerate old `101` response framing while keeping the WebSocket accept proof and subprotocol validation strict.
|
||||
- [x] Add dashboard/OpenAPI/language-pack controls and source regressions.
|
||||
- [x] Update package/source identity and Rust-independent release gates to 0.23.3.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live iLO4/legacy WebSocket acceptance on the release host.
|
||||
|
||||
See [the 0.23.3 specification audit](V0.23.3_AUDIT.md).
|
||||
|
||||
## 0.23.2
|
||||
|
||||
Current direction: 0.23.1 -> 0.23.2
|
||||
|
||||
- [x] Let Cache and Transformation live charts retain 60, 120, 300 or 600 samples without changing the 3-second polling cadence.
|
||||
- [x] Persist each chart history-window choice locally in the browser and keep history memory bounded.
|
||||
- [x] Fix local CLI administration transport detection so HTTPS administration no longer traps `--livelogs` in a 308 reconnect loop.
|
||||
- [x] Pin local CLI HTTPS to certificates from the private RustProxy certificate directory and reuse the transport for config/TLS CLI calls.
|
||||
- [x] Update package/source identity and Rust-independent release gates to 0.23.2.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live HTTPS `--livelogs` acceptance on the release host.
|
||||
|
||||
See [the 0.23.2 specification audit](V0.23.2_AUDIT.md).
|
||||
|
||||
## 0.23.1
|
||||
|
||||
Current direction: 0.23.0 -> 0.23.1
|
||||
|
||||
- [x] Add default-collapsed, full-width live activity charts to the Cache and Transform workspaces.
|
||||
- [x] Plot selected-scope Cache HIT/MISS/BYPASS rates from runtime counters without adding proxy-path work.
|
||||
- [x] Plot selected-scope Transform applied/cache-HIT/skipped/error rates from the existing runtime metrics endpoint.
|
||||
- [x] Reuse the dashboard SVG/chart styling, live 3-second refresh and language-pack model.
|
||||
- [x] Update package/source identity and Rust-independent release gates to 0.23.1.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and browser acceptance with sustained Cache/Transform traffic on the release host.
|
||||
|
||||
See [the 0.23.1 specification audit](V0.23.1_AUDIT.md).
|
||||
|
||||
## 0.23.0
|
||||
|
||||
Current direction: 0.22.3 -> 0.23.0
|
||||
|
||||
- [x] Add scoped external certificate API authentication with Key ID + Bearer Token, hash-only storage, rotation/revoke/status and last-used metadata.
|
||||
- [x] Restrict the external credential to certificate deploy/reload and require HTTPS outside loopback.
|
||||
- [x] Add Settings → Certificate API UX and preserve direct production binary commands for local deploy/reload.
|
||||
- [x] Add `rust-proxy --livelogs` with a bounded live stream, interactive structured filters, detailed request inspection and explicit lag reporting.
|
||||
- [x] Split Settings → Cache into General, Resilience, Cold cache and Static & diagnostics sub-tabs without changing the atomic cache settings document.
|
||||
- [ ] Run compiler-enabled `rust-proxy`/Cargo check, tests and release build plus live token-auth certificate rotation and sustained high-rate live-log acceptance on the release host.
|
||||
- [ ] Upstream mTLS/client certificate remains deliberately deferred.
|
||||
|
||||
See [the 0.23.0 specification audit](V0.23.0_AUDIT.md).
|
||||
|
||||
## 0.22.3
|
||||
|
||||
Current direction: 0.22.2 -> 0.22.3
|
||||
|
||||
- [x] Add HTTP/1.1 `Upgrade: h2c` on opt-in cleartext H2 listeners while preserving prior-knowledge h2c.
|
||||
- [x] Validate Upgrade/HTTP2-Settings and reject malformed or body-bearing bootstrap requests before `101`.
|
||||
- [x] Reconstruct the initiating H1 request as HTTP/2 stream 1 and retain the normal Hyper H2 path for later streams.
|
||||
- [x] Add dedicated certificate hot reload without mutating desired configuration or revision.
|
||||
- [x] Add external certificate deployment for Certbot/manual issuers with immutable generation staging and atomic multi-vhost switch by certificate id.
|
||||
- [x] Add API/CLI/panel support plus audit/OpenAPI/documentation for certificate reload/deploy.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test`, release build and live H1 -> h2c Upgrade -> H2 plus TLS/H2/H3 certificate-rotation acceptance on the release host.
|
||||
- [ ] Upstream mTLS/client certificate remains deliberately deferred.
|
||||
|
||||
See [the 0.22.3 specification audit](V0.22.3_AUDIT.md).
|
||||
|
||||
## 0.22.2
|
||||
|
||||
Current direction: 0.22.1 -> 0.22.2
|
||||
|
||||
- [x] Add replay-safe failover retry with bounded policy and observability.
|
||||
- [x] Correct explicit HTTP/2 upstream request versioning and retain h2c prior-knowledge regression coverage.
|
||||
- [x] Add per-backend maximum concurrent proxy exchanges with bounded queue timeout / 503 behavior and metrics.
|
||||
- [x] Add detailed upstream failure classification plus last failure and health ejection/recovery timestamps.
|
||||
- [x] Consolidate backend operations data in the existing dashboard table: health, active/limit, requests/errors, latency, traffic, last failure and last recovery.
|
||||
- [x] Parse and expose public-certificate issuer/SAN/validity/remaining-days/expiry status plus renewal status/last attempt/error.
|
||||
- [ ] Add a distinct maximum TCP connection/socket limit per backend; request concurrency is implemented but is intentionally not presented as a socket limit.
|
||||
- [ ] Run compiler-enabled `./dev.sh check` / `./dev.sh test` and live H1/H2/H3 plus H2 -> proxy -> H2 acceptance on the release host.
|
||||
|
||||
See [the 0.22.2 specification audit](V0.22.2_AUDIT.md).
|
||||
|
||||
## 0.22.1
|
||||
|
||||
Current direction: 0.22.0 -> 0.22.1
|
||||
|
||||
- [x] Move selective PURGE/BAN and active BAN management into dedicated Cache modals with inline operation feedback.
|
||||
- [x] Add per-vhost RFC 8441 HTTP/2 WebSocket Extended CONNECT beside RFC 9220.
|
||||
- [x] Bridge H2 RFC 8441 WebSockets to H1 upstreams and preserve Extended CONNECT to explicit H2 upstreams.
|
||||
- [x] Add opt-in cleartext HTTP/2 prior-knowledge (`h2c`) listeners.
|
||||
- [x] Add stable active-tunnel inventory, per-tunnel kill, operator reason and audit logging.
|
||||
- [x] Split WebSocket tunnel statistics by H1 / H2 RFC 8441 / H3 RFC 9220 on the main dashboard and Prometheus.
|
||||
- [x] Preserve the 0.22.0 cache feature set and `Accept-Ranges` policy.
|
||||
- [x] Update 0.22.1 source/package identity and Rust-independent release gates.
|
||||
- [ ] Run the compiler-enabled `./dev.sh check` / `./dev.sh test` gate plus live H1/H2/H3/h2c/RFC8441 acceptance on the release host.
|
||||
|
||||
See [the 0.22.1 specification audit](V0.22.1_AUDIT.md).
|
||||
|
||||
## 0.21.0
|
||||
|
||||
Current direction: 0.20.0 -> 0.21.0
|
||||
|
||||
- [x] Shard Cold Cache storage and add bounded asynchronous GC plus selective cleanup.
|
||||
- [x] Add RFC 5861 stale windows, request `max-stale`, correct request `max-age=N`, and correct revalidation-directive semantics.
|
||||
- [x] Add the extensible decode -> transform -> canonical cache -> encode stage with transformed lengths/validators, strict `no-transform`, HEAD/fill safety and canonical `Vary: Accept-Encoding` handling.
|
||||
- [x] Add global, per-vhost and Docker-discovery transformation controls and administration UI/API coverage.
|
||||
- [x] Make Passive Backend Health explicit opt-in for ordinary and Docker vhosts while preserving independent active health checks and unconditional observability.
|
||||
- [x] Keep route cache override tri-state and expose effective route/cache/transform diagnostics.
|
||||
- [x] Close 0.21.0 with the current conservative JS/CSS transformers; defer parser-backed replacements to a later development cycle.
|
||||
- [ ] Release-host gate: run Rust 1.88+ fmt/check/test/clippy/release-build and live H1/H2/H3/cache/compression/restart acceptance before deployment.
|
||||
- [x] Finish release polish: backend timing header rename, human-readable uptime, transformed Live traffic series, Docker Passive Backend Health layout fix, warning cleanup and cache module split.
|
||||
- [x] Keep package/source identity and OpenAPI at 0.21.0 and package the completed feature scope as the 0.21.0 release source.
|
||||
|
||||
See [the 0.21.0 specification audit](V0.21.0_AUDIT.md).
|
||||
|
||||
## 0.20.0
|
||||
|
||||
Current direction: 0.19.4 -> 0.20.0
|
||||
|
||||
- [x] Split Certificates into Installed / Renewal / Generate tabs.
|
||||
- [x] Move generation/import into the tabbed workspace and keep existing certificate actions compatible.
|
||||
- [x] Improve ACME/renewal status readability and display exact Certbot log locations on failures.
|
||||
- [x] Update package/source identity, OpenAPI and release checks to 0.20.0.
|
||||
|
||||
## 0.19.4
|
||||
|
||||
Current direction: 0.19.3 -> 0.19.4
|
||||
|
||||
- [x] Normalize Docker-vhost Aliases field geometry with neighboring inputs and remove the extra inherited label spacing.
|
||||
- [x] Retain `0.0 KiB/s` idle and `<0.1 KiB/s` positive low-rate backend traffic formatting with release regression coverage.
|
||||
- [x] Add Cache domain-table filtering by resolved cache-enabled state without changing aggregate cache statistics.
|
||||
- [x] Update package/source identity, OpenAPI and release checks to 0.19.4.
|
||||
|
||||
## 0.19.3
|
||||
|
||||
Current direction: 0.19.2 -> 0.19.3
|
||||
|
||||
- [x] Preserve the exact panel and Settings tab through session expiry/re-login without shell flicker.
|
||||
- [x] Canonicalize `/configuration` into persistent Settings tab routing.
|
||||
- [x] Add shared save-button busy state and field-focused validation feedback.
|
||||
- [x] Preserve certificate import file selections after failed saves.
|
||||
- [x] Add per-Settings-tab unsaved-change indicators, including Manual config.
|
||||
- [x] Add persisted dark/light administrator theme selection and consolidate theme-sensitive CSS tokens.
|
||||
- [x] Keep Live Logs column selection compact with standard checkboxes and no internal scrollbars.
|
||||
- [x] Add a fail-soft embedded-config release checker with hourly default cadence and CLI/environment overrides.
|
||||
- [x] Keep the release checker compiler-compatible by mapping boxed HTTP body collection failures explicitly into `anyhow::Error`.
|
||||
- [x] Reduce the footer to API latency/dropped logs and fix the last broad Live Logs checkbox sizing override.
|
||||
- [x] Update package/source identity, OpenAPI and release checks to 0.19.3.
|
||||
|
||||
## 0.19.2
|
||||
|
||||
Current direction: 0.19.1 -> 0.19.2
|
||||
|
||||
- [x] Restore administration-backend local-listener risk detection for startup-locked listeners and loopback aliases; make vhost discard restore the persisted draft baseline.
|
||||
- [x] Use descriptive status names for default responses.
|
||||
- [x] Add an on-demand 4096-entry live log buffer that lasts until the log window closes.
|
||||
- [x] Align inline checkboxes and reduce Docker-vhost alias editor height.
|
||||
- [x] Render idle backend traffic as `0.0 KiB/s` and positive sub-0.1 KiB/s traffic as `<0.1 KiB/s`.
|
||||
- [x] Remove cache diagnostics/validators from locally generated placeholder/default pages and enforce `no-store`.
|
||||
- [x] Allow safe vhost-ID rename with collision protection and operator warning.
|
||||
- [x] Update package/source identity, OpenAPI and release checks to 0.19.2.
|
||||
|
||||
## 0.19.1
|
||||
|
||||
Current direction: 0.19.0 -> 0.19.1
|
||||
|
||||
- [x] Repair Default responses section serialization/server routing.
|
||||
- [x] Isolate cache objects by frontend scheme.
|
||||
- [x] Keep a 256-entry live log window with 4096 retained entries available on demand.
|
||||
- [x] Polish backend traffic units, checkbox/column UI and Docker-vhost Advanced layout/alias spacing.
|
||||
- [x] Remove stale screenshots and index historical/version-labelled documentation.
|
||||
- [x] Restore source-package test files/fixtures required by the release gates.
|
||||
- [x] Update package/source identity, OpenAPI and release checks to 0.19.1.
|
||||
|
||||
## 0.19.0
|
||||
|
||||
Current direction: 0.18.8 -> 0.19.0
|
||||
|
||||
- [x] Persist per-admin Live Logs column visibility in SQLite without affecting JSON export or proxy configuration revisions.
|
||||
- [x] Remove the duplicate top-right version badge.
|
||||
- [x] Carry the legacy X.509 `tls_verify=false` compatibility fix and expanded upstream diagnostics into the release.
|
||||
- [x] Add schema-v4 migration, administration API coverage and update package/source identity to 0.19.0.
|
||||
|
||||
## 0.18.8
|
||||
|
||||
Current direction: 0.18.7 -> 0.18.8
|
||||
|
||||
- [x] Use hostname-style chips for Docker-vhost aliases.
|
||||
- [x] Add per-app HTTP-to-HTTPS redirect, WebSocket and cache switches for Docker vhosts.
|
||||
- [x] Add an agent-level default ACL-profile selector without removing per-app ACL overrides/inline rules.
|
||||
- [x] Remove the compression-codec explainer from Overview.
|
||||
- [x] Update package/source identity, API schema and release checks to 0.18.8.
|
||||
|
||||
## 0.18.7
|
||||
|
||||
Current direction: 0.18.6 -> 0.18.7
|
||||
|
||||
- [x] Keep Response time history collapsed by default without stopping its live samples.
|
||||
- [x] Make per-interface RX/TX charts visually consistent with the aggregate network history.
|
||||
- [x] Fix expanded Docker-vhost route/ACL field alignment from the 0.18.6 UI.
|
||||
- [x] Update package/source identity and release checks to 0.18.7.
|
||||
|
||||
## 0.18.6
|
||||
|
||||
Current direction: 0.18.5 -> 0.18.6
|
||||
|
||||
- [x] Add network-throughput diagnostics split by non-loopback host interface.
|
||||
- [x] Re-audit compression counters and add q-weighted negotiation coverage for all four supported codecs.
|
||||
- [x] Polish Docker-agent settings alignment and spacing around listener selection / Add agent.
|
||||
- [x] Update package/source identity and release checks to 0.18.6.
|
||||
|
||||
## 0.18.5
|
||||
|
||||
Current direction: 0.18.4 -> 0.18.5
|
||||
|
||||
- [x] Make compression counters track the codec actually applied by RustProxy and add independent per-codec regression coverage.
|
||||
- [x] Split the Overview request-rate chart into total, HTTP/1.1, HTTP/2 and HTTP/3 series.
|
||||
- [x] Add a proxied-app launcher to Docker vhosts and show their domains beside generated backend-pool IDs.
|
||||
- [x] Remove the global Open proxy shortcut.
|
||||
- [x] Make Compact density clearly tighter than Dense.
|
||||
- [x] Give proxy timeout controls explicit safe defaults instead of blank inherited values.
|
||||
- [x] Replace Docker-agent listener CSV entry with the named-listener picker and tighten the agent status-row UX.
|
||||
- [x] Update package/source identity and release checks to 0.18.5.
|
||||
|
||||
## 0.18.4
|
||||
|
||||
Current direction: 0.18.3 -> 0.18.4
|
||||
|
||||
- [x] Make TCP the default backend health-check mode without rewriting existing explicit HTTP/off configuration.
|
||||
- [x] Make Docker vhosts summary-first so large container inventories do not render every routing/ACL/timeout/health control at once.
|
||||
- [x] Simplify Settings -> Security with progressive disclosure for credential and host-policy editing.
|
||||
- [x] Move Administration audit to a dedicated on-demand modal.
|
||||
- [x] Update package/source identity and release checks to 0.18.4.
|
||||
|
||||
## 0.18.3
|
||||
|
||||
Current direction: 0.18.2 -> 0.18.3
|
||||
|
||||
- [x] Export Docker vhosts/backends under dedicated Prometheus metric families rather than ordinary vhost/backend families.
|
||||
- [x] Add a separate live Docker-vhosts metric-group switch in Prometheus settings.
|
||||
- [x] Cover Docker vhost traffic/duration and backend health/latency/probe/runtime observations with bounded labels.
|
||||
- [x] Add regression checks for ordinary-vs-Docker metric isolation.
|
||||
- [x] Add configurable separate access-log files per vhost and preserve bounded asynchronous sink behavior.
|
||||
- [x] Lock startup-owned HTTP/HTTPS/admin binds while keeping non-startup listeners editable.
|
||||
- [x] Polish compact UI, 404 response statuses, redirect summaries, global TLS cipher visibility and managed-certificate lifecycle UX.
|
||||
- [x] Default WebSocket proxying to HTTP/1.1 Upgrade and make RFC 9220 HTTP/3 Extended CONNECT an explicit experimental vhost opt-in.
|
||||
|
||||
## 0.18.2
|
||||
|
||||
Current direction: 0.18.1 -> 0.18.2
|
||||
|
||||
- [x] Serve the standalone Docker agent over HTTPS by default using a persistent self-signed ECDSA certificate.
|
||||
- [x] Add SHA-256 certificate pinning for self-signed Docker agents while retaining normal public-CA validation when no pin is configured.
|
||||
- [x] Add per-service Docker backend health-check settings backed by the normal bounded backend health machinery.
|
||||
- [x] Show Docker backend health/runtime diagnostics and agent TLS/observation state in the Docker vhosts UX.
|
||||
|
||||
## 0.18.1
|
||||
|
||||
Current direction: 0.18.0 -> 0.18.1
|
||||
|
||||
- [x] Add a standalone, token-authenticated Docker discovery agent that reports only running containers with non-loopback published TCP ports.
|
||||
- [x] Add multi-agent endpoint/token/base-domain/listener/default-IP settings and keep observed Docker inventory separate from desired persisted assignments.
|
||||
- [x] Detect multiple usable Docker-host addresses and preserve every public Docker bind for each discovered service.
|
||||
- [x] Add a Docker vhosts panel with short names, arbitrary FQDNs, aliases and per-service backend-IP selection; reconcile assignments into dynamic ephemeral vhosts without revision writes.
|
||||
- [x] Move the cache Live toggle to the right edge of the cache action toolbar.
|
||||
- [x] Remove all dedicated `X-Rust-Proxy-Revision` handling; it is no longer generated, stripped, protected or migrated.
|
||||
- [x] Replace production password recovery help with the installed `rust-proxy admin reset-password` command.
|
||||
|
||||
## 0.17.0
|
||||
|
||||
Current direction: 0.16.1 -> 0.17.0
|
||||
|
||||
- [x] Add Debian/systemd/logrotate packaging and local APT-repository generation.
|
||||
- [x] Export all currently implemented bounded process/OS diagnostics and extend safe Prometheus coverage for backend, GeoIP, certificate renewal, stream and logging state.
|
||||
- [x] Add explicit trusted-CIDR Prometheus scraping without a token and preserve actual-peer-only ACL evaluation.
|
||||
- [x] Ship a Grafana operations dashboard.
|
||||
- [x] Add dedicated certificate/listener-aware local-response / 404 hosts and a dashboard editor.
|
||||
- [x] Keep the built-in welcome placeholder `no-store` and strip optional response metadata.
|
||||
- [x] Match Redirect source-domain editing UX to Vhost hostname chips.
|
||||
|
||||
## 0.16.1
|
||||
|
||||
Current direction: 0.16.0 -> 0.16.1
|
||||
|
||||
- [x] Keep revision CAS as an internal concurrency mechanism but stop showing revision numbers in successful configuration-save feedback.
|
||||
- [x] Preserve all 0.16.0 proxy/cache/H3/admin/UX behavior and bump release identity to 0.16.1.
|
||||
|
||||
## 0.16.0
|
||||
|
||||
- [x] Keep the main vhost backend as an internal fallback separate from Custom locations, with legacy synthetic-root normalization.
|
||||
- [x] Preserve the reserved administration session cookie only for an explicitly allowed, TLS-protected self-admin reverse-proxy route; ordinary upstreams remain isolated.
|
||||
- [x] Complete backend WebSocket takeover before HTTP/3 Extended CONNECT success and add phase/error/reset/upstream diagnostics to access logs.
|
||||
- [x] Split process-memory and cache-memory reporting into RSS categories plus hot/transient fill/cold-queue/cold-I/O gauges while retaining the existing allocator-release paths.
|
||||
|
||||
## 0.15.1
|
||||
|
||||
Current direction: 0.15.0 -> 0.15.1
|
||||
|
||||
- [x] Repair EN/PL Custom locations/help translations and reject misplaced language-pack keys in release checks.
|
||||
- [x] Rework visual header-rule editing and add a live effective-behavior preview to each location.
|
||||
- [x] Expand in-panel location documentation with structured sections and common examples.
|
||||
- [x] Add combined HIT/MISS/BYPASS activity and Proxy process CPU/RSS charts.
|
||||
|
||||
## 0.15.0
|
||||
|
||||
Current direction: 0.14.0 -> 0.15.0
|
||||
|
||||
- [x] Add Nginx-style Custom location matching, rewrite and local-response controls with inline documentation and a visual header-rule builder.
|
||||
- [x] Add reusable Nagios/Icinga API checks for control-plane latency, backend availability/latency and dropped-work counters.
|
||||
- [x] Move per-vhost timing/Cloudflare diagnostics to the main frontend configuration and add source IP to live logs.
|
||||
- [x] Add dashboard history charts for RAM cache, network throughput and response latency plus compact API/footer diagnostics.
|
||||
- [x] Add separate idle-age and total-hot-residency cold-cache policies.
|
||||
- [x] Remove the runtime renewal-observation JSON importer and quarantine obsolete state only during a stopped source upgrade.
|
||||
- [x] Accept repeated literal path separators by normalizing them for routing/ACL decisions while preserving the original backend target.
|
||||
|
||||
## 0.14.0
|
||||
|
||||
Current direction: 0.13.2 -> 0.14.0
|
||||
|
||||
- [x] Accept explicitly allowlisted browser-facing administration DNS authorities behind a trusted reverse proxy without requiring the internal admin port.
|
||||
- [x] Keep direct IP/localhost administration access on the configured admin port and derive same-origin/cookie security from trusted external proxy metadata.
|
||||
- [x] Implement RFC 9220 WebSocket Extended CONNECT over HTTP/3 without a side-channel transport or HTTP/1.1 bootstrap fields on the client-facing H3 request.
|
||||
- [x] Move the H3 stack to `hpx-h3 2.5.19` with integrated Quinn transport and advertise Extended CONNECT support.
|
||||
- [x] Rename the requested dashboard sections/actions in EN/PL and update release contracts/documentation.
|
||||
|
||||
## 0.13.2
|
||||
|
||||
Current direction: 0.13.1 -> 0.13.2
|
||||
|
||||
- [x] Honor a valid administrator session on direct panel refresh and revalidate stale browser-history login documents.
|
||||
- [x] Force hot-cache handoff to enabled cold storage during managed updates and provide a longer controlled-stop budget.
|
||||
- [x] Store automatic-renewal observations in SQLite schema v3 and restore them before the administration listener starts, with one-time legacy JSON import.
|
||||
- [x] Move the raw configuration document editor under **Settings -> Manual config** while preserving `/configuration` as a compatibility alias.
|
||||
- [x] Update documentation, OpenAPI, language help, offline regressions and release identity.
|
||||
|
||||
## 0.13.1
|
||||
|
||||
Current direction: 0.13.0 -> 0.13.1
|
||||
|
||||
- [x] Extend administrator browser sessions to a configurable absolute 7–30 day lifetime, default 30 days.
|
||||
- [x] Keep password change, logout and revoke-all as immediate session invalidation boundaries.
|
||||
- [x] Allow deliberate local-listener backends, including port 9090, only behind explicit per-backend risk acceptance while retaining private/special-address policy.
|
||||
- [x] Add panel confirmation, OpenAPI fields, EN/PL strings, documentation and regressions.
|
||||
|
||||
## 0.13.0
|
||||
|
||||
Current direction: 0.12.1 -> 0.13.0
|
||||
|
||||
- [x] Add first-class redirect hosts and dashboard navigation.
|
||||
- [x] Support scheme/path matching, URL/host/path targets, 301/302/303/307/308, path/query and redirect-cache controls.
|
||||
- [x] Share named listeners and certificate inventory with redirects while rejecting conflicting frontend ownership.
|
||||
- [x] Default backend HTTPS `tls_verify` to false when omitted; keep explicit opt-in verification.
|
||||
- [x] Compact certificate inventory cards, render DNS SANs as vhost-style badges and inspect legacy/manual public PEM files when stored coverage metadata is absent.
|
||||
- [x] Update OpenAPI, docs, translations, regressions and release identity.
|
||||
|
||||
## 0.12.1
|
||||
|
||||
Current direction: 0.12.0 -> 0.12.1
|
||||
|
||||
- [x] Split ordinary configuration writes into revisioned section endpoints and retain atomic full-document publication for intentional multi-section changes.
|
||||
- [x] Stop unrelated control-plane saves from rotating cache compatibility identity.
|
||||
- [x] Preserve dashboard subpage routing across browser refresh/back-forward navigation.
|
||||
- [x] Add independently selectable cold-cache idle/LRU/shutdown persistence policies.
|
||||
- [x] Flush hot cache objects to cold storage during graceful shutdown and release RAM after bulk demotion where the allocator supports it.
|
||||
- [x] Expose certificate DNS SubjectAltName coverage separately from configured SNI bindings.
|
||||
- [x] Improve HTTPS backend TLS validation guidance while preserving secure-by-default omitted configuration and the explicit debug preset.
|
||||
- [x] Update OpenAPI, regression checks and release identity to 0.12.1.
|
||||
- [ ] Compile and execute the Rust test suite on a Rust 1.88+ staging host.
|
||||
|
||||
## 0.12.0
|
||||
|
||||
Current direction: 0.11.5 -> 0.12.0
|
||||
|
||||
- [x] Move Layer-4 TCP/UDP stream management out of Settings into a dedicated main-navigation page directly below Vhosts.
|
||||
- [x] Give Streams the vhost-style searchable card + modal workflow with explicit active-versus-desired restart state.
|
||||
- [x] Add fixed-cardinality per-stream connection/session, reject, error, byte and UDP packet telemetry without database work on the data path.
|
||||
- [x] Add browser-session RX/TX rate charts derived from monotonic backend stream counters.
|
||||
- [x] Restyle named listener bind addresses with the same chip interaction used for vhost hostnames.
|
||||
- [x] Extend offline source/release regression gates for Streams navigation, authenticated assets, UI contracts and L4 metrics source invariants.
|
||||
|
||||
- [x] Stop successful unsafe methods from globally purging otherwise unrelated cached GET objects.
|
||||
- [x] Use Host + URL as the logical primary cache identity and response `Vary` for representation variants instead of hashing unrelated request headers/backend members.
|
||||
- [x] Share cache objects across backend-pool members and GET/HEAD requests.
|
||||
- [x] Preserve resident age through 304 revalidation and hot/cold movement; persist the additional cold metadata in format 2.
|
||||
- [x] Add variant-schema safety and cache regression coverage for the new behavior.
|
||||
- [x] Make Force SSL require a real HTTP ingress and choose port 443 deterministically when several TLS ports are selected.
|
||||
- [x] Add a graphical ACL-profile rule editor and resilient bulk-rule import with exact line errors.
|
||||
- [x] Hide RustProxy cache diagnostics when a vhost explicitly disables cache.
|
||||
- [x] Distinguish disabled vhost pools from unhealthy backends in the dashboard.
|
||||
- [x] Add per-vhost client-IP forwarding control without weakening RustProxy ACL/GeoIP/rate-limit/Tinyauth identity.
|
||||
- [x] Add a compact vhost search/filter for large installations.
|
||||
- [x] Keep the checked-in Cargo lockfile stable and correct the Quinn manifest version to the resolved release.
|
||||
- [x] Make the standard JSONL log directory writable under the hardened systemd service.
|
||||
- [x] Accept HTTP/2/H3 `:authority` on the HTTPS administration panel without requiring a duplicate legacy Host header.
|
||||
- [x] Reject ambiguous requests where legacy Host conflicts with protocol-native authority, while preserving strict HTTP/1.x origin-server semantics.
|
||||
- [x] Add administration H2 authority and `/healthz` regression tests.
|
||||
- [x] Add per-vhost Force SSL with an HTTP 308 redirect to the configured TLS frontend while preserving path/query.
|
||||
- [x] Preserve NPM `ssl_forced` in the SQLite migrator as RustProxy Force SSL with usable HTTP+HTTPS listener bindings.
|
||||
- [x] Fix managed update/rollback health checks for persisted administration HTTPS and changed admin bind/Host policy.
|
||||
- [x] Add a dry-run-first SQLite migration tool for Nginx Proxy Manager proxy-host names and backends, with generic RustProxy TLS certificate fallback and manual-review warnings for unsupported NPM features.
|
||||
- [x] Add offline migration-planner and HTTPS health-target regression coverage.
|
||||
- [x] Add reusable ACL Profiles with country allow/block and IP/CIDR policy, attachable per vhost while retaining cumulative inline vhost and route ACL controls.
|
||||
- [x] Add chip-style hostname editing and leading `*.` wildcard domains with exact-host and longest-wildcard precedence.
|
||||
- [x] Add compact browser-session request-rate charts to vhost cards with progressive lifetime compaction.
|
||||
- [x] Add the built-in HTTP 401 error page and treat benign post-upgrade WebSocket closes as normal tunnel completion.
|
||||
- [x] Redirect plaintext requests arriving on the HTTPS administration socket and accept valid DNS Host values when no explicit admin hostname allowlist is configured.
|
||||
- [x] Allow one named frontend listener policy to bind up to 16 explicit local addresses while forbidding wildcard binds in multi-address mode.
|
||||
- [x] Align the Logging format builder with the Vhost configuration modal and reposition its field-configuration action.
|
||||
- [x] Make source ZIP generation deterministic and verify reproducibility in release smoke tests.
|
||||
- [x] Add bounded hot RAM and optional persistent cold disk cache tiers with asynchronous demotion/promotion, restart recovery, integrity metadata and separate hot/cold statistics.
|
||||
- [x] Add cold-tier settings for path, disk/object budgets and idle demotion time while preserving global hot RAM limits.
|
||||
- [x] Add structured-log format presets plus a visual field selector/renamer with JSON preview and advanced raw mapping fallback.
|
||||
- [x] Normalize Logging sink cards to the shared application card styling instead of release-specific fieldset CSS.
|
||||
- [x] Add baseline multi-stage Docker/OCI packaging with an unprivileged runtime user and persistent data volume.
|
||||
- [x] Document browser hard-reload cache revalidation semantics and expose the exact request revalidation reasons in the cache inspector.
|
||||
- [x] Redesign vhost cards around listener/protocol/certificate/cache identity plus live pool health, requests, active exchanges, errors, latency and traffic rate.
|
||||
- [x] Add bounded structured JSON access-log sinks for JSONL files, Logstash TCP and Loki HTTP(S), with configurable field mapping/static fields and sink counters.
|
||||
- [x] Expand cache object inspection with body bytes, resident bytes, overhead and aggregate stored-object memory counters.
|
||||
- [x] Add optional `X-Cache-Resident-Age` and expose resident age for stored HITs.
|
||||
- [x] Add administration HTTPS using the application-managed default certificate or a selected certificate, with restart-aware persisted bind address and hostname allow list.
|
||||
- [x] Permit non-loopback administration binding when HTTPS is enabled; keep plain remote HTTP behind the legacy explicit risk gate.
|
||||
- [x] Add global TLS protocol/cipher policy plus per-vhost TLS 1.2/1.3 and cipher overrides for TCP TLS. HTTP/3 vhosts inherit the global TLS 1.3 policy.
|
||||
- [x] Make Settings tabs fill the available width and add dedicated Administration/TLS policy pages plus a separate Logging navigation page.
|
||||
- [x] Enable shared cache by default while keeping explicit vhost/route disable controls.
|
||||
- [x] Implement fresh conditional HIT for `If-None-Match` / `If-Modified-Since`.
|
||||
- [x] Implement backend validator revalidation and cached-body reuse on backend 304.
|
||||
- [x] Treat request/response `no-cache` as validation semantics rather than no-store; preserve `no-store` as hard exclusion.
|
||||
- [x] Retain stale validators for bounded revalidation without stale serving.
|
||||
- [x] Raise maximum object configuration to 1 GiB and remove eager object-sized fill allocation.
|
||||
- [x] Add diagnostics, real-binary smoke scenarios, unit regressions and 0.8.1 release documentation.
|
||||
- [x] Per-vhost H2/H3 frontend opt-outs next to named-listener selection, capability-gated by Settings listeners.
|
||||
- [x] Global static-cookie cache defaults for common assets, visible global/per-vhost controls and response-side privacy guards.
|
||||
- [x] Listener editor uses page scrolling without a nested scrollbar.
|
||||
- [x] Per-vhost fixed-window request rate limiting with burst allowance.
|
||||
- [x] Per-country rate overrides and block/allow-only country access rules backed by verified install-time GeoIP data.
|
||||
- [x] Cloudflare client IP mode gated by direct-peer Cloudflare CIDRs.
|
||||
- [x] Per-vhost H2/H3 frontend opt-outs and Server-Timing diagnostics.
|
||||
- [x] Named listener selection in vhosts; listening IP/ports managed in Settings.
|
||||
- [x] Health-check `off` disables active and passive classification.
|
||||
- [x] HTTPS-by-IP backend debugging defaults and warnings.
|
||||
- [x] Global static-cookie cache defaults plus per-vhost inheritance/overrides with response privacy guards.
|
||||
- [x] Corrected cache Age calculation.
|
||||
- [x] Updated deployment regressions, docs and 0.8.0 release identity.
|
||||
- [x] Release CLI can generate the one-time setup token before first server start.
|
||||
- [x] Explicit two-flag risk gate for wildcard remote administration binding.
|
||||
- [x] Numeric Host validation for the wildcard panel; DNS hostnames remain rejected.
|
||||
- [x] Linux/systemd install defaults enable 80/443; explicit `--no-https` opt-out.
|
||||
- [x] Updated deployment regressions, docs and 0.7.3 release identity.
|
||||
- [ ] Build/check/test the Rust binary and exercise remote-panel/systemd behavior live.
|
||||
- [x] Explicit release identity, without overwriting the 0.7.1 artifact.
|
||||
- [x] Swagger asset default independent of environment presence/Cargo config lookup.
|
||||
- [x] Embedded assets prepared by our build, without an adapter's old-version fallback.
|
||||
- [x] Offline local ZIP, bounded member validation, optional SHA-256 and safe caching.
|
||||
- [x] Executable build-helper regressions and updated build/migration instructions.
|
||||
- [ ] Build/check/test real Rust and render the actual upstream Swagger distribution.
|
||||
- [x] Per-location visual proxy-request and client-response header rules.
|
||||
- [x] Minimal anonymous login document and filtered extensible language bundle.
|
||||
- [x] Exact default-deny admin route/method policy including private assets and docs.
|
||||
- [x] Protected OpenAPI/Swagger, cookie session and CSRF-confirmed mutations.
|
||||
- [x] Generic public discovery/errors and cross-tab UI revocation cleanup.
|
||||
- [x] Source audit, access probe and regression tests with explicit execution limits.
|
||||
- [ ] Compile and run router/proxy tests, inspect real Swagger rendering, and run the
|
||||
anonymous probe against the built release before production acceptance.
|
||||
- [x] Scheduled renewal for HTTP-01, Cloudflare, OVH and RFC2136 managed profiles.
|
||||
- [x] Validated revisioned hot certificate publication with unchanged/failure safety.
|
||||
- [x] Per-certificate opt-out, manual check, dry run, next/last/expiry observations.
|
||||
- [x] Separate install/update scripts; isolated service, full data backup and rollback.
|
||||
- [x] Vhost Basic Auth with bounded Argon2id checks and optional credential forwarding.
|
||||
- [x] Per-vhost WebSocket toggle and graphical cumulative CIDR ACL editing.
|
||||
- [x] Visual prefix locations with pool exclusion for dedicated origins.
|
||||
- [x] Neutral welcome page, opt-in protocol fixture, shared square modal/Settings style.
|
||||
- [x] Independent proxy and local administrator control plane; no Docker dependency.
|
||||
- [x] SQLite documents, revision CAS, immutable snapshots, audit and private backups.
|
||||
- [x] Accounts, bounded sessions, setup capability, origin/CSRF protections.
|
||||
- [x] Host/path routes, aliases, explicit private-origin permission and CIDR ACLs.
|
||||
- [x] Streaming bodies and full-exchange limits; bounded logs, SSE and Prometheus.
|
||||
- [x] Public TLS/SNI, verified HTTPS upstreams, guarded DNS, HTTP/2 and WebSocket source.
|
||||
- [x] Whole-source upgrade, legacy auth-module repair and rollback on copy failure.
|
||||
- [x] Persist public HTTP/HTTPS bind addresses and ports, including 80/443 presets.
|
||||
- [x] Distinguish active listeners, desired listeners and startup defaults; show restart pending.
|
||||
- [x] Allow remote origins on ordinary 80/443 without allowing local listener loops.
|
||||
- [x] RAM cache with TTL/Age, entry/object/byte limits, LRU eviction and route bypass.
|
||||
- [x] Bounded streaming fills; do not publish partial, failed, oversized or trailer bodies.
|
||||
- [x] Privacy exclusions, conservative Vary identity and ACL-before-cache ordering.
|
||||
- [x] Optional X-Cache, X-Cache-Hits and Cache-Status; counters and authenticated purge.
|
||||
- [x] Invalidate old fill generations on purge, config publication and successful unsafe methods.
|
||||
- [x] Streaming gzip, Brotli, Zstandard and deflate negotiation with privacy/no-transform safeguards.
|
||||
- [x] Preserve/hide/custom Server policy; client-response and upstream-request header editors.
|
||||
- [x] Denser responsive dashboard; original logo retained.
|
||||
- [x] OS/process CPU, RAM/RSS, load, descriptors, threads, network, cgroup and cache diagnostics.
|
||||
- [x] Compile-time language discovery from langs/*.json; metadata, fallback and RTL.
|
||||
- [x] Extra language files survive managed source updates.
|
||||
- [x] Log filtering by host/path/cache outcome and bounded JSON export.
|
||||
- [x] Unit and real-binary integration test source; 49 simulated-API frontend checks.
|
||||
- [x] Example unprivileged systemd service with low-port capability.
|
||||
- [x] Remove reported compression threshold type mismatch without narrowing or panic conversion.
|
||||
- [x] Explicit frontend IP/port/TLS ownership inside a vhost; actual-destination isolation.
|
||||
- [x] Multiple backend members, weights, backup and drain modes.
|
||||
- [x] Weighted round-robin, least active exchanges, least traffic, adaptive and IP hash.
|
||||
- [x] Connection keepalive/reuse limits and timers, not a Keepalived/VRRP integration.
|
||||
- [x] Bounded TCP/HTTP health checks, slow-response exclusion, fall/rise and recovery.
|
||||
- [x] Opaque cookie/IP affinity; compatible edit continuity, safe cache bypass.
|
||||
- [x] Full-exchange backend leases; no automatic replay of failed writes.
|
||||
- [x] Per-vhost response/security headers, TLS-only HSTS and explicit preload policy.
|
||||
- [x] HTTP/2 TLS preference retains HTTP/1.1 for clients and HTTPS origins.
|
||||
- [x] Vhost editor, atomic legacy migration, health/traffic/latency dashboard and API metrics.
|
||||
- [x] All new user-facing text in discovered language packs; logo unchanged.
|
||||
- [x] Rust regression and real-binary acceptance test source; 63 simulated-API UI checks.
|
||||
- [x] Complete source update, examples, migration documentation and evidence report.
|
||||
- [x] Split oversized status JSON expansion instead of masking it with a larger recursion limit.
|
||||
- [x] Optional per-vhost certificate upload/selection with bounded private staging and validated SNI mappings.
|
||||
- [x] Independent vhost cache behavior, inherited defaults and shared resident/object ceilings.
|
||||
- [x] **Selective cache invalidation by vhost**, promoted from Cache evolution; invalidate pending fills too.
|
||||
- [x] Compact manager list and tabbed vhost dialog, visual header rules and live health/latency.
|
||||
- [x] Dashboard density presets and top alignment, without redesigning the logo.
|
||||
- [x] Separate modal/docked live logs with persistent controls, vhost filters, pause and scoped export.
|
||||
- [x] Global/vhost error pages, maintenance/static response and direct-IP/unknown-host behavior.
|
||||
- [x] Security shortcut within Settings; new labels remain in discoverable language packs.
|
||||
- [x] Python-only random-data mock origin for cache, health, delay, compression and error-page development.
|
||||
- [x] Regression test source for new runtime policies; executed frontend/helper checks in TEST_REPORT.md.
|
||||
- [x] Canonical Forwarded/X-Forwarded-For/X-Real-IP with explicit bounded proxy trust; keep destination-IP routing independent.
|
||||
- [x] Per-vhost Tinyauth auth subrequest, sanitized identity headers, restricted login redirects and fail-closed handling before cache/static/upgrades.
|
||||
- [x] Separate certificate inventory tab with upload, per-vhost selection and metadata-only read API; leave ACME as future work.
|
||||
- [x] Named multiple-IP listeners, descriptive scope, reusable vhost references and explicit legacy-route permission.
|
||||
- [x] HTTP/3 UDP adapter using Quinn/h3 with TLS 1.3, same SNI/policy pipeline, Alt-Svc, requested limits and bounded drain; retain TCP H2/H1.
|
||||
- [x] Request ID/revision off by default, independent per-vhost controls, optional mock-origin removal and effective per-vhost Server policy.
|
||||
- [x] Actual frontend socket in cache identity; streaming-safe empty request detection for H2/H3.
|
||||
- [x] Toast above active modal backdrop, including browser top-layer/inertness handling.
|
||||
- [x] Python fake-auth peer plus Rust regression sources for auth, headers, extra-frontend cache, listeners and real QUIC/TCP.
|
||||
- [x] Dedicated bounded cache panel: resident objects/bytes, per-domain effectiveness, TTL/Age/hits, reasons and vhost filters.
|
||||
- [x] Remove the reserved administrator cookie before cache eligibility; preserve application-cookie privacy.
|
||||
- [x] Handle empty terminating DATA frames and expose fixed X-Cache-Reason / Cache-Status detail diagnostics.
|
||||
- [x] Replace special mock-origin hiding with explicit revision controls; keep general header rules.
|
||||
- [x] Default HTTP/3 for TLS while persisting explicit opt-out and TCP fallbacks.
|
||||
- [x] Diagnose overlapping sockets with addresses, ownership, protocol/limit differences and remedies.
|
||||
- [x] Classify unavailable/invalid/timed-out upstreams as 503/502/504 respectively.
|
||||
- [x] Basic Let's Encrypt DNS-01/RFC2136 job and library-import workflow through Certbot; private TSIG/account state and staging-first consent.
|
||||
- [x] Offline adapter tests, browser fixtures and Rust regression sources; unchanged brand assets.
|
||||
- [x] Vhosts-only runtime/UI and one-way legacy import preserving path/backend and IP ownership.
|
||||
- [x] HTTP-01 active-job/domain-scoped challenge serving with private webroot storage.
|
||||
- [x] Certbot Cloudflare and OVH API DNS-01 adapters alongside RFC2136.
|
||||
- [x] Unified provider/import dialog, masked credentials, explicit consent and issuer metadata.
|
||||
- [x] Dedicated opt-in Prometheus endpoint, scrape CIDRs and environment-token authentication.
|
||||
- [x] Application/admin/listener/vhost/backend/cache/system collectors and exchange histograms.
|
||||
- [x] Functional Settings tabs with preserved dirty fields, keyboard navigation and no Security sidebar.
|
||||
- [x] Offline provider regressions, simulated-API UI checks and unexecuted Rust acceptance tests.
|
||||
- [ ] Validate real HTTP-01, Cloudflare/OVH/RFC2136 DNS updates, CA issuance, cancellation cleanup and certificate hot-deployment.
|
||||
- [x] Add the managed renewal scheduler and audited validated deployment source.
|
||||
- [ ] Verify real renewal/publication and add external expiry alerts, revocation/account lifecycle.
|
||||
- [ ] Resolve and retain Cargo.lock; run check, test and all real-binary suites.
|
||||
- [ ] Verify real Tinyauth integration, revocation, trusted forwarding and independent HTTP/3 client interoperability.
|
||||
- [ ] Run an independent RFC 9114/QUIC conformance suite, malformed-stream/load tests and actual TLS/UDP production deployment checks.
|
||||
- [ ] Execute vhost isolation/weighted balancing/health/recovery/keepalive/affinity acceptance against a real Rust binary.
|
||||
- [ ] Verify compression output with independent Brotli/Zstandard decoders.
|
||||
- [ ] Run real TLS/HTTP2/WebSocket/cache concurrency, cancellation and graceful-drain tests.
|
||||
- [ ] Benchmark HIT/MISS/streaming RSS and CPU under slow clients and origin failures.
|
||||
- [ ] Fuzz malformed HTTP/cache directives and language-pack validation.
|
||||
- [ ] Exercise real non-root 80/443 bindings and systemd service confinement.
|
||||
- [ ] Verify native browser HTTP/CSP/cookie enforcement (navigation blocked in this environment).
|
||||
- [ ] Validate the dedicated scrape endpoint/token with a real Prometheus server and production network policy.
|
||||
- [x] X-Cache-Resident-Age - implemented in 0.9.0
|
||||
|
||||
## Optional module follow-ups
|
||||
|
||||
### Docker discovery
|
||||
|
||||
Implemented in 0.18.1 through the standalone `docker-agent/` provider boundary.
|
||||
Future work can add provider-side filters, mTLS and DNS-provider automation; the core remains useful without Docker and never opens the Docker socket itself.
|
||||
|
||||
### Cache evolution
|
||||
|
||||
Conditional revalidation is implemented. Stale-while-revalidate/stale-if-error, request collapsing,
|
||||
tag-based invalidation and richer per-route policy remain open. Persistent hot/cold storage is implemented in 0.10.0.
|
||||
Selective invalidation by vhost is implemented in 0.3.0; the domain/object inspector in 0.5.0; tags are not. No VCL engine,
|
||||
distributed cache, ESI or Varnish-protocol compatibility is implemented.
|
||||
|
||||
### Operations
|
||||
|
||||
Container/OCI packaging is implemented in 0.10.0. Certificate alerting/revocation and account lifecycle, reproducible releases,
|
||||
performance baselines and cross-platform diagnostics remain open. Remote HTTPS administration is implemented in 0.9.0;
|
||||
loopback remains the default and plain remote HTTP remains explicitly risk-gated.
|
||||
+12
-2
@@ -11,8 +11,10 @@ Administration binds to loopback HTTP by default. Settings can enable a dedicate
|
||||
administration HTTPS listener, choose the application-managed certificate or a
|
||||
certificate from the inventory, persist a non-loopback bind and allow explicit DNS
|
||||
Host/Origin names. Remote persisted binding is accepted only with administration TLS.
|
||||
An explicit startup `--allow-remote-admin` can expose plain HTTP on a non-loopback address;
|
||||
that path should remain behind a trusted firewall/private network boundary.
|
||||
The normal installer, one-line bootstrap and reference service keep the plain-HTTP admin listener
|
||||
on loopback by default. An explicit startup `--allow-remote-admin` can expose plain HTTP on a
|
||||
non-loopback address; that path should remain behind a trusted firewall/private network boundary and
|
||||
should be replaced by Administration HTTPS for direct remote use.
|
||||
Passwords use salted Argon2id; password work has admission limits and runs off the
|
||||
network I/O path. Setup requires local filesystem authority or the one-time random
|
||||
capability. No default administrator/password is created.
|
||||
@@ -77,6 +79,14 @@ not application-level authorization or message semantics. Frame/message limits o
|
||||
backend remain the backend's responsibility. Proxy buffers, tunnel/connection counts
|
||||
and inactivity timers bound proxy-side resource usage.
|
||||
|
||||
Web Server PHP-FPM integration never forwards the client `Proxy` header as CGI `HTTP_PROXY`
|
||||
(httpoxy protection), regardless of optional Web Service hardening. FastCGI response framing and
|
||||
hop-by-hop headers are discarded and RustProxy owns downstream framing. PHP-FPM endpoints are
|
||||
limited to Unix sockets or loopback TCP. Optional custom FastCGI parameters are validated static
|
||||
operator values and cannot replace core CGI, `HTTP_*`, `PHP_VALUE` or `PHP_ADMIN_VALUE`; php.ini
|
||||
overrides use a dedicated validated `PHP_VALUE` map. Configurable request-body, response-header
|
||||
and stderr bounds keep the PHP connector resource usage explicit.
|
||||
|
||||
## Information and resource controls
|
||||
|
||||
Access logging does not collect credential headers, query values, cookies, bodies
|
||||
|
||||
+2
-5
@@ -80,9 +80,7 @@ Use a firewall and normal network policy even with HTTPS.
|
||||
|
||||
## Structured access logging
|
||||
|
||||
The **Settings -> Logging** tab controls optional external sinks while the existing bounded
|
||||
live ring remains available to the panel. Sink I/O is performed by a bounded background
|
||||
queue; request processing only performs a non-blocking enqueue. Supported destinations:
|
||||
The **Settings -> Logging** page is split into **Outputs**, **JSON format** and **Error log** subsections, using the same in-card sub-tab layout and keyboard interaction as Cache. Outputs controls optional external access-log sinks while the existing bounded live ring remains available to the panel. Sink I/O is performed by a bounded background queue; request processing only performs a non-blocking enqueue. Supported destinations:
|
||||
|
||||
- JSONL file append, either one combined file such as `/var/log/rustproxy/access.jsonl` or
|
||||
one file per resolved vhost under a configurable directory (default `/var/log/rustproxy/vhosts`).
|
||||
@@ -96,8 +94,7 @@ queue; request processing only performs a non-blocking enqueue. Supported destin
|
||||
`logging.format.fields` maps output field names to standard event fields; an empty map
|
||||
emits the complete standard event. The panel provides Standard, Nginx-style, ECS-style
|
||||
and Minimal presets plus a visual field selector/renamer with JSON preview. Advanced raw
|
||||
mapping remains available for aliases not representable by the simple builder.
|
||||
`static_fields` adds constant string fields. Loki labels are separately configurable.
|
||||
mapping remains available for aliases not representable by the simple builder. Supported mapped sources include `vhost`, `route`, `cache_effective_enabled`, `transform_effective_enabled`, `backend`, request/response metadata and cache outcome fields. `static_fields` adds constant string fields. Loki labels are separately configurable.
|
||||
`/api/status.logging.sinks` reports queue capacity, dropped events, successfully delivered
|
||||
events and sink errors.
|
||||
|
||||
|
||||
+55
-41
@@ -1,58 +1,72 @@
|
||||
# Verification report - RustProxy 0.24.10
|
||||
# Verification report - RustProxy 0.25.0
|
||||
|
||||
## Scope
|
||||
|
||||
RustProxy 0.24.10 implements the Secret Store + password-encrypted full backup/restore and optional ERROR-only file logging specifications. Secret Store adds schema version 7, encrypts ACME DNS-provider credentials with a local master key, migrates legacy provider `.ini` files, and recreates plaintext credential files only around the external Certbot operation. Full backup/restore uses Argon2id plus authenticated AES-256-GCM encryption, an explicit manifest, Secret Store key wrapping, staged validation and atomic data-directory activation. Error-file logging is a separate, disabled-by-default asynchronous bounded sink with JSON/RAW formats, central secret redaction and external `logrotate` rotation.
|
||||
|
||||
The release also retains the 0.24.8 overview cache diagnostics, 0.24.7 transform resource controls and 0.24.6 cache/background-worker memory hardening described by the earlier audit material below.
|
||||
RustProxy 0.25.0 adds a reusable Web Server source while preserving the existing reverse-proxy pipeline. Web Services are independent configuration resources; vhosts and custom locations only choose a source type and reference a Web Service ID. The current development tree provides static GET/HEAD streaming, directory/index behavior, validators, single ranges, document-root confinement, ordered `try_files`, Web Service rewrites, a bounded migration-oriented `.htaccess` compatibility layer, expanded MIME policy, per-extension/MIME Cache-Control rules, fixed source headers, precompressed sidecars, forced-download extensions and optional bounded FastCGI/PHP-FPM. The Web Service editor is organized into General, Routing, .htaccess, MIME, Cache & headers, Delivery, PHP-FPM and Security tabs, with one-shot presets for Static/SPA/PHP/WordPress/Drupal/Laravel/Symfony/Joomla/PrestaShop/Downloads. Existing 0.25 work also includes repeatable directory listing, Web Server vhost-wide metrics, Logging sub-tabs, corrected structured-log source validation, bounded per-vhost Traffic analytics with effective-client-IP rankings/donut charts, User-Agent/optional-country logging, stable Web Service rendering after fast refreshes, generic/customizable 403 handling and automatic RSS relief for reclaimable allocator/HOT-cache memory. The `/docs` surface separates the Markdown Reader from API/OpenAPI and documents the implemented PHP-FPM runtime.
|
||||
|
||||
## Source contracts reviewed
|
||||
|
||||
- SQLite schema version 7 includes the generic encrypted `secret_store` table; stored secret values are AES-256-GCM ciphertext with per-record nonces and the application master key lives outside SQLite in a private file.
|
||||
- Cloudflare, OVH and RFC2136 ACME credentials are validated, imported into Secret Store, decrypted only when required, and legacy provider `.ini` files are removed after successful migration. Certbot credential files are temporary and removed in `finally` paths.
|
||||
- `rust-proxy backup create` writes a new `.rpb` file outside the data directory, derives an independent backup key with Argon2id, encrypts authenticated chunks with AES-256-GCM, excludes cache/log/runtime data and wraps the Secret Store master key inside the encrypted backup.
|
||||
- `rust-proxy backup restore` requires an interactive password, decrypts into private staging, validates manifest/checksums/schema/configuration/Secret Store decryptability before activation, then switches the data directory by rename with rollback on activation failure.
|
||||
- `error_log` is independent from normal access logging, defaults disabled, accepts only `ERROR`, supports JSON/RAW, uses a bounded queue and a single asynchronous writer, handles filesystem failures without terminating RustProxy, and relies on system `logrotate` rather than application rollover.
|
||||
- Error File stays in the existing revisioned `logging` section: its separate dashboard form and the access-log form both save a composite `{ logging, error_log }` value through `/api/config/logging`. A database-reopen regression verifies that `enabled`, path and format survive restart, the standalone `/api/config/error_log` route is intentionally absent, and historical access-only `/api/config/logging` payloads remain accepted for compatibility. The redundant Error Log help sentence is absent from the panel.
|
||||
- The stderr/journald path, access-log sinks and the optional error-file sink share secret-redaction helpers for authorization/provider/password/private-key material.
|
||||
- The KV secret-redaction expression uses a hash-delimited Rust raw string, avoiding the `E0762` unterminated-character-literal parser failure while preserving the same redaction character class.
|
||||
- The release checker preserves the existing dashboard contract while using bundled roots plus common system CA bundles (`SSL_CERT_FILE`, `CURL_CA_BUNDLE`, FreeBSD/OPNsense and Linux paths), follows at most five credential-free HTTP(S) redirects without HTTPS-to-HTTP downgrade, and reports network/TLS/HTTP/parser failures at `ERROR` level so the optional error-file sink receives them.
|
||||
- The overview Cache RAM block keeps separate histories for HOT allocated bytes, transient RAM, fill bytes, COLD queue bytes, COLD I/O bytes and COLD disk bytes; the disk series is never included in process RAM accounting.
|
||||
- HOT and transient histories are rendered against their runtime limits, while COLD storage is rendered against the configured COLD byte budget.
|
||||
- The long `memoryAccountingHint` remains translated and available on demand through the Process information control instead of consuming permanent dashboard height. Response time history is no longer collapsible and has the same compact information control explaining that it charts successive samples of the cumulative mean duration of completed HTTP exchanges.
|
||||
- Transform `preset`, `memory_budget_bytes` and `max_inflight` are part of the normal revisioned Settings document and therefore persist in SQLite; the reopen test covers them.
|
||||
- Existing configurations default to 128 MiB transform temporary memory and 32 concurrent attempts.
|
||||
- New transform attempts use atomic runtime byte/concurrency reservations and fail open with fixed `memory_pressure` / `concurrency_pressure` reasons rather than queueing full-body work.
|
||||
- Presets modify only resource limits; transform type switches and extension allow-lists remain independent.
|
||||
- Global transform representation/eligibility settings participate in cache compatibility identity. Resource-only preset/budget/concurrency fields do not.
|
||||
- OpenAPI and both language packs expose the new controls and preset states.
|
||||
- `GET /api/status` exposes `transform_resources` and `memory_accounting`; the latter keeps process RSS separate from HOT/transient cache accounting and treats transform bytes as an overlapping conservative reservation.
|
||||
- Cache runtime telemetry exposes COLD byte/object limits so the overview can show disk occupancy against configured capacity without mixing disk and RAM.
|
||||
- `GET /api/transform` exposes current process-wide reserved transform bytes and active slots alongside the existing counters.
|
||||
- 0.24.6 aggregate/decode bounds, allocation reductions and bounded cache/background workers remain in place.
|
||||
- The bounded transform-body collection path maps its boxed body error explicitly into `anyhow::Error`; source/release regressions reject the incompatible `.context(...)` form that was reported by an external compiler run.
|
||||
- A subsequent external Rust compile reached warning-only status and reported four lint warnings. The source now keeps the COLD transient read lease explicitly alive via `_read_lease`, names the RAII-only `TransientLease` field `_inner`, and removes the two dead CSS `last_char` assignments without lint suppression. Offline source/release regressions pin those shapes; a compiler-enabled rerun is still required to confirm a warning-clean build.
|
||||
- `Config.web_services` is a separate persisted collection; vhost/location `source` defaults to Reverse Proxy for old documents and Web Server stores only `web_service_id`.
|
||||
- Full configuration compilation validates Web Service IDs, absolute/existing document roots, index names, duplicate IDs and every active Web Service reference. A pure static vhost does not require a backend pool; mixed Web Server and Reverse Proxy locations do.
|
||||
- Web Server dispatch occurs after normal frontend routing, ACL and Basic/Tinyauth authorization and before backend selection/DNS/cache/upstream work. Static responses continue through the existing custom error-page, response-header/security, compression and transport pipeline.
|
||||
- Static files use streamed Tokio file bodies with explicit lengths rather than whole-file buffering.
|
||||
- Files support metadata-based ETag/Last-Modified, If-None-Match/If-Modified-Since, one Range/If-Range and 304/206/416 behavior.
|
||||
- Directory requests redirect to a slash path, then search the optional ordered index list (which may be empty), then optionally render an HTML-escaped and URL-encoded RustProxy-styled listing without exposing filesystem paths.
|
||||
- Root directory listing opens a fresh directory file description per request rather than a `dup` sharing the persistent root descriptor offset; a regression test requests the same listing twice. Nested directories independently apply index lookup first and listing fallback only when no index exists. Generated listings send `Cache-Control: no-store`.
|
||||
- A directory with no matching index and directory listing disabled returns the built-in generic 403 page (or the configured vhost/global 403 replacement in the outer response pass), not a Web Server implementation-detail string. HEAD keeps an empty body.
|
||||
- Web Services support up to 64 normalized MIME overrides, a validated fallback MIME header and an optional validated default `Cache-Control` header. Static files remain backed by the filesystem/OS page cache; existing vhost/location response-header rules run later and can override the source-level cache policy.
|
||||
- Web Services additionally support ordered `ext:`/`mime:` Cache-Control rules, validated fixed response headers, ordered `try_files`, regex internal/redirect rewrites, precompressed `.br`/`.gz` sidecars and attachment extensions. Protected framing/transport headers cannot be overridden by the source header map.
|
||||
- Optional `.htaccess` compatibility compiles a bounded root/subdirectory set at Web Service Apply time rather than parsing per request. It supports common RewriteRule/RewriteCond front controllers, DirectoryIndex/Indexes, AddType, Header, Expires, PHP AddHandler and simple Require all granted/denied. Unsupported access/handler scopes fail closed, `.ht*` control files are never served, and PHP AddHandler requires PHP-FPM.
|
||||
- Web Service presets are UI-only generators: they populate ordinary configuration fields and do not persist a hidden CMS mode. ID/name/document root and PHP-FPM endpoint/tuning remain operator-owned. Optional hardening is persisted explicitly and defaults off for compatibility.
|
||||
- `block_common_attacks` rejects TRACE/CONNECT/TRACK, sensitive dot/control/backup paths and a bounded set of high-confidence exploit probes; it also suppresses FastCGI `HTTP_PROXY` derivation from the inbound `Proxy` header. It does not claim generic WAF/SQLi/XSS filtering.
|
||||
- `strip_unnecessary_headers` removes common source/PHP fingerprint headers after Web Service and `.htaccess` response handling while leaving the later vhost/location response-header pipeline authoritative.
|
||||
- Optional PHP handling executes configured extensions through a bounded FastCGI connector over Unix socket or loopback TCP. PHP concurrency uses a fixed semaphore without an unbounded wait queue, request/response bodies use bounded streaming, and connection failure cannot fall back to serving PHP source. Advanced configuration adds Authorization forwarding control, a streaming request-body ceiling, bounded CGI response headers/stderr, trusted custom FastCGI parameters and validated `PHP_VALUE` overrides that cannot replace core CGI/HTTP fields or `PHP_ADMIN_VALUE`.
|
||||
- Web Service symlink policy defaults to `deny`/`O_NOFOLLOW`; Linux-only `inside_root` verifies opened descriptors through `/proc/self/fd` against the canonical root. PHP-FPM is intentionally limited to `deny` because the external worker reopens `SCRIPT_FILENAME`.
|
||||
- Routing rejects malformed/ambiguous encoded paths before filesystem lookup. Unix filesystem lookup walks from an opened root descriptor; `deny` uses `openat` + `O_NOFOLLOW`, while Linux-only `inside_root` verifies every opened descriptor against the canonical root. PHP-FPM requires `deny`. The secure Web Server compile path remains Unix-only.
|
||||
- No second URL router, custom-error subsystem or object cache was introduced. Reverse Proxy remains the default source for existing configuration.
|
||||
- Dashboard CRUD, source selectors, English/Polish strings and OpenAPI schemas expose the new model.
|
||||
- Web Service index files are optional (0..16). An empty list skips index lookup, allowing directory-listing-only services without synthetic index names.
|
||||
- Generated directory listings use a self-contained RustProxy panel-style layout (matching palette/typography, responsive light/dark treatment and RustProxy footer) while preserving HTML escaping, URL encoding and filesystem-path secrecy.
|
||||
- Pure Web Server vhosts no longer present backend diagnostics as though an origin pool existed; their Backends summary identifies `Web Server`, while mixed static/proxy vhosts retain backend diagnostics.
|
||||
- Status payloads expose fixed-cardinality per-vhost metrics independently of backend pools. The Vhosts dashboard uses those counters for Web Server-only request/active/error values, EWMA latency and byte-rate traffic while retaining backend health details for reverse-proxy sources.
|
||||
- Logging settings are split into Outputs, JSON format and Error log sub-tabs inside one card, matching the Cache subsection layout. `route`, `cache_effective_enabled` and `transform_effective_enabled` are accepted by the same backend validator that saves custom JSON mappings, and the regression test validates then renders those fields.
|
||||
- Structured logging now exposes `user_agent` and `country`. User-Agent capture defaults on; country capture defaults off and GeoIP resolution is skipped unless capture or an existing country ACL/rate-limit needs it.
|
||||
- The authenticated Traffic workspace uses a bounded 2048-sample non-blocking queue, at most 64 vhost buckets and 32-entry approximate top tables for countries, User-Agents, effective client IPs, paths, routes, methods, status classes and cache outcomes. It never writes per-request analytics to SQLite. Countries, User-Agents, client IPs, methods, status classes and cache outcomes also render bounded donut summaries from the same in-memory TOP state.
|
||||
- Sustained-traffic memory maintenance calls `malloc_trim(0)` every 60 seconds on Linux/glibc to release already-free allocator pages and trims HOT objects only when above the configured waterline and idle past the configured age. It does not periodically reload vhosts, purge active objects or reset bounded upstream keep-alive pools.
|
||||
- Cache compatibility currently includes vhost configuration, so a cache-affecting vhost save can purge cache during snapshot publication; replacing the compiled snapshot also retires its upstream clients after outstanding references drain. These mechanisms explain why a manual vhost save can visibly reduce RSS without implying that reloads are required for steady-state operation.
|
||||
- The Web Server list now uses the same vhost card/detail-cell visual structure as the Vhosts list. Reverse Proxy vhost creation reports a dedicated “at least one backend” validation error instead of the generic paths/ACL/headers JSON error.
|
||||
- Web Service cards use only the shared `el(...)` DOM helper; a regression contract rejects the previous undefined `text(...)` call that aborted list rendering. Authenticated-shell startup now verifies `/api/auth/session` first and never reveals the legacy embedded sign-in form for non-authentication JavaScript/API failures, preventing F5 from falsely presenting the user as logged out.
|
||||
- The Web Server UI module performs a catch-up render when it registers after `app.js`; this closes the race where a very fast `/api/config` response could finish before `web-server.js` existed and leave the Web Service list blank until a later render.
|
||||
- The Web Service editor now builds its configuration tabs with the same `vh-tabs` + `quiet` button pattern and active/ARIA state handling as the Vhost editor; the source contract also checks this shared modal-tab pattern and invalid-field navigation switches to the owning tab.
|
||||
- Static dispatch clones only `Method`, `HeaderMap` and `Uri` before awaiting the filesystem source; it does not hold `&Request<Body>` across an await, keeping the Axum 0.8 fallback handler future `Send`. This addresses the reported `Handler<_, _>` / E0277 failure at `.fallback(forward)`.
|
||||
- `/docs` is an authenticated documentation surface with a Markdown Reader, searchable embedded docs bundle and a separate API/OpenAPI tab. Reader Markdown files are direct `include_str!` compiler inputs and no longer depend on a generated `OUT_DIR/docs-content.json`, preventing clean/incremental builds from failing on a missing documentation artifact.
|
||||
- Documentation cleanup keeps README and the active ROADMAP current-only; operator release history, developer-level changelog history and completed roadmap milestones are separated into CHANGELOG/audit/archive documents.
|
||||
|
||||
## Implemented automated coverage
|
||||
|
||||
Rust unit tests in `src/web_server.rs` cover GET/HEAD/index/slash redirect, MIME/length, validators, valid/invalid range handling, If-Range, escaped/repeated directory listings, per-directory index-before-listing fallback, generic 403/HEAD behavior, MIME overrides/default MIME, cache rules, source headers, `try_files`, rewrite redirect/internal behavior, `.htaccess` WordPress-style front-controller routing, nested DirectoryIndex/MIME/Header/Expires behavior, strict-mode rejection and PHP-source protection, hardening probe/method blocking and fingerprint-header stripping, precompressed representations/ranges, download headers, PHP FastCGI fixture execution/failure-source-disclosure behavior, request-body 413 enforcement, custom FastCGI/PHP_VALUE validation and reserved-parameter rejection, direct traversal rejection and Unix/Linux symlink policy. `src/traffic.rs` includes bounded-table and effective-client-IP view coverage. Configuration tests cover pure static vhosts without a pool, mixed Web Server/Reverse Proxy routing, reuse of one Web Service by multiple vhosts, unknown service references and backward-compatible default source behavior. ACL tests include encoded traversal/separator/malformed-encoding cases.
|
||||
|
||||
Rust-independent release checks additionally validate UI/JSON/language/source contracts and reproducible packaging.
|
||||
|
||||
## Verification status in this workspace
|
||||
|
||||
| Check | Status |
|
||||
|---|---|
|
||||
| `python3 scripts/preflight.py` | PASS |
|
||||
| `python3 scripts/langs_check.py` | PASS |
|
||||
| `python3 scripts/docs_check.py` | PASS |
|
||||
| `python3 scripts/memory_contracts.py` | PASS |
|
||||
| Browser JavaScript `node --check` | PASS for all administration JS bundles |
|
||||
| `python3 scripts/web_server_contracts.py` | PASS |
|
||||
| Browser JavaScript `node --check` | PASS for app, Settings, Docs Reader, Web Server, Traffic and vhost administration bundles |
|
||||
| OpenAPI/language JSON parse | PASS |
|
||||
| Shell `bash -n` | PASS |
|
||||
| Python syntax / bytecode compile, including ACME provider worker | PASS |
|
||||
| Secret Store / encrypted backup / error-log / portable update-check source-contract regression checks | PASS |
|
||||
| SQLite schema 7 migration smoke (`secret_store`) | PASS |
|
||||
| Docker agent `go test ./...` / `go vet ./...` / `go build ./...` | PASS |
|
||||
| Shell `bash -n` | PASS in source/release checks |
|
||||
| `go test ./...` in `docker-agent` | PASS |
|
||||
| Python source parsing/contract checks | PASS |
|
||||
| `python3 scripts/check_source.py` | PASS |
|
||||
| `python3 scripts/release_smoke.py` | PASS |
|
||||
| FreeBSD/OPNsense live release-check execution | NOT RUN in this workspace; source contract and platform CA paths are covered, target runtime confirmation is still required |
|
||||
| `./dev.sh fmt` / `cargo fmt --all` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `./dev.sh check` / `cargo check --locked --all-targets` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `./dev.sh test` Rust phase | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| Sustained per-preset transform RSS/heap profiling | release-host acceptance gate |
|
||||
| `./dev.sh test` Rust-independent phases | PASS; Rust phase BLOCKED because Cargo is unavailable |
|
||||
| `cargo fmt --all` / `./dev.sh fmt` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `cargo check --locked --all-targets` / `./dev.sh check` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| `cargo test --locked --all-targets` / Rust phase of `./dev.sh test` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
|
||||
| Live H1/H2/H3 Web Server integration and large-file acceptance | release-host acceptance gate |
|
||||
|
||||
See [V0.24.8_AUDIT.md](V0.24.8_AUDIT.md) for the dashboard change and [V0.24.7_AUDIT.md](V0.24.7_AUDIT.md) for the retained transform resource-control design and runtime acceptance gate.
|
||||
The source package therefore has static/source-contract verification here, but compiler-enabled and live transport acceptance must still be run on the release host before production release.
|
||||
@@ -0,0 +1,19 @@
|
||||
# RustProxy TODO
|
||||
|
||||
This file contains open work that remains after the current RustProxy 0.25 Web Server implementation.
|
||||
|
||||
## Web Server follow-up
|
||||
|
||||
- Multipart byte-range responses if required; current single-range/If-Range support remains the default scope.
|
||||
- Named locations only if they can reuse the existing vhost/location router rather than introduce a second router.
|
||||
- Optional PHP `PATH_INFO` script/path splitting after a confinement-safe rule is defined.
|
||||
- Additional FastCGI observability (bounded active/error/latency counters) without per-script labels.
|
||||
- A race-resistant non-Unix filesystem confinement implementation before enabling the Web Server on non-Unix targets.
|
||||
|
||||
## Release acceptance
|
||||
|
||||
- Run `./dev.sh fmt`, `./dev.sh check` and `./dev.sh test` on a host with the stable Rust toolchain.
|
||||
- Run live static-file acceptance over HTTP/1.1, HTTP/2 and HTTP/3, including ACL/auth/custom-error/header behavior.
|
||||
- Run a real PHP-FPM acceptance matrix over a Unix socket and loopback TCP, including `index.php`, front-controller `try_files`, POST bodies, timeouts and source-disclosure failure tests.
|
||||
|
||||
Completed release work belongs in `CHANGELOG.md`; planned version work belongs in `ROADMAP.md`; implementation/audit evidence belongs in the matching audit document.
|
||||
@@ -0,0 +1,122 @@
|
||||
# RustProxy 0.25.0 specification audit
|
||||
|
||||
This document maps every numbered section of the RustProxy 0.25 plan to the implementation. It distinguishes **implemented source** from **release-host runtime verification**. The workspace used for this package has no Rust/Cargo toolchain, so no compiler or live H1/H2/H3 result is claimed here.
|
||||
|
||||
Status legend:
|
||||
|
||||
- **IMPLEMENTED** - the required source/configuration/UI/documentation exists and Rust-independent contracts pass.
|
||||
- **RELEASE GATE** - implementation exists, but compiler/runtime acceptance still has to run on a Rust-enabled host.
|
||||
|
||||
## Sections 1-22
|
||||
|
||||
| Spec section | Status | Implementation / evidence |
|
||||
|---|---|---|
|
||||
| 1. Goal of 0.25 | IMPLEMENTED | Web Server is integrated as a source in the existing proxy request pipeline rather than as a second HTTP server. |
|
||||
| 2. Target concept | IMPLEMENTED | `CompiledSource` selects Reverse Proxy or Web Server; Reverse Proxy remains the default for old/missing `source` fields. |
|
||||
| 3. Separate Web Service | IMPLEMENTED | `Config.web_services` contains reusable `web_server::Service` objects independent of vhosts. |
|
||||
| 4. Attach service to vhost | IMPLEMENTED | Vhost/location `Source::WebServer` stores only `web_service_id`; filesystem settings remain in the service. |
|
||||
| 5. Full usage flow | IMPLEMENTED | Dashboard workflow is Web Server -> create service -> Vhosts -> select Web Server -> select service. |
|
||||
| 6. Reuse one service | IMPLEMENTED | One Web Service can be referenced by multiple vhosts/locations; a dedicated configuration test covers two vhosts using the same service. |
|
||||
| 7. Locations integration | IMPLEMENTED | Existing location matcher selects static/proxy source; one vhost can mix `/` static and `/api` reverse proxy without a second URL router. |
|
||||
| 8. First-stage configuration | IMPLEMENTED | Model, validation, normal revisioned storage, section API and CRUD UI are present. No SQLite schema migration is needed because the existing serialized configuration document stores `web_services`. |
|
||||
| 9. Static File Server | IMPLEMENTED | GET/HEAD, expanded built-in + per-service MIME, Content-Length, streamed bodies, directories, ordered static/PHP index files, slash redirect, listing, precompressed sidecars and forced-download policy are implemented. |
|
||||
| 10. Directory Listing | IMPLEMENTED | Service-level switch defaults OFF; listing escapes HTML, percent-encodes names/URLs, distinguishes directories and does not reveal filesystem paths. Each request uses a fresh directory description so refreshes do not inherit an exhausted `readdir` offset; generated listings send `Cache-Control: no-store`. Disabled listing returns a normal error that remains eligible for the existing custom-error pipeline. |
|
||||
| 11. Index | IMPLEMENTED | The ordered index list is optional (0..16). Every requested directory checks configured names in order and serves the first regular file; only that directory's empty/no-match result falls through to listing/error policy. |
|
||||
| 12. HTTP validators | IMPLEMENTED | Metadata-derived ETag/Last-Modified and If-None-Match/If-Modified-Since -> 304 are implemented without hashing full files. |
|
||||
| 13. Range | IMPLEMENTED | Single byte Range, If-Range, Accept-Ranges, Content-Range, 206 and 416 are implemented for the selected static/precompressed representation; multipart ranges remain intentionally outside the current scope. |
|
||||
| 14. Filesystem security | IMPLEMENTED | Routing rejects malformed/ambiguous encoding and dot segments. Default Unix access uses `openat` + `O_NOFOLLOW`; Linux can optionally follow a symlink only when each opened descriptor resolves inside the canonical root. PHP-FPM requires the deny policy. |
|
||||
| 15. Existing RustProxy architecture | IMPLEMENTED | Host/location routing, ACL, Basic Auth/Tinyauth, response/security headers, custom error pages, compression and H1/H2/H3 transport stay in the existing outer pipeline. |
|
||||
| 16. Cache | IMPLEMENTED | No Web Server object cache was added. Static files use filesystem/OS page cache and HTTP validators/ranges. Web Services support a default `Cache-Control` plus ordered `ext:`/`mime:` rules; existing vhost/location response-header rules apply later. Reverse Proxy cache remains unchanged. |
|
||||
| 17. Tests | IMPLEMENTED / RELEASE GATE | Rust unit/integration source plus Rust-independent source/UI/docs contracts cover static behavior, configuration, security and integration ordering. Rust tests cannot be executed here without Cargo; live H1/H2/H3 acceptance is still required. |
|
||||
| 18. Future extensibility | IMPLEMENTED | `try_files`, Web Service rewrites, bounded `.htaccess` migration compatibility and bounded FastCGI/PHP-FPM were added without changing the Web Service / source-selection architecture. Remaining follow-up is limited to named locations, optional `PATH_INFO`, multipart Range, full Apache compatibility and non-Unix confinement. |
|
||||
| 19. Documentation cleanup | IMPLEMENTED | `docs/README.md` is canonical; functional, admin/operations, development/testing, technical, audits and historical records are separated. Duplicated historical release notes were removed from README, completed roadmap history was moved to `docs/ROADMAP_HISTORY.md`, and `/docs` embeds the Markdown set in Reader. |
|
||||
| 20. CHANGELOG | IMPLEMENTED | Root CHANGELOG is now operator-facing. Pre-cleanup compiler/refactor/test detail is preserved separately in `docs/CHANGELOG_TECHNICAL_ARCHIVE.md`. |
|
||||
| 21. README / Docs / Reader | IMPLEMENTED | README now describes the current 0.25 release instead of duplicating release history; ROADMAP contains active/future work with completed milestones archived. The docs index, Reader/API split, local Markdown links and current version references are checked automatically. Migration history includes 0.24.10 -> 0.25.0. |
|
||||
| 22. Definition of Done | IMPLEMENTED / RELEASE GATE | All source/documentation items below are implemented; compiler/runtime and live transport acceptance remain the only unexecuted release gate in this workspace. |
|
||||
|
||||
## Definition of Done - item by item
|
||||
|
||||
- [x] Dedicated **Web Server** administration section exists.
|
||||
- [x] Web Service can be created.
|
||||
- [x] Document root is configurable.
|
||||
- [x] Ordered index-file list is configurable.
|
||||
- [x] Directory listing can be enabled/disabled and defaults to disabled.
|
||||
- [x] Web Service can be edited and deleted; referenced deletion is rejected by validation and blocked in the UI.
|
||||
- [x] Existing vhost/source configuration offers `Reverse Proxy` / `Web Server`.
|
||||
- [x] Selecting Web Server offers an existing Web Service reference.
|
||||
- [x] Vhost does not store document root/index/listing copies.
|
||||
- [x] One Web Service can be reused by more than one vhost.
|
||||
- [x] Web Server uses the existing locations system.
|
||||
- [x] One vhost can mix Web Server and Reverse Proxy locations.
|
||||
- [x] GET implemented.
|
||||
- [x] HEAD implemented.
|
||||
- [x] MIME implemented.
|
||||
- [x] Web Service MIME overrides and fallback MIME implemented.
|
||||
- [x] Optional static `Cache-Control` default and ordered extension/MIME cache rules implemented without a second object cache; vhost/location header rules can override them.
|
||||
- [x] Fixed Web Service response headers implemented with framing/transport protections.
|
||||
- [x] `try_files` and ordered internal/redirect rewrite rules implemented inside the selected Web Service.
|
||||
- [x] Bounded `.htaccess` compatibility implemented for common rewrite/front-controller, index/listing, MIME, header, Expires and PHP AddHandler migration rules; security-sensitive unsupported handlers/access scopes fail closed.
|
||||
- [x] Web Service application presets added as one-shot normal-configuration generators (Static, SPA, PHP generic, WordPress, Drupal, Laravel, Symfony, Joomla, PrestaShop, Downloads) with optional explicit hardening for common exploit probes/sensitive paths and fingerprint-header removal.
|
||||
- [x] Precompressed `.br`/`.gz` sidecars and configured forced-download extensions implemented.
|
||||
- [x] FastCGI/PHP-FPM implemented with bounded concurrency/timeouts, Unix socket or loopback TCP endpoints, advanced request/header/stderr limits, Authorization forwarding control, validated custom FastCGI/PHP_VALUE parameters and no PHP source fallback.
|
||||
- [x] Content-Length implemented.
|
||||
- [x] File streaming implemented without loading the whole file into RAM.
|
||||
- [x] Index lookup implemented.
|
||||
- [x] Directory listing implemented.
|
||||
- [x] Repeated directory-listing refreshes use fresh directory offsets; nested directories independently prefer index files before listing.
|
||||
- [x] Directory slash redirect implemented with query preservation.
|
||||
- [x] ETag implemented from metadata.
|
||||
- [x] Last-Modified implemented.
|
||||
- [x] 304 implemented.
|
||||
- [x] Single Range implemented.
|
||||
- [x] 206 implemented.
|
||||
- [x] 416 implemented.
|
||||
- [x] Document-root confinement implemented.
|
||||
- [x] Symlink handling cannot escape the root; deny is the default and Linux can optionally follow only targets verified inside the canonical root. PHP-FPM requires deny.
|
||||
- [x] Web Server uses the existing RustProxy request/response pipeline.
|
||||
- [x] No second URL router was added.
|
||||
- [x] No second error-page subsystem was added.
|
||||
- [x] No second object-cache subsystem was added.
|
||||
- [~] Existing vhost features remain on the shared code path and source contracts verify ordering; full compiler/runtime regression execution is a release-host gate.
|
||||
- [x] Appropriate Rust tests and Rust-independent contract checks are present.
|
||||
- [x] Configuration is stored/read through the existing revisioned configuration store; old configs default to Reverse Proxy.
|
||||
- [x] Documentation has been reorganized.
|
||||
- [x] Docs and Reader are wired to the same embedded Markdown set and API is separated into its own tab.
|
||||
- [x] CHANGELOG has been cleaned of developer-only churn; detailed old material is archived as technical history.
|
||||
- [x] README and ROADMAP describe the actual 0.25 state, historical release/roadmap material is separated into CHANGELOG/audits/archives, and the remaining release-host gate is explicit.
|
||||
|
||||
## Reported Axum E0277 correction
|
||||
|
||||
The reported `.fallback(forward)` error was caused by passing `&Request<Body>` into the asynchronous Web Server function. That shared borrow survived across `.await`; because the body is not `Sync`, the `forward()` future no longer satisfied Axum 0.8's `Send` handler requirement.
|
||||
|
||||
Static dispatch now clones only the request metadata needed by the local filesystem source (`Method`, `HeaderMap`, `Uri`) and moves those owned values into `web_server::serve`. The Web Server no longer holds a shared `Request<Body>` reference across an await. The Rust-independent contract explicitly rejects the former call shape.
|
||||
|
||||
## Reported Reader build-artifact correction
|
||||
|
||||
The Reader initially embedded a generated `OUT_DIR/docs-content.json`. A clean/incremental build could therefore reach `include_bytes!` without that artifact being present. Reader documents are now direct `include_str!` compiler inputs from the project and `docs/` tree; the JSON response is serialized once from those embedded strings. The Reader no longer depends on a generated documentation file in `target/`, and `docs_check.py` verifies that every top-level Markdown document is embedded.
|
||||
|
||||
## Verification performed in this workspace
|
||||
|
||||
- `python3 scripts/check_source.py` - PASS.
|
||||
- `python3 scripts/release_smoke.py` - PASS.
|
||||
- `python3 scripts/memory_contracts.py` - PASS.
|
||||
- `python3 scripts/web_server_contracts.py` - PASS.
|
||||
- `python3 scripts/docs_check.py` - PASS.
|
||||
- `python3 scripts/langs_check.py` - PASS.
|
||||
- `node --check` for app, Settings, Docs Reader, Web Server and vhost administration JavaScript - PASS.
|
||||
- OpenAPI and both language JSON files parse - PASS.
|
||||
- `bash -n dev.sh` - PASS.
|
||||
- `go test ./...` in `docker-agent` - PASS.
|
||||
- `./dev.sh test` - all Rust-independent phases PASS, then exits because `cargo` is not installed in this workspace.
|
||||
|
||||
## Remaining release-host gate
|
||||
|
||||
Before a production release, run on a host with the stable Rust toolchain:
|
||||
|
||||
```bash
|
||||
./dev.sh fmt
|
||||
./dev.sh check
|
||||
./dev.sh test
|
||||
```
|
||||
|
||||
Then run live static-file acceptance over HTTP/1.1, HTTP/2 and HTTP/3, including ACL/auth/custom-error/header behavior and a large streamed file. This is verification work, not a missing source feature.
|
||||
@@ -0,0 +1,131 @@
|
||||
# RustProxy 0.25.0 pre-production security audit
|
||||
|
||||
Date: 2026-10-04
|
||||
|
||||
This audit is a source/configuration/dependency review of the current 0.25.0 development tree. It is **not** a completed penetration test because the audit environment has no Rust/Cargo toolchain and therefore cannot build or start the RustProxy binary. Production acceptance remains blocked until the runtime gates at the end of this document are executed on an isolated release host.
|
||||
|
||||
## Result
|
||||
|
||||
No source-reviewed issue remains that is known to provide an unauthenticated direct path to RustProxy process takeover. Additional runtime/fuzzing gates remain open, so this is not production approval. Concrete pre-production issues found during this review were fixed in the same 0.25.0 development tree:
|
||||
|
||||
1. The Debian one-line bootstrap and reference unit exposed plain-HTTP administration on `0.0.0.0:9090` by default. They now default to `127.0.0.1:9090`; plain remote HTTP requires explicit opt-in and Administration HTTPS remains the preferred remote mode.
|
||||
2. Recursive source packaging could include a local `scripts/.../.env`. Exact `.env` files are now excluded from release archives while `.env.example` templates remain included.
|
||||
3. FastCGI `HTTP_PROXY`/httpoxy protection depended on optional Web Service hardening. Client `Proxy` is now unconditionally discarded before FastCGI parameter generation.
|
||||
4. PHP-FPM CGI output could supply downstream framing headers. `Content-Length`, transfer/connection framing, TE/Trailer and `Proxy-*` transport headers are now discarded so RustProxy owns downstream framing.
|
||||
5. `.htaccess` compatibility could read a symlinked control file during Apply. `.htaccess` files are now opened with no-follow semantics, symlink control files are rejected and recursive discovery verifies that scanned directories remain below the canonical Web Service root.
|
||||
6. PHP-FPM CGI `Status:` accepted informational codes such as `101`. FastCGI output is now restricted to final HTTP status codes `200..=599`, preventing an external PHP worker from trying to drive protocol-switch semantics through the normal HTTP response path.
|
||||
7. The Debian unit used `UMask=0027`; it is now `0077`, matching the reference installer unit so newly created process files default to owner-only access.
|
||||
8. Web Service CMS presets previously changed only the preset description until the separate Apply button was pressed. Selecting a non-Custom preset now immediately materializes the ordinary form fields, and a behavioral JS regression test verifies that WordPress index/`try_files`/PHP/cache values survive the Save serialization path.
|
||||
|
||||
The reference/generated systemd units were also aligned with the stronger Debian sandbox baseline (`PrivateDevices`, `ProtectKernelLogs`, namespace/realtime restrictions and native syscall architecture).
|
||||
|
||||
## Tests executed
|
||||
|
||||
Passed in the audit environment:
|
||||
|
||||
- `python3 scripts/check_source.py`
|
||||
- `python3 scripts/web_server_contracts.py`
|
||||
- `python3 scripts/security_contracts.py`
|
||||
- `python3 scripts/security_dependency_contracts.py` (offline minimum-version gates for RustSec items reviewed on 2026-10-04)
|
||||
- `node scripts/web_service_ui_test.mjs` (preset selection + Save serialization regression)
|
||||
- `python3 scripts/memory_contracts.py`
|
||||
- `python3 scripts/docs_check.py`
|
||||
- `python3 scripts/langs_check.py`
|
||||
- `python3 scripts/release_smoke.py`
|
||||
- `node --check` for all administration JavaScript
|
||||
- `bash -n` for managed shell scripts
|
||||
- `go test ./...` for `docker-agent`
|
||||
- deterministic source archive generation plus assertion that no exact `.env` is packaged
|
||||
- `systemd-analyze security --offline=yes` for the reference and Debian units: exposure score 3.3 (`OK`) in the audit environment; both now use `UMask=0077`
|
||||
- targeted source review of administration authentication/CSRF/Host-Origin handling, backend SSRF/address policy, HTTP framing limits, Web Server path confinement, `.htaccess`, PHP-FPM, backup/secret storage, command execution and unsafe/FFI surfaces
|
||||
- hard-coded secret scan for common private-key/token patterns: no production secret found; documentation placeholders only
|
||||
- manual review of the locked major network/security dependencies against current RustSec advisories, plus an offline regression deny-list for the reviewed 2026 malicious-crate campaign
|
||||
|
||||
`./dev.sh test` runs every non-Rust phase successfully and then stops because `cargo/rustc` are unavailable. `scripts/admin_audit.py` was also attempted, but no compiled/running RustProxy administration listener exists in this workspace, so its live probes are **blocked/unexecuted**, not passed.
|
||||
|
||||
## Dependency review
|
||||
|
||||
Important locked versions reviewed manually:
|
||||
|
||||
- `rustls 0.23.45` - includes the fix for RUSTSEC-2026-0285 (`>=0.23.45`)
|
||||
- `rustls-webpki 0.103.15` - above the RUSTSEC-2026-0104 fix (`>=0.103.13`)
|
||||
- `quinn-proto 0.11.18` - above RUSTSEC-2026-0037 (`>=0.11.14`) and RUSTSEC-2026-0185 (`>=0.11.15`) fixes
|
||||
- `h2 0.4.19` - above the RUSTSEC-2026-0258 fix (`>=0.4.16`)
|
||||
- `bytes 1.12.1` - above the RUSTSEC-2026-0007 fix (`>=1.11.1`)
|
||||
- `time 0.3.55` - above the RUSTSEC-2026-0009 fix (`>=0.3.47`)
|
||||
- `sqlx 0.8.6` - above the RUSTSEC-2024-0363 fix (`>=0.8.1`)
|
||||
- `tungstenite 0.29.0` - above the historical RUSTSEC-2023-0065 fix (`>=0.20.1`)
|
||||
- `ring 0.17.14` - above the RUSTSEC-2025-0009 fix (`>=0.17.12`)
|
||||
|
||||
This manual review is not a substitute for `cargo audit`/OSV scanning of the complete resolved graph on the release host.
|
||||
|
||||
## Security boundaries reviewed
|
||||
|
||||
### Administration
|
||||
|
||||
- default bind is loopback; persisted non-loopback configuration requires Administration TLS;
|
||||
- private routes require a browser session; mutations additionally require exact Origin, `X-RustProxy-Request: 1` and a session-bound CSRF token;
|
||||
- cookies are HttpOnly/SameSite=Strict and become Secure on Administration HTTPS;
|
||||
- passwords use Argon2id and password work has bounded workers;
|
||||
- unknown users receive equivalent password-verification work;
|
||||
- certificate API credentials are scoped and require HTTPS for non-loopback requests.
|
||||
|
||||
Residual operational risks: browser sessions can be configured for 7-30 days, there is no 2FA/role model yet, and the global login throttle can be used for availability lockout if a remote admin listener is exposed. Keep administration private or tightly firewalled and use the shortest session lifetime for production.
|
||||
|
||||
### Backend SSRF / routing
|
||||
|
||||
- backend origins are HTTP/HTTPS only;
|
||||
- metadata/link-local/special targets remain blocked; private/loopback addresses require explicit opt-in;
|
||||
- local RustProxy listener targeting has an additional explicit risk gate;
|
||||
- DNS answers are validated before use and a validated address is used without a second DNS lookup.
|
||||
|
||||
Production requirement: enable `tls_verify=true` for HTTPS origins whenever the backend network is not fully trusted. Verification-off remains a deliberate compatibility default and permits an on-path attacker to impersonate that origin.
|
||||
|
||||
### Web Server / filesystem
|
||||
|
||||
- decoded and encoded traversal/separator ambiguity is rejected;
|
||||
- Unix file access uses document-root descriptors and `openat`; default symlink policy uses `O_NOFOLLOW`;
|
||||
- only regular files/directories are served; PHP source extensions are denied when PHP-FPM is unavailable;
|
||||
- `.ht*` files are protected; `.htaccess` parsing is bounded, control files are opened/rejected with no-follow symlink handling, and unsupported access/handler directives fail closed;
|
||||
- directory listings re-open entries through the same confinement rules.
|
||||
|
||||
### PHP-FPM
|
||||
|
||||
FastCGI is restricted to Unix sockets or loopback TCP, script selection is rooted in the Web Service document root and symlink-following PHP mode is rejected. Client `Proxy` cannot create CGI `HTTP_PROXY`; CGI response framing cannot override RustProxy downstream framing, and informational/101 CGI statuses are rejected. Operator-defined FastCGI parameters cannot override core CGI/HTTP fields or `PHP_VALUE`/`PHP_ADMIN_VALUE`; php.ini overrides use a separate validated `PHP_VALUE` map. Optional request-body, response-header and stderr limits bound PHP connector resource usage.
|
||||
|
||||
The most important production boundary is external to RustProxy: run each PHP-FPM pool as a dedicated non-root, non-`rustproxy` user. A compromised CMS/plugin must not be able to read `/var/lib/rustproxy`, SQLite, the Secret Store, TLS keys or backups. Separate writable upload directories from executable PHP source where the application permits it.
|
||||
|
||||
|
||||
### Build / update supply chain
|
||||
|
||||
The one-line Debian bootstrap uses HTTPS but clones the moving repository head and then invokes repository deployment scripts with root privileges. That is convenient for development but is not a strong production provenance boundary: compromise of the repository/default branch at install time would become host compromise. Production installation should use a reviewed immutable commit/tag or the audited source archive, verify its SHA-256 out of band, build with `--locked` as an unprivileged builder, and only then run the reviewed installation step. The exact `.env` files are excluded from generated source archives.
|
||||
|
||||
### Resource / protocol DoS
|
||||
|
||||
- public connection and inflight request counts are bounded;
|
||||
- HTTP/1 header count/buffer and header-read time are bounded;
|
||||
- HTTP/2 concurrent streams/header list/windows and connection lifetime/drain controls are bounded;
|
||||
- WebSocket connections retain the public connection lease and have inactivity limits;
|
||||
- FastCGI concurrency/timeouts and traffic analytics queues/cardinality are bounded;
|
||||
- cache/transformation background work has bounded queues/permits.
|
||||
|
||||
A real hostile load test is still required before production because source bounds do not prove allocator/kernel behavior under mixed H1/H2/H3/WebSocket/PHP traffic.
|
||||
|
||||
One residual DoS gap is intentionally recorded rather than hidden: RustProxy currently streams request bodies but has no general per-vhost/location byte ceiling equivalent to `client_max_body_size`. Connection/inflight/body-idle/FastCGI timeout bounds prevent an unbounded in-process request-body buffer, but a client can still spend bandwidth and backend/PHP upload resources with a very large body. Before exposing public CMS upload endpoints, set conservative PHP/application limits (`post_max_size`, `upload_max_filesize`) and add/test a RustProxy request-body byte limit.
|
||||
|
||||
## Production blockers / release-host gates
|
||||
|
||||
Do not treat this audit as production approval until all of these pass on the exact release artifact:
|
||||
|
||||
1. Install stable Rust/Cargo and run `./dev.sh doctor`, `./dev.sh check`, `./dev.sh test`, `cargo test --locked` and a release build.
|
||||
2. Run `cargo audit` (and preferably OSV/Trivy or equivalent) against the exact `Cargo.lock`; resolve vulnerabilities and review unmaintained/yanked transitive crates.
|
||||
3. Start the exact release binary under the target systemd unit and run `scripts/admin_audit.py` against loopback.
|
||||
4. Run active malformed HTTP tests for duplicate/ambiguous framing, oversized headers, slow headers/bodies, oversized request bodies, H2/H3 stream floods, WebSocket idle/connection exhaustion and Range edge cases.
|
||||
5. Fuzz/property-test `routing_path`, rewrite/`try_files`, `.htaccess`, CGI header parsing and backup restore parsers.
|
||||
6. Run filesystem escape tests using symlink races, nested links, renames and mount/bind-mount edge cases on the production kernel/filesystem.
|
||||
7. Exercise a real PHP-FPM pool with hostile headers/body sizes, disconnects, timeouts and an intentionally compromised test PHP application; verify that the PHP user cannot read RustProxy private state.
|
||||
8. Perform sustained mixed-protocol load/soak testing while monitoring RSS, FDs, tasks, cache memory and latency.
|
||||
9. Verify firewall policy: public only intended frontend TCP/UDP ports; admin 9090 loopback/private only unless Administration HTTPS is intentionally exposed; PHP-FPM never public. For CMS uploads, enforce tested request-body limits in PHP/application and preferably RustProxy before public launch.
|
||||
10. Back up and restore on an isolated host, then rotate/revoke restored sessions and credentials.
|
||||
|
||||
Until those runtime gates pass, status remains **pre-production / runtime security verification open**.
|
||||
+8
-5
@@ -1,15 +1,17 @@
|
||||
> 0.7 adds graphical locations, Basic Auth, cumulative IP ACL editing and a
|
||||
> WebSocket toggle. See [host access and locations](VHOST_ACCESS.md).
|
||||
|
||||
# Virtual hosts, frontend bindings and backend pools - 0.2.0
|
||||
# Virtual hosts, frontend bindings and backend pools
|
||||
|
||||
This is the source implementation contract. Rust compilation and runtime acceptance
|
||||
were not performed in the packaging environment; see TEST_REPORT.md.
|
||||
|
||||
## One vhost, one backend pool
|
||||
|
||||
A `vhosts` entry owns an `id`, `enabled`, `frontend`, `backends`, `load_balancing`,
|
||||
`routes`, optional `acl`, `headers` and `security_headers`. The pre-production top-level
|
||||
A `vhosts` entry owns an `id`, `enabled`, `frontend`, `source`, `backends`, `load_balancing`,
|
||||
`routes`, optional `acl`, `headers` and `security_headers`. `source` defaults to Reverse Proxy
|
||||
for older documents; it can instead reference an independently configured Web Service. See
|
||||
[WEB_SERVER.md](WEB_SERVER.md). The pre-production top-level
|
||||
routing and inline-listener formats are no longer accepted. Unknown JSON fields are
|
||||
rejected. The examples are complete documents, not JSON merge patches:
|
||||
|
||||
@@ -126,8 +128,9 @@ still validated, but create no pool or additional active listener.
|
||||
|
||||
## Paths, policies and migration
|
||||
|
||||
`routes` contains per-vhost paths: `id`, `path_prefix`, `enabled`, nullable `cache`,
|
||||
optional `acl`, `headers` and `backend_id`. An empty array becomes one enabled root route. Longest
|
||||
`routes` contains per-vhost paths: `id`, `path_prefix`, `enabled`, `source`, nullable `cache`,
|
||||
optional `acl`, `headers` and `backend_id`. `source` selects Reverse Proxy or a reusable Web Service;
|
||||
`backend_id` is valid only for Reverse Proxy. An empty array leaves the main vhost source as the fallback. Longest
|
||||
segment-boundary prefix wins. Origins receive the original path/query; prefixes
|
||||
are not stripped. IDs must use ASCII letters, digits, hyphens and underscores.
|
||||
Host-policy, reusable ACL-profile, vhost and route ACLs are ANDed before pool
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
# Web Server - RustProxy 0.25
|
||||
|
||||
RustProxy 0.25 provides a Web Server source inside the existing vhost/location pipeline. A Web Service is a reusable configuration resource; vhosts and locations select it by ID and do not duplicate filesystem/PHP settings.
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
listener -> vhost -> location -> shared ACL/auth/policy
|
||||
-> source
|
||||
|- Reverse Proxy
|
||||
`- Web Server -> Web Service
|
||||
|- static file
|
||||
`- FastCGI -> PHP-FPM
|
||||
-> shared response/error/header/compression pipeline
|
||||
```
|
||||
|
||||
A Web Service can be reused by several vhosts and one vhost can mix Web Server and Reverse Proxy locations. Web Services live in the normal revisioned RustProxy configuration (`web_services`); there is no separate Web Server configuration database.
|
||||
|
||||
## Dashboard configuration
|
||||
|
||||
The Web Service editor is split into stable configuration tabs so later features do not create one long form:
|
||||
|
||||
- **General** - optional one-shot application preset, ID, name, document root, ordered index files, directory listing and quick hardening switches.
|
||||
- **Routing** - `try_files` and Web Service rewrite rules.
|
||||
- **.htaccess** - bounded migration-oriented Apache compatibility, recursive scan and strict-mode behavior.
|
||||
- **MIME** - per-extension MIME overrides and fallback MIME type.
|
||||
- **Cache & headers** - default `Cache-Control`, ordered cache rules and fixed response headers.
|
||||
- **Delivery** - precompressed `.br`/`.gz` sidecars, forced-download extensions and Range/streaming information.
|
||||
- **PHP-FPM** - Unix/loopback-TCP endpoint, executable extensions, connect/request timeout, bounded concurrency, Authorization forwarding, request/header/stderr limits, custom FastCGI parameters and controlled `PHP_VALUE` overrides.
|
||||
- **Security** - symlink policy, request/response hardening summary and filesystem-confinement notes.
|
||||
|
||||
After the Web Service is saved, attach it under **Vhosts** by selecting `Web Server` and the service ID for the main source or a custom location.
|
||||
|
||||
### Application presets
|
||||
|
||||
The editor provides one-shot presets for **Static site, SPA, PHP generic, WordPress, Drupal, Laravel, Symfony, Joomla, PrestaShop and Downloads/file repository**. Applying a preset writes normal Web Service fields; it does not store a hidden CMS mode and every generated field remains editable. Service ID/name, document root and the deployment-specific PHP-FPM endpoint/tuning are preserved. Laravel/Symfony operators should point `document_root` at the application's `public/` directory.
|
||||
|
||||
The preset control also exposes two independent hardening switches. They are saved as normal Web Service configuration and remain active even after the generated preset settings are edited manually.
|
||||
|
||||
## Configuration example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "main-site",
|
||||
"name": "Main site",
|
||||
"document_root": "/var/www/main",
|
||||
"index": ["index.html", "index.php"],
|
||||
"directory_listing": false,
|
||||
"htaccess": {
|
||||
"enabled": true,
|
||||
"filename": ".htaccess",
|
||||
"scan_subdirectories": true,
|
||||
"strict": false
|
||||
},
|
||||
"try_files": ["$uri", "$uri/", "/index.php?$query_string"],
|
||||
"rewrites": [
|
||||
{"pattern": "^/old/(.*)$", "replacement": "/new/$1", "status": 301}
|
||||
],
|
||||
"mime_types": {"avif": "image/avif"},
|
||||
"default_mime_type": "application/octet-stream",
|
||||
"cache_control": "public, max-age=3600",
|
||||
"cache_rules": [
|
||||
{"matcher": "ext:html", "cache_control": "no-cache"},
|
||||
{"matcher": "mime:image/", "cache_control": "public, max-age=604800"}
|
||||
],
|
||||
"response_headers": {"x-content-type-options": "nosniff"},
|
||||
"precompressed": {"enabled": true, "brotli": true, "gzip": true},
|
||||
"download_extensions": ["zip", "iso"],
|
||||
"symlink_policy": "deny",
|
||||
"hardening": {
|
||||
"block_common_attacks": true,
|
||||
"strip_unnecessary_headers": true
|
||||
},
|
||||
"php": {
|
||||
"enabled": true,
|
||||
"extensions": ["php"],
|
||||
"endpoint": "unix:/run/php/php-fpm.sock",
|
||||
"connect_timeout_ms": 1000,
|
||||
"request_timeout_ms": 30000,
|
||||
"max_concurrent_requests": 64
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Older configurations remain compatible because all newly added settings have safe defaults.
|
||||
|
||||
## Request routing inside a Web Service
|
||||
|
||||
The outer vhost/location router always runs first. Inside the selected Web Service the file-serving sequence is:
|
||||
|
||||
1. validate and decode the already-selected public path;
|
||||
2. apply configured Web Service rewrite rules in order;
|
||||
3. apply the compiled `.htaccess` rewrite subset when enabled;
|
||||
4. resolve `try_files` candidates when configured;
|
||||
5. open the selected filesystem object within the document-root boundary;
|
||||
6. execute configured PHP extensions through PHP-FPM or serve a static file;
|
||||
7. for a directory, redirect to the slash form if required, then test the effective index list;
|
||||
8. if no index exists, generate directory listing when effectively enabled or return the normal customizable 403 response.
|
||||
|
||||
This is Web Service file resolution, not a replacement for vhost/location routing.
|
||||
|
||||
### `try_files`
|
||||
|
||||
One candidate is configured per line. Supported substitutions are `$uri` and `$query_string`.
|
||||
|
||||
Example for an SPA:
|
||||
|
||||
```text
|
||||
$uri
|
||||
$uri/
|
||||
/index.html
|
||||
```
|
||||
|
||||
Example for a PHP front controller:
|
||||
|
||||
```text
|
||||
$uri
|
||||
$uri/
|
||||
/index.php?$query_string
|
||||
```
|
||||
|
||||
A final `=4xx`/`=5xx` candidate can return an error status, for example `=404`. Non-final candidates are tested for existence; the final path candidate is the fallback target.
|
||||
|
||||
### Rewrite rules
|
||||
|
||||
Rules use a regular-expression pattern and a replacement path. The replacement must start with `/`.
|
||||
|
||||
- without a status: internal rewrite;
|
||||
- with `301`, `302`, `307` or `308`: client redirect.
|
||||
|
||||
The current query string is retained unless the replacement supplies its own query. Rewritten paths still pass normal Web Server path validation and filesystem confinement.
|
||||
|
||||
## `.htaccess` compatibility
|
||||
|
||||
RustProxy implements a **bounded compatibility subset for migration**, not a complete Apache runtime. The files are read and compiled when the Web Service is validated/saved/applied. They are **not parsed on every request**. After changing `.htaccess` on disk, apply the Web Service again.
|
||||
|
||||
Supported directives in 0.25 development:
|
||||
|
||||
- `RewriteEngine`, `RewriteBase`, `RewriteCond`, `RewriteRule`;
|
||||
- `DirectoryIndex`;
|
||||
- `Options +Indexes`, `Options -Indexes` and the common `-MultiViews` no-op;
|
||||
- `AddType`;
|
||||
- `AddHandler` when the handler is PHP-related;
|
||||
- `Header set`, `Header add`, `Header unset`, including `always`/`onsuccess`;
|
||||
- `ExpiresActive`, `ExpiresDefault`, `ExpiresByType`;
|
||||
- `Require all granted` / `Require all denied` outside `Files` blocks.
|
||||
|
||||
Rewrite compatibility covers the common front-controller patterns used by WordPress/Laravel-style deployments. Conditions can inspect `REQUEST_FILENAME` with `-f`, `-d` and `-s`, plus `REQUEST_URI`, `REQUEST_METHOD`, `QUERY_STRING`, `HTTP_HOST`, `HTTPS`, `REQUEST_SCHEME`, `DOCUMENT_ROOT`, `THE_REQUEST`, selected server/client variables and request headers. Supported rewrite flags are `L`, `END`, `R`, `R=301/302/307/308`, `QSA`, `NC`, `F` and condition `OR`. `PT`/`NE` are accepted as no-ops. `E=` is accepted as a compatibility no-op because HTTP request headers are already forwarded to PHP-FPM.
|
||||
|
||||
Example front controller:
|
||||
|
||||
```apache
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.php [L]
|
||||
```
|
||||
|
||||
`DirectoryIndex`, `Options ±Indexes`, MIME, header and Expires directives are scoped by the directory containing the compiled `.htaccess`. Subdirectory files can therefore override the effective index/listing/MIME/header/cache behavior for their subtree when recursive scanning is enabled.
|
||||
|
||||
PHP remains intentionally controlled by RustProxy: `AddHandler` may extend the set of PHP file extensions, but the PHP-FPM endpoint, timeouts and concurrency are configured only in the Web Service PHP-FPM tab. Apache `SetHandler` socket/proxy syntax cannot choose an arbitrary FastCGI endpoint.
|
||||
|
||||
The compatibility scanner is bounded to 128 files, depth 16, 128 KiB per file and 1 MiB total. Symlinked directories are not traversed. `.htaccess`, `.htpasswd` and `.ht*` control files are blocked from HTTP delivery. Unsupported non-security directives are logged and ignored by default; **Strict** mode rejects them instead. General `Files`/`FilesMatch`, unsupported authentication/authorization directives, non-PHP handlers and `SetHandler` are rejected even with Strict off because ignoring them could weaken access control or expose source. `ErrorDocument`, `SetEnvIf`, `Redirect`/`RedirectMatch` and `FallbackResource` are not part of this subset. Existing RustProxy vhost/location ACL, authentication, custom error pages and response rules remain authoritative.
|
||||
|
||||
## Index and directory behavior
|
||||
|
||||
`index` is an ordered list and can contain static files and, when PHP is enabled, `index.php`. For every requested directory RustProxy checks the list from the beginning. If no configured index exists, directory listing is used only when enabled.
|
||||
|
||||
Directory listing is disabled by default. A generated listing:
|
||||
|
||||
- opens a fresh directory handle for every request, so repeated refreshes remain correct;
|
||||
- HTML-escapes names and percent-encodes URL path segments;
|
||||
- distinguishes files/directories without revealing local filesystem paths;
|
||||
- sends `Cache-Control: no-store`.
|
||||
|
||||
If listing is disabled and no index exists, RustProxy returns the standard generic `403 Access denied` response. Existing vhost/global custom error pages may replace it.
|
||||
|
||||
## MIME handling
|
||||
|
||||
Static `Content-Type` is selected in this order:
|
||||
|
||||
1. Web Service extension override;
|
||||
2. built-in MIME table;
|
||||
3. `default_mime_type` (default `application/octet-stream`).
|
||||
|
||||
The built-in table covers common HTML/CSS/JS/data formats, archives, images, audio/video, fonts and common Office file formats. Extension override keys are normalized to lowercase without a leading dot.
|
||||
|
||||
## Cache policy and Web Service headers
|
||||
|
||||
RustProxy still does **not** add a second object cache for local files. Static content uses filesystem/OS page cache, validators and normal HTTP client/intermediary caching.
|
||||
|
||||
A Web Service can define:
|
||||
|
||||
- default `Cache-Control`;
|
||||
- ordered `cache_rules` using `ext:<extension>` or `mime:<prefix>`;
|
||||
- fixed response headers.
|
||||
|
||||
Rules are evaluated before the default. Example:
|
||||
|
||||
```text
|
||||
ext:html = no-cache
|
||||
mime:image/ = public, max-age=604800, immutable
|
||||
```
|
||||
|
||||
Vhost/location response-header rules still execute later in the shared pipeline and can impose URL-specific policy. Framing/transport headers such as `Content-Length`, `Content-Encoding`, `Content-Range`, `Transfer-Encoding`, connection headers and `Vary` cannot be replaced by Web Service fixed headers.
|
||||
|
||||
## Precompressed static files
|
||||
|
||||
Optional precompressed delivery checks sidecar files only after the original resource has been resolved safely:
|
||||
|
||||
- `file.js.br` for Brotli;
|
||||
- `file.js.gz` for gzip.
|
||||
|
||||
The client must advertise the matching coding in `Accept-Encoding`. Brotli is preferred when both are available. The response keeps the original file's MIME type and adds the appropriate `Content-Encoding` and `Vary: Accept-Encoding`.
|
||||
|
||||
Validators, streaming and a single Range request operate on the selected representation. RustProxy does not compress the file on every request in this mode.
|
||||
|
||||
## Range and downloads
|
||||
|
||||
Static and precompressed responses support:
|
||||
|
||||
- single `Range: bytes=...`;
|
||||
- `If-Range`;
|
||||
- `206 Partial Content`;
|
||||
- `416 Range Not Satisfiable`;
|
||||
- `Accept-Ranges` and `Content-Range`;
|
||||
- streaming rather than whole-file buffering.
|
||||
|
||||
Multipart ranges remain intentionally unsupported.
|
||||
|
||||
Configured `download_extensions` add `Content-Disposition: attachment` using an encoded filename. This is useful for storage/download services without changing the MIME type.
|
||||
|
||||
## Validators
|
||||
|
||||
Static files emit metadata-based `ETag` and `Last-Modified` and handle `If-None-Match` / `If-Modified-Since` with `304 Not Modified`. Large files are not hashed on each request.
|
||||
|
||||
## PHP-FPM / FastCGI
|
||||
|
||||
PHP execution is optional per Web Service. RustProxy speaks FastCGI directly to a long-running PHP-FPM process; it never starts `php`, `php-cgi` or a shell command per request.
|
||||
|
||||
Supported endpoint forms:
|
||||
|
||||
```text
|
||||
unix:/run/php/php-fpm.sock
|
||||
tcp:127.0.0.1:9000
|
||||
tcp:[::1]:9000
|
||||
```
|
||||
|
||||
TCP endpoints are deliberately restricted to literal loopback addresses. The connector has explicit connect/request timeouts and a bounded semaphore. If all PHP execution slots are busy the request receives `503`; connection failures/timeouts become gateway errors and PHP source is never returned as a fallback.
|
||||
|
||||
The PHP-FPM tab also exposes an optional streaming request-body limit (`0` means no additional RustProxy limit), response-header and stderr bounds, an Authorization-forwarding switch, static custom FastCGI parameters and php.ini-style `PHP_VALUE` overrides. Custom parameters use `NAME = value` per line; PHP settings use `directive = value` per line. Core CGI/HTTP/PHP control parameter names cannot be overridden. The in-panel **FastCGI syntax and safety** dialog contains the exact syntax and examples.
|
||||
|
||||
Configured PHP extensions are executable rather than downloadable source. `index.php` and `try_files` front-controller patterns use the same Web Service root and path validation. See [PHP_FPM.md](PHP_FPM.md) for the operator/runtime details.
|
||||
|
||||
## Optional Web Service hardening
|
||||
|
||||
`hardening.block_common_attacks` is a deterministic high-confidence protection layer for the local Web Server. It is **not a generic WAF** and deliberately avoids broad SQL-injection/XSS regex matching that would create application false positives. When enabled it:
|
||||
|
||||
- denies TRACE, CONNECT and TRACK at the Web Service source;
|
||||
- blocks hidden dot/control paths except `.well-known`;
|
||||
- blocks common secret/configuration targets such as `.env`, `wp-config.php`, Joomla `configuration.php`, Drupal `settings.php`, Composer auth/config metadata and private-key file names;
|
||||
- blocks common backup/database suffixes (`.bak`, `.old`, `.sql`, `.sqlite`, `.db`, editor swap files and `~` backups);
|
||||
- blocks high-confidence exploit-probe paths such as exposed PHPUnit `eval-stdin`, Laravel Ignition execute-solution, Apache server-status/server-info and `cgi-bin`;
|
||||
- suppresses the incoming `Proxy` header when building FastCGI parameters, mitigating the CGI/FastCGI `HTTP_PROXY`/httpoxy class.
|
||||
|
||||
Existing decoded-path/traversal validation, document-root confinement, `.ht*` protection, vhost ACL/authentication and PHP source protection continue to run independently of this switch. A denied hardening request uses the normal customizable 403 pipeline.
|
||||
|
||||
`hardening.strip_unnecessary_headers` removes common implementation/fingerprint response headers after Web Service and `.htaccess` response processing: `Server`, `X-Powered-By`, ASP.NET version headers, `X-Runtime`, `X-Generator` and Drupal cache fingerprints. Vhost/location response rules run later and can intentionally add an operator-controlled header if required.
|
||||
|
||||
## Filesystem security and symlinks
|
||||
|
||||
The request path rejects malformed encoding, encoded separators, backslashes, control characters and `.`/`..` traversal before filesystem access.
|
||||
|
||||
On Unix, filesystem lookup starts from an opened document-root descriptor and walks relative components with `openat`.
|
||||
|
||||
Two symlink policies are available:
|
||||
|
||||
- `deny` (default) - every path component is opened with `O_NOFOLLOW`; symlinks are rejected.
|
||||
- `inside_root` - Linux-only; symlinks may be followed only when the opened descriptor resolves back inside the canonical document root through `/proc/self/fd` verification after every component.
|
||||
|
||||
`inside_root` is not available with PHP-FPM in 0.25 because PHP-FPM reopens `SCRIPT_FILENAME` itself. PHP therefore requires the safer `deny` policy.
|
||||
|
||||
The secure Web Server implementation remains Unix-only until an equivalent race-resistant confinement implementation exists for non-Unix systems.
|
||||
|
||||
## Shared RustProxy pipeline
|
||||
|
||||
Web Server dispatch occurs after the existing vhost/location selection and access controls. Responses continue through the existing common mechanisms, including:
|
||||
|
||||
- ACL, authentication and authorization;
|
||||
- rate/access policy;
|
||||
- vhost/location custom and security headers;
|
||||
- custom error pages;
|
||||
- access logging and per-vhost Traffic metrics;
|
||||
- response processing/compression where applicable;
|
||||
- TLS and existing HTTP/1.1, HTTP/2 and HTTP/3 listeners.
|
||||
|
||||
A local Web Server request does not create a reverse-proxy backend connection. WebSocket upgrades remain unsupported for a Web Server source.
|
||||
|
||||
## Validation limits
|
||||
|
||||
Current configuration limits include:
|
||||
|
||||
- index files: maximum 16;
|
||||
- MIME overrides: maximum 64;
|
||||
- cache rules: maximum 64;
|
||||
- fixed Web Service headers: maximum 32;
|
||||
- `try_files`: maximum 16 candidates;
|
||||
- rewrites: maximum 32 rules;
|
||||
- download extensions: maximum 64;
|
||||
- PHP extensions: maximum 16;
|
||||
- PHP concurrency: 1..4096;
|
||||
- PHP connect timeout: 50..60000 ms;
|
||||
- PHP request timeout: 100..3600000 ms;
|
||||
- `.htaccess`: maximum 128 files, depth 16, 128 KiB per file and 1 MiB total.
|
||||
|
||||
Document root must be absolute, exist and be a directory at configuration compile time. References to unknown Web Services are rejected and deletion of a referenced service is blocked/caught by validation.
|
||||
|
||||
## Remaining follow-up
|
||||
|
||||
The current implementation intentionally leaves multipart Range, named locations, `PATH_INFO` script splitting, full Apache `.htaccess` semantics and non-Unix confinement for later work. These additions must preserve the existing Web Service / vhost-source separation.
|
||||
Reference in new issue
Block a user