Files
RustProxy/docs/VHOSTS.md
T
2026-10-21 14:39:51 +02:00

92 lines
9.6 KiB
Markdown

# Vhosts, domains and backends
A **Vhost** publishes one or more hostnames on named HTTP/HTTPS listeners. Its source can be an HTTP reverse-proxy backend pool or a reusable local Web Service. Use **Vhosts → Add** in the panel.
## Publish a site
1. Enter an ID and the exact domain (`app.example.com`) or supported wildcard (`*.example.com`). Exact names win over wildcards. Configure DNS independently.
2. Choose the enabled HTTP/HTTPS frontend listeners. Select a certificate for HTTPS.
3. Choose **Reverse Proxy** and add an upstream address such as `http://10.0.0.20:3000`, or select an existing **Web Service**.
4. Check backend reachability and TLS policy; configure health checks and load balancing for multiple origins.
5. Decide whether to force HTTPS, redirect www/non-www, enable WebSockets, cache, access rules and custom paths.
6. Save, visit the hostname, inspect the Vhost's health and logs, then test failure and recovery.
A Vhost may bind several frontends. Hostnames and selected listeners must match: the existence of a certificate or an upstream does not create DNS entries or a listening socket. Existing Vhosts retain their bindings when new listeners are created.
## Block request Content-Type values (ordinary Vhosts)
Go to **Vhosts → Edit → Security → Request Content-Type**. Enable **Block selected Content-Type values**, enter one MIME pattern per line, then **Save**. The policy is off by default and is available in the regular Vhost editor, not in the Docker vhost editor.
Example patterns:
```text
multipart/form-data
application/xml
image/*
```
- Accepts up to **64** unique patterns: exact `type/subtype` or a media family `type/*`. The policy matches case-insensitively and ignores parameters (`multipart/form-data; boundary=...` matches `multipart/form-data`). Whitespace outside a pattern is trimmed; invalid patterns and duplicates are rejected at save/validation time.
- A matching request receives **HTTP 403** before reading the body, proxying to an upstream, serving a Web Server/PHP-FPM file, choosing a Custom location or returning a cached response. When the policy is enabled, malformed, repeated or ambiguous `Content-Type` values are also denied.
- Requests with no `Content-Type` are **not blocked**. This is header filtering, not content sniffing, body inspection or a comprehensive WAF. Applications can accept unsafe input through other formats and routes.
- Blocked types cannot be used for normal requests either: blocking `multipart/form-data` disables traditional file-upload forms for the selected Vhost. Evaluate legitimate traffic before enabling and test an allowed type and a denied type.
- The policy is stored in the Vhost's `content_type_policy` object, for example `{"enabled":true,"blocked":["multipart/form-data"]}`. Existing Vhosts default to disabled. Changes are applied on the regular configuration publish cycle, without listener restart.
Check with `curl -i -H 'Content-Type: multipart/form-data; boundary=test' --data 'x' https://your-vhost.example/upload` (expected **403**) and a valid application request without the blocked type. Applying this filter is **not a fix for an underlying PHP/application vulnerability**: keep PHP, extensions and application code patched.
## Source and backends
- **Reverse Proxy:** one Vhost has a backend pool. Each member has a configured URL, ID, enabled flag, weight, optional backup/drain state, health settings and capacity limits.
- **Web Server:** Vhost references a Web Service by ID. Its document root, directory handling, PHP options and static-file headers remain configured under **Web Server**.
- **Custom locations:** can override selected URL paths and use the default pool, a pinned backend, a different Web Service, a redirect or a local response. Unmatched paths still use the main source.
Sample documents in `examples/vhosts-private.json` and `examples/vhosts-balanced.json` illustrate JSON formats, but their IP addresses, certificates and health endpoints are examples only.
## Backend connection and HTTP modes
| Setting | Use |
|---|---|
| `http1` | Standard HTTP/1.1 upstream. |
| `auto` | HTTPS negotiates HTTP/2 or HTTP/1.1; plaintext uses HTTP/1.1. |
| `http2` (legacy) | Compatible HTTPS ALPN or plaintext H2C, kept for existing configurations. |
| `h2` | Strict HTTP/2/H2C; requires origin support. |
A backend's `preserve_host` option can retain the frontend authority when appropriate. HTTPS encryption alone does not guarantee verified backend identity: `tls_verify` is **false by default**. Enable verification and configure trusted CA/name for sensitive connections. Private, loopback and RustProxy-local listener targets require explicit security exceptions; do not point a public route to the admin listener. Read [Security](SECURITY.md).
Connection reuse is bounded by configured idle-pool/recycle limits. 0.34.0 changes the default H1 upstream idle pool for newly configured Vhosts; previously saved explicit values remain. Configure timeouts to suit expected request and upload behavior; a slow origin may need more than the default response-header timeout.
## Load balancing and health
Backend pools support scheduling/weighting, standby members, draining and optional session affinity. Check the **Backends** status view for member health, recently observed HTTP response code, upstream protocol and resource usage. A reported status from normal traffic is not necessarily the result of a health probe.
- Health monitoring may use TCP or HTTP checks with a path, Host, interval and thresholds. Avoid write endpoints; use a lightweight `/health` or equivalent.
- Each member can override the pool health check or disable active/passive monitoring with `health_check_enabled=false`. Disabling checks treats the member as available, not proven healthy.
- New monitored pools can temporarily have no eligible healthy member until rise checks succeed. A failed/incorrect check can produce `503` even if the process is reachable.
- `backup` members act as fallbacks; `drain` prevents new normal selection while letting existing work complete within normal lifetimes. Explicitly pinned backends need careful policy review.
- Concurrency and queue limits protect overloaded origins. Retries are restricted; do not assume non-idempotent requests are automatically replayed.
The **Redirects** and **404 hosts** editors distinguish host identity/domains from frontend listeners and certificate selection. The configuration options have not changed.
## Hostnames, redirects and errors
- `force_ssl` redirects matching plaintext traffic to HTTPS using `308`, preserving path/query; configure both HTTP and HTTPS frontends.
- WWW controls can direct `www.example.com` to `example.com` or the opposite as supported by the editor; ensure DNS/certificate coverage for both.
- Use the dedicated **Redirects** workspace for redirect-only domains. Use **404 hosts** to claim a hostname and return a local not-found page without forwarding.
- **Custom locations** may return status/body or redirect for selected paths. **Internal locations** can be used as fallbacks for configured `403/404/500/502/503/504` application responses.
- The **Pages** section can replace supported origin error bodies without contacting a second backend. This keeps the response status and disables caching of the replaced error body.
## Safe operating practices
Keep Vhost IDs stable for monitoring/history unless renaming is intentional. Renaming may reset the runtime identity and invalidate incompatible cache objects. Confirm the deployed scheme and Host, HTTPS trust, method/access restrictions, health status and logs after saving. For per-path behavior see [Custom locations](CUSTOM_LOCATIONS.md); for policies see [Access](ACCESS.md); for caching see [Cache](CACHE.md).
## Editor layout
Within the Vhost editor, **SSL certificates** contains the named certificate selection and the explicit certificate/domain mismatch exception. The next **SSL settings** section contains the optional override of the global TLS 1.2/1.3 and cipher policy. Turning off the TLS override retains the inherited global policy. These two sections are on the same **SSL** tab.
The **Security** tab groups Traffic policy by reusable ACL profiles, HTTP methods, per-IP limits, country access, country-specific limits and User-Agent limits. It also separates HSTS, other security response headers and per-Vhost User-Agent blocking. Within **Custom locations → Access**, profile, HTTP method, country and inline IP/CIDR rules are likewise separated. **Details** separates base Vhost properties from WebSocket options; **Backends** separates balancing strategy, retry behavior and keepalive/connection reuse. The visual grouping does not change saved configuration keys or access precedence.
## Several ACL profiles and intentional TLS mismatch
Assign up to eight ACL profiles using the Vhost security tab. Explicit deny/blocked country wins, matching explicit allows combine across those profiles, and unmatched defaults must all allow. The legacy single `acl_profile_id` field still works. Inline, location and global policies are independently enforced. See [Access](ACCESS.md) for precedence and safe examples.
Normally RustProxy rejects a named certificate assigned to domains outside its DNS SubjectAltName coverage. To intentionally use such a certificate, select a **named** certificate and enable **Force an incompatible certificate** for that Vhost, then accept the confirmation. This records `allow_certificate_mismatch: true` on this Vhost only. Certificate/key matching remains mandatory, and client browsers will still warn/reject the certificate. Prefer a matching certificate; an inherited default certificate does not support this force option.