2026-10-10 11:35:04 +02:00
2026-10-08 11:27:18 +02:00
2026-10-08 22:22:46 +02:00
2026-10-10 11:35:04 +02:00
2026-10-05 10:58:50 +02:00
2026-10-08 22:22:46 +02:00
2026-10-07 22:22:54 +02:00
2026-10-10 11:35:04 +02:00
2026-10-08 11:27:18 +02:00
2026-10-03 00:27:09 +01:00
2026-10-08 22:22:46 +02:00
2026-10-10 11:35:04 +02:00
2026-10-04 11:15:58 +02:00
2026-10-10 11:35:04 +02:00
2026-10-03 00:27:09 +01:00
2026-10-03 00:27:09 +01:00
2026-10-03 00:27:09 +01:00
2026-10-10 11:35:04 +02:00
2026-10-07 22:22:54 +02:00
2026-10-10 11:35:04 +02:00
2026-10-10 11:35:04 +02:00
2026-10-10 11:35:04 +02:00
2026-10-10 11:35:04 +02:00
2026-10-07 13:40:21 +02:00
2026-10-08 22:22:46 +02:00
2026-10-07 22:22:54 +02:00
2026-10-08 22:22:46 +02:00
2026-10-10 11:35:04 +02:00
2026-10-10 11:35:04 +02:00
2026-10-03 00:27:09 +01:00
2026-10-10 11:35:04 +02:00
2026-10-03 00:27:09 +01:00
2026-10-07 22:22:54 +02:00
2026-10-07 22:22:54 +02:00

RustProxy 0.30.1

Independent Rust reverse proxy and static Web Server with a dashboard, SQLite configuration, streaming HTTP/TLS/WebSocket forwarding, raw TCP/UDP stream hosts, IP-bound vhosts and backend pools.

0.30.1 release source.

Layer-4 streams

Raw TCP/UDP forwarding has its own Streams page in the primary navigation, alongside Vhosts, Redirects and 404 hosts. Streams use the same card/modal workflow as vhosts, but each stream owns a dedicated Layer-4 listener and one upstream and intentionally bypasses HTTP ACL/cache/header/compression logic. The page exposes live per-stream connections/sessions, rejects, errors, transferred bytes and RX/TX rate charts. Listener changes require a restart. See TCP/UDP streams.

Named HTTP/HTTPS listener bind addresses use the same chip-style editor as vhost hostnames, including multi-address listeners.

What changed in 0.30.1

  • Match H1/H2/H3 legend markers to the corresponding protocol-chart line colors across chart palettes.
  • Keep About focused on the product, author, license and source/package links. Move Python/ACME diagnostics out of the About dialog.
  • Add Settings -> System information (/settings?tab=system-info), showing OS release/kernel/architecture where available, CPU, RAM, uptime, process metrics, ACME interpreter/pip/Certbot versions where discoverable from local metadata, ACME mode/state, and data paths. OS/kernel details come from the existing sysinfo Rust library. Version display reads bounded pyvenv.cfg and Python .dist-info/METADATA files at ACME initialization; it does not execute diagnostic commands. Some system-installed tools lack these metadata files, so their versions will be shown as unavailable rather than guessed. Operational ACME checks and certificate issuance still run Python/Certbot as required.
  • The authenticated status API exposes the extra read-only runtime fields; SQLite schema 9, Cold Cache format 3 and existing configurations are unchanged. Real Rust compilation and live integration verification are still required.

Previously in 0.30.0

  • Edit individual active health-check policies in Vhosts → Health. The backend selector lists only members with monitoring enabled in Backends. Choose a member and optionally customize its TCP/HTTP mode, path, Host, interval, timeout, thresholds and expected status range. Other backends retain their unsaved edits; disabling monitoring hides its editor but preserves the saved override for future re-enablement. No API or SQLite schema changes.
  • Improve sustained-memory handling: reclaim selective PURGE-generation bookkeeping, avoid unnecessary analytics-label allocations, reuse serialized access JSON across JSONL/Logstash/Loki, and avoid duplicate directory listing vectors/HTML buffers. Stored Logs discovery retains at most 256 per-vhost and 64 rotated-gzip candidates. See memory stress verification for the audit and real-world RSS/load test procedure; source-only checks cannot rule out runtime leaks.
  • The previous 0.29.7 improvements remain included. SQLite schema 9 and Cold Cache format 3 are unchanged.

Previously in 0.29.7

  • Configure active/passive monitoring per backend independently from backend enablement and balanced-pool eligibility. Optional per-member active TCP/HTTP health-check overrides inherit the vhost's HTTP Host when omitted. An unmonitored internal 404 backend remains routable but is no longer probed or passively ejected.

  • Add global and per-vhost HIT-only cache diagnostics. Suppress X-Cache, X-Cache-Hits, X-Cache-Reason and Cache-Status on MISS/BYPASS, while retaining diagnostic headers on actual HIT. The separately configured Via header still applies; internal metrics are unaffected.

  • Detect and warn about Web Services sharing the same PHP-FPM endpoint with different PHP_VALUE or PHP_ADMIN_VALUE settings. Shared PHP-FPM worker processes can retain dynamic ini settings between requests (including open_basedir), so WordPress/Roundcube must use distinct PHP-FPM pools/sockets when their policy differs. See PHP-FPM isolation.

  • Add configuration/Rust source regressions for per-backend monitor overrides, HIT-only cache policy and cache revision stability. Existing persisted settings load with their prior defaults; SQLite schema 9 and Cold Cache format 3 remain unchanged.

  • Cargo and live PHP-FPM tests remain required before production deployment.

  • Expand per-service and shared-profile PHP-FPM editor help: field-by-field examples, FastCGI NAME = value, PHP_VALUE and PHP_ADMIN_VALUE syntax, and dedicated WordPress/Roundcube pool guidance. Fix checkboxes/labels and add explanatory info tooltips for PHP execution, PATH_INFO and Authorization forwarding. See PHP-FPM settings.

  • Add opt-in vhost origin-error interception (Vhosts → Pages) with selected 400/404/5xx statuses. RustProxy replaces application HTML with a configured vhost/global page or a built-in page; the application's HTTP error status is always preserved, final internal fallbacks have precedence, and intercepted responses are no-store. Origin responses remain unchanged when interception is disabled, even if a global RustProxy error page exists.

Previously in 0.29.6

  • Fix native Web Server/PHP-FPM response compression across HTTP/1.1, HTTP/2 and HTTP/3 by fusing the FastCGI response stream; prevent a futures-util::stream::unfold panic after EOF.
  • When Error file is enabled, write warnings, errors, PHP-FPM stderr and worker panic diagnostics to the error file instead of duplicating them in systemd. When disabled, use the console. If the file cannot be written, fall back to console diagnostics.
  • Add EOF, gzip and error-log routing regressions; actual Rust/Cargo build and Roundcube runtime verification are still required.

Previously in 0.29.5

  • Fix PHP-FPM PATH_INFO dispatch for existing scripts such as Roundcube 1.7 /static.php/skins/...: when PATH_INFO is enabled, invoke the script before try_files can fall back to /index.php.
  • Keep FastCGI SCRIPT_FILENAME, SCRIPT_NAME, PATH_INFO, REQUEST_URI and the query string accurate, and check access rules on the resolved PHP script path.
  • Add mock FastCGI regression tests proving that Roundcube static assets reach static.php; opt-out (path_info: false) retains the previous fallback behavior.
  • No database migration or saved Web Service configuration changes. Rust compiler/runtime verification is still required before production deployment.

Previously in 0.29.4

  • Reuse named PHP-FPM profiles across Web Services, or keep per-service PHP-FPM settings; edit profiles in the expandable Web Server modal.
  • Open the same PHP-FPM profile manager from the PHP-FPM profiles button beside New Web Service on the Web Server page.
  • Run vhost RustProxy cache and enabled response transformations for Web Server filesystem/PHP sources with normal response privacy protections.
  • Preserve the original request Host in FastCGI HTTP_HOST for WordPress, including HTTP/2/HTTP/3 authority-only requests.
  • Added regression tests; the Rust compiler/runtime gate is still required before production deployment.

Previously in 0.29.3

  • Fix internal error fallback for empty GET/HEAD requests over HTTP/2 or HTTP/3 with unknown body-length hints by safely checking if the body stream is empty; nonempty and unbounded bodies remain protected from unsafe replay.
  • Preserve the final status, headers and HTML returned by the internal fallback location, including its own 404 page, instead of replacing it with RustProxy's global error page. Warn when a named internal target cannot be found.
  • Add Rust regression tests for empty H2/H3 GET/HEAD, unknown-length request bodies and response precedence. These Rust tests require a Cargo-enabled environment before production deployment.

Previously in 0.29.2

  • Add Nginx-style internal error fallbacks for the vhost source and Custom locations. Configured upstream/Web Server statuses can internally hand the original method, URI, query string and request context to an internal Custom location without an HTTP redirect. Supported bounded statuses are 403/404/500/502/503/504; configuration cycles are rejected and runtime dispatch has a depth limit.
  • Execute error fallback before an intercepted response is finalized or cached. The target location re-enters the normal vhost/location pipeline, including ACL, headers, compression, cache policy and response processing. Request bodies are replayed only when safely bounded and replayable; otherwise the original error is retained.
  • The main Web Server source ignores backend health/unavailability; Custom Locations configured for Reverse Proxy continue to use their backend pool. Error-fallback-specific Prometheus counters have been removed.
  • Add streaming multipart byte-range responses for requests such as Range: bytes=0-99,200-299, with a maximum of 16 ranges and identity representation for multipart responses.
  • Add opt-in PHP-FPM PATH_INFO splitting. With path_info: true, /index.php/foo/bar securely resolves the existing index.php script, keeps SCRIPT_FILENAME on that file and sends /foo/bar as PATH_INFO.

0.30.0 keeps SQLite schema 9 and Cold Cache format 3. Existing configurations remain loadable; new optional health and diagnostic fields receive backward-compatible defaults. Historical details are in CHANGELOG.md.

Historical 0.26.7 release notes

  • Show explicit HOT and COLD cache occupancy progress on /cache, including object-count and byte/disk limits from Cache settings plus percentage usage.
  • Preserve compatible upstream client pools across unrelated active-snapshot rebuilds so generation age, request count and Rotations diagnostics do not restart at zero unless the backend connection policy actually changes.
  • Keep age-based backend rotation in the maintenance loop and retain request-count rotation; compatible snapshot reuse now makes the existing counters observable over long-running processes.
  • Refresh container documentation and ship the OCI image with one pinned Certbot environment containing all RustProxy-supported DNS plugins: Cloudflare, OVH and RFC2136.
  • Review current installation/container/cache/backend lifecycle documentation for stale version or behavior statements.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.6 requires no data migration.

0.26.7 retains the 0.26.6 access-policy and administration fixes below.

Retained 0.26.6 release notes

  • Keep backend diagnostics visible-column selection, sort key and sort direction synchronized with the account-scoped administrator preferences whenever preferences are loaded or updated.
  • Clear the ACME certificate-creation form after the issuance job finishes successfully, so successful certificates do not leave stale values while failed jobs keep the non-secret form values available for correction.
  • Compose explicit IP allows and Allow only countries as alternatives inside one ACL policy scope. Explicit IP denies and blocked countries still win, and profile/vhost/location scopes remain cumulative. This makes default=deny support private CIDRs or selected countries as intended.
  • Document the sibling migrate_npm_core.py and migrate_npm_api.py modules required by scripts/migration/migrate_npm.py, and fix the container example to mount the dedicated scripts/migration directory.
  • Detect the Linux runtime environment in Process diagnostics. LXC reports Linux / LXC and overrides system uptime with PID 1 age plus load average from the container-visible /proc/loadavg; VM/host/Docker and other Linux environments keep the existing host statistics path.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.5 requires no data migration.

0.26.6 retains the 0.26.5 interface-scaling and listener-navigation fixes below.

Retained 0.26.5 release notes

  • Keep compact toolbar select controls on the same scaled box model as neighboring inputs, including Stored Logs, Backends, Docker, vhost-style lists and Settings filters. Form-control dimensions consume the interface-scale field variables consistently.
  • Make Streams -> Add TCP/UDP listener navigate to Settings -> Listeners instead of opening a new Stream configuration dialog.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.4 requires no data migration.

Retained 0.26.4 release notes

  • Extend session-only editor drafts to 404 hosts, preserving the complete unfinished form state when another editor is opened or the dialog is minimized.
  • Complete the Polish translation for Settings -> Appearance -> Button style and keep the button-size preference independent from global interface scale.
  • Keep search/filter inputs in compact toolbars no taller than the active button style, including Backends, vhost-style lists, Docker, Logs and Settings search controls.
  • Reuse the vhost Enabled control presentation in 404 hosts, Redirects and Streams so modal enable/disable state is visually consistent.
  • Replace the tall Overview-card checkbox list in Appearance with a compact responsive tile grid; each tile toggles visibility and retains reorder controls.
  • Run time-based upstream-client pool recycling from backend maintenance as well as request dispatch, so an idle backend rotates after its configured age instead of remaining on generation 0 until the next request.
  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.3 requires no data migration.

Retained 0.26.3 release notes

  • Make interface scaling truly global: the 70-125% setting now scales the authenticated dashboard, navigation, dialogs, overlays, draft dock and other top-level administration UI consistently. Form fields receive an additional proportional size adjustment so inputs/selects/textarea do not remain visually oversized at low scale or undersized at high scale.
  • Tighten the Overview metric cards so wide dashboards fit more telemetry with less empty vertical space.
  • Expand chart presentation presets to Default, Soft, Technical, High contrast, Neon, Monochrome, Warm and Cool. Presets now alter palette, surface treatment, grid character, line weight and chart contrast instead of changing only stroke shape.
  • Restyle the bottom-right draft dock as a square-corner panel that follows the existing RustProxy card/navigation language instead of using a rounded glass/floating treatment.
  • Let the draft dock collapse to one bar and show the age of every suspended draft.
  • Add Settings search across translated section labels and settings content, per-section Appearance resets, and a full Appearance reset.
  • Add visual palette buttons for all chart presets, independent table/log density, independent dashboard density, and an Ultra compact option for both data tables/logs and Overview cards.
  • Add a per-user Button style selector: Normal keeps the refreshed buttons and Compact restores the smaller source-style button sizing independently from interface scale. The selection now applies consistently to generated vhost actions and tab buttons inside dialogs.
  • Let administrators hide/show and reorder the Overview telemetry cards from Appearance without changing metric collection.
  • Keep all new appearance choices account-scoped in the existing SQLite administrator-preferences document; schema 8 and the saved proxy configuration format remain unchanged.

0.26.3 includes the 0.26.2 administration workflow improvements below:

  • Add session-only editor drafts for Web Server, Vhosts, Redirects and Streams. Closing an edited form minimizes it into a bottom-right draft dock, while opening another item starts a clean independent editor.

  • Add Settings -> Appearance. Theme, language, interface scale, 12/24-hour time display and chart style are account-scoped preferences stored in SQLite; the scale slider now spans 70-125%.

  • Apply time-format preferences to dashboard timestamps and compact expanded Stored Logs details to reduce scrolling on large records.

  • Merge the Stored Logs and Live Logs top-bar actions into one Logs menu.

  • Replace the Stored Logs filter row with an optional log-source selector, one query field and page-size control. Search accepts Kibana-style field clauses such as req: GET AND !country: Poland, quoted values, wildcards and numeric comparisons.

  • Parse JSON/JSONL records into dynamic selectable columns discovered from returned fields instead of maintaining fixed protocol-specific columns. matched_by and sni are no longer hard-coded table columns, but remain available when present in a record.

  • Parse the built-in RAW error-log format into timestamp, level, target, message and detected key=value fields while retaining the original raw line.

  • Expand selected records as parsed field/value rows with optional raw JSON, and move the column picker to the upper-right edge of the result table.

  • Remove the Configured files inventory while keeping an optional source selector; the explorer searches all bounded configured log sources by default and narrows to one selected source when requested.

  • Replace backend sort text (A-Z / Z-A) with direction arrows (↑ / ↓).

  • Keep SQLite schema 8 and the saved proxy configuration format unchanged; upgrading from 0.26.1 requires no data migration.

The detailed 0.25.5 implementation audit remains available as historical baseline evidence. Current 0.28.1 verification status is maintained in docs/TEST_REPORT.md.

Documentation

Release history

Historical user/operator-visible changes are maintained in CHANGELOG.md. Detailed historical implementation notes are retained in docs/CHANGELOG_TECHNICAL_ARCHIVE.md, and completed roadmap milestones are retained in docs/ROADMAP_HISTORY.md.

Core capabilities and references

Managed certificates imported into the library renew automatically unless disabled. Initial issuance/import remains explicit and staging-first; imported PEM alone is not auto-managed. See renewal and recovery.

Read installation and update, host access and locations, migration, NPM migration, ACME providers, Prometheus, cache diagnosis, HTTP/3 scope, TCP/UDP streams and container deployment. Cloudflare Tunnel remains deferred. Docker discovery is available through the standalone agent; see Docker discovery. Examples are disposable full configurations: applying one replaces, not merges, an existing document.

Installation and source build

Official package repositories

The preferred installation/update path is the project-maintained package repositories:

  • DEB/RPM packages: https://rustproxy.linuxiarz.pl/
  • OPNsense plugin: https://rustproxy-opn.linuxiarz.pl/

Use the repository instructions appropriate for the target operating system. Package/service installs do not need a packaging-time GeoIP download: the proxy starts an enabled-by-default background updater after its listeners bind, performs the first verified refresh immediately, and then checks again every 24 hours unless changed in Settings -> GeoIP updates. Building on Debian is kept as an optional source/development path rather than the primary installation method.

The production CLI default data directory is /var/lib/rustproxy. dev.sh explicitly overrides it to the repository-local ./data directory for development commands.

Optional: Debian 13+ one-line source install/update

The bootstrap installs the compiler/build dependencies and Rust, clones this repository and builds the locked release. With no argument it runs in auto mode: a host without a managed RustProxy installation is installed, while an existing /opt/rustproxy/install.json triggers the safe update.sh path with backup, health check and rollback. First install starts HTTP on 0.0.0.0:80, HTTPS on 0.0.0.0:443 and keeps the administration panel on loopback HTTP 127.0.0.1:9090. Updates preserve the saved listener and service settings. Use an SSH tunnel for initial remote access, then enable Administration HTTPS before exposing a non-loopback admin bind.

# automatic: install on a new host, update an existing managed installation
wget -qO- https://git.linuxiarz.pl/gru/RustProxy/raw/branch/master/install-debian13.sh | bash

# explicit update
wget -qO- https://git.linuxiarz.pl/gru/RustProxy/raw/branch/master/install-debian13.sh | bash -s -- update

Manual build prerequisites used by that bootstrap:

apt install -y build-essential gcc git ca-certificates python3 pkg-config wget sudo python3-certbot-dns-rfc2136 python3-certbot-dns-cloudflare
wget -qO- --https-only --secure-protocol=TLSv1_2 https://sh.rustup.rs | sh

Rust stable (declared minimum 1.88), Cargo, C compiler/linker, Bash and Python 3.10+. Linux is the primary deployment target; macOS/WSL2 need normal native build tools. Detailed OS diagnostics currently use Linux procfs and cgroup v2. Unsupported measurements remain null/N/A.

The first build needs access to the Rust toolchain and crate registry. dev.sh never installs system software or runs sudo. Rustls handles runtime TLS; zstd's native dependency still needs a C build toolchain.

The Debian bootstrap intentionally builds with one Cargo job, LTO disabled and codegen-units=8. This avoids rustc being killed by the OOM killer on small VPSes while leaving the repository's normal release profile unchanged. For a manual low-memory build use:

CARGO_BUILD_JOBS=1 CARGO_PROFILE_RELEASE_LTO=false \
  CARGO_PROFILE_RELEASE_CODEGEN_UNITS=8 cargo build --release --locked

Package-build metadata remains outside this source tree and is maintained with the official package repositories above.

The 0.28.1 source archive preserves the resolved Cargo.lock supplied with the source tree and updates only this package's own version entry. This packaging environment has no Cargo, so the dependency graph was not re-resolved here. On the compiler-enabled deployment host, run the locked check/test/release gates below and retain the verified lockfile. dev.sh can generate a lockfile only when one is genuinely absent; it does not replace normal locked verification.

cd RustProxy
bash dev.sh doctor
bash dev.sh check
bash dev.sh test
bash dev.sh
Service Development default
Default HTTP http://127.0.0.1:8080
Default HTTPS https://localhost:8443
Administration (default) http://127.0.0.1:9090; HTTPS/remote bind is opt-in in Settings
Optional protocol fixture 127.0.0.1:9000, only with RUST_PROXY_DEMO=1

In a second terminal, print the one-time setup capability and use the browser, or initialize an administrator locally:

bash dev.sh admin setup-token
# Alternative: interactive account creation, no default credentials.
bash dev.sh admin init

There is no default username/password. Normal startup serves a neutral informational page for an unconfigured address and does not seed sample vhosts. The self-signed bootstrap certificate is retained under data/certs and is not publicly trusted. Assign intended certificates explicitly. Public frontend TLS does not implicitly expose the separate administration listener. Administration remains loopback HTTP by default; enable its own HTTPS setting before choosing a remote bind. Existing databases are never reset by this default.

Use the protocol fixture only explicitly when running the documented test suites; RUST_PROXY_DEMO=1 bash dev.sh seeds a new disposable database. The separate bash dev.sh mock helper remains available for cache/backend testing.

For a system service, build as an ordinary user and follow the complete procedure in INSTALL.md:

bash dev.sh release
bash install.sh --plan --binary target/release/rust-proxy
sudo bash install.sh --binary target/release/rust-proxy
# A subsequent release:
sudo bash update.sh --binary target/release/rust-proxy

Copy .env.example to .env for startup defaults; it is trusted shell code. RUST_PROXY_DEMO=0 disables the demo. RUST_PROXY_TLS=0 removes the startup TLS default used when bootstrapping listeners.

The release checker reads its compile-time defaults from repository-root UPDATE_CHECK.toml, which is embedded in the final binary. It checks the configured Cargo.toml URL immediately on startup and then every 3600 seconds by default. A failed request is ignored until the next interval; it never blocks startup or proxy traffic and it never installs updates. On Unix-like systems the checker keeps its bundled public roots and also imports certificates from SSL_CERT_FILE, CURL_CA_BUNDLE and common Linux/BSD CA bundles, including the FreeBSD/OPNsense ca_root_nss path. It follows at most five credential-free HTTP(S) redirects and never downgrades an HTTPS check to HTTP. Failed checks stay invisible in the dashboard, preserving the existing footer behavior, but are emitted as application ERROR events so the optional error-file sink can capture them. Operators may override the embedded values with global CLI options or equivalent environment variables:

--update-repository-url         RUST_PROXY_UPDATE_REPOSITORY_URL
--update-version-url            RUST_PROXY_UPDATE_VERSION_URL
--update-check-interval-secs    RUST_PROXY_UPDATE_CHECK_INTERVAL_SECS

Set the interval to 0 to disable automatic checks. Debian/systemd installs may place the environment overrides in /etc/rustproxy/environment; source/development runs may use the normal process environment.

Persisted frontend sockets live only in listeners.endpoints and are edited under Settings -> Listeners. Listener address/TLS/H2/H3 capability changes need a process restart; vhost H2/H3 switches only narrow those capabilities and routing/pool policies otherwise use validated hot publication.

Private vhosts and backend pools

Use Settings -> Listeners to configure frontend sockets, then use Vhosts to select those named listeners and configure backend members. examples/vhosts-private.json binds its named listener only to 127.0.0.2 and uses two explicit loopback origins. Replace these with addresses assigned to your machine and your real services. examples/vhosts-balanced.json shows an opt-in public 80/443 deployment; do not apply it unintentionally.

A private vhost is selected by hostname and the accepted socket's actual local IP, port and TLS state. Sending its Host/X-Forwarded-* values to a different IP does not select it. A shared wildcard socket may accept TCP at multiple addresses, but each vhost keeps its original routing constraints. IP binding is not a firewall or authentication: NAT/another proxy can still forward traffic to that private IP. Keep network restrictions and application authentication.

New health-checked members remain in checking until the configured successes make them eligible. No healthy member means 503; a healthy backup may be selected. HTTP checks measure time to response headers, not whole-body throughput. Affinity cookies bypass shared cache; they contain only an opaque routing token and are not login sessions. Existing cookie sessions may finish on a draining healthy member. The keepalive controls are connection reuse, not Keepalived/VRRP.

Save pool/routing/security changes live. New/removed sockets and TLS ALPN changes need a process restart; active vs desired endpoints are visible in Settings/API. Old top-level routes are converted once into vhosts during validated startup/import. There is no separate legacy routing UI or dispatcher; path-to-origin ownership is retained. Read the migration guide before updating an existing database. See VHOSTS.md for algorithms, defaults, bounds, caveats and the complete configuration contract.

Standard ports without running as root

Settings -> Listeners accepts multiple named endpoints and socket addresses such as 0.0.0.0:80, 0.0.0.0:443, [::]:443 and custom ports. Presets change only the port: they do not silently replace a loopback interface with a public one. The admin listener is independent of these controls and stays loopback by default. In Settings -> Administration, enabling HTTPS permits a persisted non-loopback bind using either the application-managed certificate or a selected certificate. Plain remote HTTP remains available only with the explicit --allow-remote-admin startup flag.

Linux low-port binding can require CAP_NET_BIND_SERVICE. Use a dedicated service account and the example in deploy/README.md, not a root-run application. Port conflicts and OS permissions cannot be proved by merely saving configuration; bind failures are reported on restart. See settings, defaults and rollback.

Cache and response controls

The shared cache is enabled by default. Normal fresh 200 GET and cacheable HEAD requests use s-maxage, max-age or Expires; a configurable default TTL applies only to explicit public responses without an origin freshness lifetime and defaults to zero. GET/HEAD share the same frontend scheme + Host + exact URL object, response Vary selects representation variants, and unrelated request headers or the selected backend-pool member do not fragment that object. Since 0.19.1 HTTP and HTTPS use distinct primary cache identities so scheme-dependent origin responses cannot cross protocols. Non-GET/HEAD methods pass without globally purging unrelated cached objects.

Cookies (except the configured static-asset exception), authorization, ranges, If-Match/If-Unmodified-Since, private/no-store responses, Set-Cookie, Vary: *, streaming events and failed/incomplete bodies are not reused. If-None-Match and If-Modified-Since can be answered from a fresh cache entry as local conditional HITs. Request no-cache/freshness constraints revalidate a stored validator instead of blanket-bypassing the cache. Response no-cache with a usable validator may be retained, but must validate before every reuse. Request/response no-store remains a hard exclusion.

Default cache memory limits are 256 MiB HOT allocated/charged data, 16 MiB per object, 64 MiB transient RAM, a 32 MiB COLD writer queue, 4096 HOT entries and eight fill permits. The panel also offers memory-aware conservative/recommended/performance presets derived from the lower of detected host RAM and a finite cgroup memory limit; automatic presets are disabled below 256 MiB effective RAM. max_object_bytes remains an independent per-object ceiling and cannot exceed the global HOT budget. If it is configured above the transient budget, the panel warns that objects near that size will pass through uncached because a fill cannot reserve enough bounded transient RAM. Optional cold cache defaults to disabled; when enabled it uses a bounded disk path under the private data directory and asynchronously demotes LRU/idle hot objects. Cold objects survive process restart for the same configuration revision and are promoted to RAM on a fresh hit. Large fill buffers grow incrementally and consume multiple permits. Actual process RSS also includes in-flight responses, compression buffers and runtime allocations. HIT/MISS/BYPASS, hit count and standardized RFC 9211 Cache-Status diagnostics are independently optional; required Age advances on ordinary cache hits even when the origin does not send Age. A successful origin 304 Not Modified starts a new freshness-age calculation, so the next Age may legitimately be 0; optional X-Cache-Resident-Age tracks RustProxy residency across revalidation and tier movement. Purge is authenticated, CSRF-protected, audited and invalidates both tiers plus older fills. See cache behavior and limits and cache diagnostics.

Response compression is streamed and negotiated with Accept-Encoding; zstd, Brotli and gzip default ON while deflate defaults OFF, and equal client quality uses zstd -> br -> gzip -> deflate server preference. The selected algorithm is reported in Content-Encoding with Vary: Accept-Encoding. Existing Content-Encoding, ranges, SSE, upgrades and no-transform are passed through without recompression. Cookie, Authorization, Set-Cookie, private and no-store headers do not by themselves disable dynamic compression. Ordinary vhosts and Web Server services may inherit/enable/disable compression and individual codecs. Docker publications expose a single Compression on/off switch and always use the globally enabled codec set; explicitly disabling a configurable scope hides/disables its codec selectors in the dashboard while preserving their saved values. Strong ETags are weakened after transformation, and obsolete content digests are removed. Server policy is applied after generic response rules. Protected framing/identity headers and cache-owned Age cannot be edited through generic rules.

With the separate demo enabled, /cache-demo returns an explicitly public 30-second object. Enable cache and X-Cache in Settings, then issue this twice without cookies:

curl -i -H 'Host: localhost' http://127.0.0.1:8080/cache-demo

The first eligible request is MISS, then HIT while fresh. The origin timestamp stays unchanged on HIT. Unlike proxy/system measurements, this endpoint is explicitly demo content. The reserved admin cookie is removed before eligibility; application cookies still trigger privacy bypass. Use anonymous curl requests to check cache behavior.

Adding a language

Create langs/de_DE.json with metadata and string translations, then rebuild and restart. No JavaScript language switch or registry edits are needed:

{
  "meta": {
    "locale": "de-DE", "name": "German", "native_name": "Deutsch", "direction": "ltr"
  },
  "translations": { "settings": "Einstellungen", "overview": "Ubersicht" }
}

Missing keys fall back to en_US.json. Translation strings are rendered as text, not HTML; locale and direction metadata also control formatting/RTL. The two bundled languages are English and Polish. New packs are compile-time assets, not untrusted runtime plugins. See langs/README.md.

Updating an installed source tree

Read MIGRATION.md. Back up actual data/certificates, stop the old server and extract this archive into a separate, non-nested directory. From the new source directory:

rust-proxy --data-dir /actual/RustProxy/data backup create \
  --output /private/rustproxy-before-upgrade.rpb
bash upgrade.sh /actual/RustProxy --stopped
# Also pass --data-dir /actual/private/data when it is external.
cd /actual/RustProxy
bash dev.sh test
bash dev.sh

The supported operator backup is the password-encrypted rust-proxy backup create command. tools/legacy/backup.py is retained only as an offline release-test helper and must not be used as a Secret Store backup. See Secret Store and encrypted backup/restore.

.env, data, unmanaged files and previous managed sources are preserved. Extra language JSON files survive the update; shipped files replace their old names, whose previous bytes remain in the backup. Unknown custom source edits are not merged. Do not overlay individual source files onto an old tree.

RustProxy 0.25.3 upgrades SQLite to schema version 8 by adding retained manual-configuration history. Existing schema-7 data is migrated automatically; the current configuration is seeded as the first retained history row and future successful saves keep the newest 512 revisions. Vhost/location method and access-policy fields are additive and default to disabled/inherited behavior when omitted. Once a 0.25.3 configuration containing the new fields is saved, an older binary may reject unknown configuration fields. Roll back using the pre-upgrade data backup as well as the old source, not just the binary.

Source helper layout

script responsibilities are intentionally separated:

  • scripts/runtime, scripts/build, scripts/deploy, scripts/migration are coupled to application/build/deployment behavior;
  • tools/checks, tools/dev, tools/audit, tools/legacy are auxiliary tools and are not needed by the running proxy;
  • integrations/ contains external platform helpers such as OPNsense ACME and RouterOS OCI tooling.

See scripts/README.md, tools/README.md and integrations/README.md.

Documentation and checks

documentation index, API, architecture, security, transport, vhosts and pools, Web Server, settings, cache, roadmap, changelog, verification.

# Rust-independent checks:
python3 tools/checks/check_source.py
python3 tools/checks/release_smoke.py
# Runs those checks first, then the Rust suite when Cargo is available:
bash dev.sh test
# Source-only package, with no Git checkout required:
python3 make_zip.py /tmp/RustProxy-0.28.1.zip

New management and test-origin guide

See MANAGEMENT.md for the certificate staging workflow, page/status behavior and logs; MOCK_SERVER.md provides a ready-to-use cache/health test setup. The example examples/mock-vhost.json is a complete minimal document for a fresh test installation, not a merge patch.

Authentication and mock development

In Vhosts -> Authentication, enable Tinyauth and supply its base URL (or the complete /api/auth/nginx endpoint) and public login URL. Private verifiers need the explicit private-network permission; optionally constrain allowed networks. Default identity headers are Remote-User and Remote-Email. No embedded provider password or disabled TLS verification is required. Do not protect the login host with itself. See INTEGRATIONS_040.md for exact status/redirect behavior and limits.

# Separate terminals, after building the real proxy on a toolchain-enabled host:
bash dev.sh mock --port 9001 --name origin-a --ttl 30
bash dev.sh mock-auth --port 9300

The fake-auth server accepts the intentionally insecure cookie mock_auth=allow; it is a loopback-only development peer, never an authentication product.

Docker vhosts operational controls

Docker vhosts now publish/unpublish immediately per service. Each Docker agent has a configurable inventory polling interval, while the optional Live view refreshes cached runtime state only. Docker-backed applications can use ACL profiles/inline ACLs and per-vhost proxy connect/header/read/send timeouts, matching the ordinary vhost proxy controls.

S
Description
No description provided
Readme AGPL-3.0
74 MiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 59.8%
JavaScript 18.6%
HTML 9.7%
CSS 5%
Python 4.8%
Other 2.1%