v0.34.0_fina;

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-18 12:00:59 +02:00
1 parent 1ca019d849
commit c207e8a03f
69 files changed
+1496 -13838

No files matched your search

+29 -212
View File
@@ -1,225 +1,42 @@
# Security model and limitations
# Security model and deployment boundaries
This is a development source release with no executed Rust integration results in
the packaging environment. Do not expose it as a production security boundary until
the actual build, protocol tests, deployment review and an appropriate security
assessment have passed.
RustProxy provides several security controls, but it is not a complete Web Application Firewall, PHP sandbox or network firewall. Safe deployment depends on frontend TLS, trusted origin connectivity, application updates, least-privilege operating-system access and release testing.
## Administration
## Administration and private state
Administration binds to loopback HTTP by default. Settings can enable a dedicated
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.
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.
- Keep the separate admin listener on **loopback** unless explicitly configuring trusted administration HTTPS and restricted reachability. Use an SSH tunnel for simple remote management.
- Create the first administrator locally. There are **no default passwords**. Protect CLI recovery operations, sessions, session revocation and API token creation.
- Keep the SQLite database, Secret Store encryption material, certificate keys, `.env`, ACME profiles, external credentials and backups readable only by trusted operators. `.env` and service configuration may be trusted executable/input material.
- Never expose stored logs, OpenAPI, detailed status, full config or backup files anonymously. Keep public Vhosts away from the administration listener except in a carefully reviewed explicit-risk topology.
Sessions have HttpOnly/SameSite=Strict cookies, idle and absolute expiries and
credential-generation revocation. Mutations require scheme-aware Host/Origin checks,
the request marker and a CSRF token. Local CLI reset changes the hash and invalidates
all existing sessions without editing SQLite manually. Administration HTTPS marks the
session cookie Secure; HTTP cannot. The admin certificate and bind changes are
restart-required. A dedicated metrics credential is separate from browser sessions.
## Origin and request trust
The data directory and SQLite files are private. The local OS user with data-directory
access is a recovery authority and can create short-lived CLI sessions. Protect that
account, filesystem and backup copies; browser authentication does not defend against
a compromised process owner. `.env` is trusted shell code, never untrusted input.
- Enforce IP/country/DDNS policies, rate limits and HTTP method rules **before** connecting to backends. A Custom location cannot undo a Vhost-level denial.
- Private and local backend addresses require deliberate exceptions. Routing to the local administration listener can expose secrets or create routing loops.
- HTTPS to a backend is not proof of identity unless upstream certificate/hostname verification is enabled; current backend defaults do **not** enable verification automatically.
- Honor forwarding identity headers only from correctly configured trusted peers. A client can forge arbitrary `X-Forwarded-*` and User-Agent headers.
- Restrict Basic Auth to HTTPS and protect Tinyauth endpoints. Authentication traffic should never be stored in public shared cache.
## Backend and routing boundary
## Content and cache privacy
Only configured HTTP/HTTPS origins may be dialed. Absolute-form client targets and
CONNECT cannot turn the proxy into an unrestricted forward proxy. ACL is evaluated
before new TCP/TLS connections and before reuse of an existing upstream connection.
Host and route restrictions combine; route allow cannot override host deny.
Forwarded headers are rebuilt from socket identity by default. An explicit
trusted-proxy CIDR policy can accept a bounded existing chain and derive the client
IP for ACL/affinity; see INTEGRATIONS_040.md. Routing still uses the actual local
destination, never any forwarded address or host.
- Shared cache must refuse private/no-store content and unsafe authenticated representations. Test behavior with cookies, `Authorization`, `Set-Cookie`, `Vary` and conditional requests.
- HTTP BAN/PURGE is disabled by default and must use a narrow allowlist if enabled. Never grant untrusted clients cross-site invalidation rights.
- Rewrites/transforms and custom headers can change semantics; verify that CSP, HSTS, CORS, validators and `Cache-Control` remain appropriate.
Private/loopback destinations require explicit approval. DNS answers pass the same
policy and optional per-backend CIDR restriction; an unsafe answer fails the entire
resolution. Validated results are used without a second DNS lookup. Special-address
blocks include common metadata/link-local targets and normalize mapped IPv6.
Listener self-target restrictions prevent simple loops and control-plane access by
default. A privileged administrator can deliberately set `accept_local_listener_risk=true`
on one backend; private/loopback destinations additionally require `allow_private=true`.
This is intended for consciously accepted local-listener use (including port 9090) and
can create a request loop or expose administration through a public vhost. It does not
relax metadata/link-local/special-address filtering or CIDR restrictions. Keep network
egress and frontend ACLs as defense in depth.
## Web Server and PHP
No backend `Location` redirect is followed internally. HTTPS transport encryption remains
available, but backend trust/hostname verification is off by default. Set `tls_verify: true`
for origins where certificate-chain and hostname authentication is required. With
verification disabled, a network attacker able to intercept that route may impersonate
the origin. Address/DNS restrictions still apply; the local-listener exception exists only
when explicitly accepted as above. Operator-supplied backend configuration is privileged
configuration, not a field that an unauthenticated caller can edit.
- Put credentials, source secrets and backups **outside document roots**. Directory listing and symlink relaxation are disabled by default; change only when deliberate.
- Run PHP-FPM as a separate controlled service. Give unrelated PHP applications distinct FPM pools to prevent cross-application INI/worker leakage.
- Treat `.htaccess` support as a restricted compatibility feature, not arbitrary Apache configuration. RustProxy hardening rules supplement but do not replace application security updates.
## TLS and tunnels
## Integrations and transport
Private key files are size-bounded, regular files, owner-only on POSIX and opened
without following final-component symlinks. Named files cannot escape the certificate
directory by using path separators. Keep the entire directory tree private as well.
Keys and certificate name coverage are validated before publication. Generated
self-signed certificates are development material, not automatic public trust.
- Docker agents have read-only inventory endpoints but their local Docker socket permission is highly privileged. Restrict the host account, port, Bearer token and pinned certificate.
- Prometheus has its own endpoint/network credential policy and no admin browser session. Keep it private or behind a secure tunnel.
- TCP/UDP Streams do **not** inherit HTTP ACL/auth/cache/TLS termination. Protect protocol endpoints separately.
- HTTP/3 needs UDP and should be tested with firewall, NAT and TLS behavior on the actual deployment.
- Managed ACME and external certificate reload integrations require least-privilege DNS/file/token access.
Existing TLS sessions/tunnels are not revoked by changing a certificate or ACL.
Policies apply to new requests and handshakes. Restart/stop the relevant process for
immediate termination until a scoped administrative close operation is implemented.
WebSocket payloads remain opaque byte streams. The proxy validates upgrade metadata,
not application-level authorization or message semantics. Frame/message limits on a
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
or WebSocket payloads. Hostnames and paths are logged; never put secrets in them. Do not enable third-party verbose tracing or application logging without
reviewing their output separately. Access rings, viewer slots, auth work, updates,
DNS workers and request/connection admission are bounded. A slow log viewer does not
create an unbounded delivery queue.
Backups include TLS private keys and credential/session state. Restore matching
SQLite and certificate data together, then revoke restored sessions. Never commit
`.env`, the data directory, backups or generated certificates to a public repository.
## Not a completed security feature
Docker socket access controls, service-account metrics access,
2FA, roles, provider secret storage, certificate
expiry automation, a full special-address registry policy and independent fuzz/load
assessment remain roadmap work. Feature availability is not evidence of a completed
security audit or a performance guarantee.
## Cache, response transforms and ports (0.1.0)
Cache is enabled by default in 0.8.1 and ACLs precede lookup. Cookie (outside the
configured static-asset exception), Authorization, Range, unsafe preconditions and
request/response `no-store` remain hard shared-cache exclusions. Conditional validators
can be satisfied from a fresh object or revalidated against the origin. Response
`no-cache` with a usable validator may be retained only for mandatory validation before reuse. Origin privacy is
checked before custom header removal, and generated request IDs are not cached. Bounded
fill permits, object/entry/byte limits and generation checks protect cancellation,
update and purge paths. Purge is authenticated, CSRF-protected and audited, not a
public PURGE/BAN capability.
Compression is opt-in, with authenticated/private/no-transform exclusions. Response
rules cannot overwrite protected framing/identity fields. For compatibility with 0.26.6,
custom `Age` rules remain accepted. Response-side `Age` is deferred to the final wire stage,
after RustProxy's cache freshness/revalidation logic, so it cannot alter stored age, TTL or
cache eligibility. Server hiding is cosmetic and
must not be considered an access-control or vulnerability mitigation substitute.
Standard public 80/443 ports are supported without globally forbidding remote
origins using those ports. Local listener targets remain guarded. Review SETTINGS.md
for interface-enumeration and restart semantics. A Linux service can grant only
CAP_NET_BIND_SERVICE to a dedicated unprivileged account; the application does not
acquire capabilities itself. Public listener controls do not implicitly expose the separate admin
API. The provided systemd unit is an unexecuted example, not an audit result.
Language packs are trusted build inputs with size/type/metadata bounds. The browser
renders strings as text and falls back per key. Translations are not executable
plugins, and no directory browsing or runtime arbitrary file loading is exposed.
## 0.2.0 frontend and pool boundaries
An explicit vhost binding is checked using the accepted stream's real local IP,
port and TLS state. Host, SNI and forwarded headers cannot assert a different local
address. A shared wildcard TCP listener does not grant every vhost access on every
accepted IP. Legacy routing does not inherit additional frontend sockets. Conflicting
hostname ownership is rejected, including disabled declarations.
Binding a private IP is not an authorization mechanism or firewall. NAT, port
forwarding or another proxy can make that destination reachable. Configure network
restrictions and application authentication as well; no trusted-proxy identity or
Keepalived/VRRP service is introduced. New unavailable IP bindings fail startup.
Health probes share literal/DNS/allowlist/loop protections, including actual old
listeners and desired new listeners, and cannot follow redirects to arbitrary
origins. They are bounded and do not use user cookies or credentials. Probes can
still hit an operator-selected GET path; select a side-effect-free health endpoint.
Affinity uses opaque random tokens but is not authentication, CSRF protection or
session replication. Tokens survive compatible edits, not process restarts. Cookie
mode bypasses cache; the dedicated cookie is stripped before origin forwarding and
cannot be overridden by an origin Set-Cookie. No failed request, especially a write,
is replayed on another member to obtain a successful response.
Dedicated per-vhost security headers also cover matching-host denials/errors and
cache hits. HSTS is removed on plaintext; includeSubDomains/preload remain explicit
opt-ins. Preload directives do not enroll a domain in a browser list. Arbitrary CSP
and Permissions-Policy values are encoding-validated, not semantically audited.
Old configurations retain origin headers unless an explicit policy overrides them.
## Certificate uploads and custom pages (0.3.0)
Certificate upload is an authenticated local-control-plane mutation protected by
Origin and CSRF validation, body/per-file bounds and two-worker admission. PEM pairs
are parsed, key-matched and checked against supplied DNS names. Private immutable
files use generated simple names, mode 600 and the existing no-symlink/directory
lock protections. Public API responses/config/audit contain metadata, not key PEM.
JavaScript clears file controls after use, but does not claim secure erasure of
browser memory. Only configuration publication activates an inventory selection.
No new listener or public certificate-upload endpoint is created.
Custom HTML is fully trusted administrator-authored content served on the chosen
public vhost. It may contain executable HTML/scripts there; it is never previewed
or inserted as HTML in the admin DOM. Do not upload untrusted markup. The fixed
welcome page interpolates only the software version, not Host, URL or user input.
HTML is bounded to 32 KiB per page and by the overall 256 KiB configuration limit.
Responses use no-store; old representation encoding/length/cookies are discarded
when replacing an origin error. Authentication challenges, Allow and Retry-After
are retained, then administrator response/security rules are applied.
ACLs run before static/fallback/direct-IP pages. Even a custom status 200 for a
blocked request never authorizes an upstream fetch. Such overrides can confuse
clients and monitoring; retaining the original 401/403/5xx status is recommended.
Direct-IP HTTPS still needs a completed TLS handshake and a suitable certificate;
an HTTP welcome page cannot remove a TLS certificate-name error.
## Integration boundaries in 0.4.0
Tinyauth runs after host/path ACLs and before any cached/static/origin response or
WebSocket upgrade. Incoming identity headers are stripped, including after generic
header rules, and only configured fields from a successful verifier are copied.
The verifier gets no request body or admin session cookie. Its DNS/private-network
and TLS checks match the origin safety boundary. Authentication failure cannot be
turned into a 200 by custom pages. Denials and protected responses are no-store;
there is no auth-result or protected-content shared cache. Existing upgraded
sessions are not reauthenticated continuously.
Only configured login-origin redirects are accepted. Do not expose the fake-auth
helper or treat its test cookie as an actual login. H3 uses the same routing,
auth, request limits and response policies; 0-RTT is disabled. Transport resource
limits do not replace rate limiting, firewalls or independent security/conformance
testing. H3 is uncompiled/unexecuted in this packaging environment.
Diagnostic response fields are hidden by default, but origin secrets still need
explicit response rules. In 0.5.0 the dedicated controls expose request ID and
revision independently; the obsolete hide_mock_origin field is not accepted. X-Mock-Origin can be
removed using ordinary response-header rules. Scope labels on listeners never
enforce network restrictions. See ACME_RFC2136.md for private TSIG/account storage
and the separate backup requirement for manual DNS-01 issuance.
## User-Agent blocklists
RustProxy can apply an optional global User-Agent blocklist and an additional per-vhost blocklist. Matching is case-insensitive; plain text matches a substring and `*` is a wildcard. Policies are bounded and disabled by default. They are evaluated before opening an upstream; a match returns HTTP 403. Requests without a User-Agent are not denied by this rule.
User-Agent is client-controlled and easy to spoof, so this is an operational noise/blocking control rather than an authentication or identity boundary. Keep ACLs, authentication and rate limits as the authoritative controls.
## Release and operational validation
The provided 0.34.0 source includes changes without completed native compilation, all-protocol regression or production performance measurement. Do **not** treat source-code inspection as proof of security or performance. Before using it at an Internet edge, test on the target OS, run the automated suite, verify TLS/H2/H3/WebSocket handling, access and cache privacy, backup/restore, logging and failure recovery. Keep monitored off-host backups and a rollback plan.