- Add `WARPBOX_TRUSTED_PROXIES` configuration to restrict accepted forwarded client IP headers to specific proxy IPs/CIDRs, securing client IP resolution. - Integrate `BanService` into the background cleanup job to automatically purge expired abuse and ban evidence events. - Update documentation with reverse proxy security guidelines and a production systemd deployment guide.
1.9 KiB
Security Proxy Notes
Warpbox usually runs behind a reverse proxy such as Caddy. IP-based quotas, manual bans, and automatic bans depend on Warpbox seeing the real client IP.
Caddy
Use this shape when Caddy and Warpbox are on the same host:
warpbox.dev {
reverse_proxy 127.0.0.1:6070 {
header_up X-Forwarded-For {http.request.remote.host}
header_up X-Real-IP {http.request.remote.host}
}
}
By default, Warpbox trusts X-Forwarded-For and X-Real-IP so simple Docker,
Podman, and systemd deployments work without extra setup. This is convenient,
but it is only safe when the Warpbox port is not directly reachable by the
public internet.
Trusted Proxies
For stricter deployments, set WARPBOX_TRUSTED_PROXIES to the IPs or CIDR
ranges that are allowed to provide forwarded headers:
WARPBOX_TRUSTED_PROXIES=127.0.0.1,::1,172.16.0.0/12,10.0.0.0/8
When this value is set, Warpbox trusts X-Forwarded-For and X-Real-IP only
if the TCP peer address is inside one of those trusted ranges. Requests coming
directly from any other IP ignore forwarded headers and use the socket address.
Recommended values:
- Same-host Caddy with systemd:
127.0.0.1,::1 - Docker bridge networks: add the bridge CIDR, often
172.16.0.0/12 - Private reverse-proxy networks: add the exact private CIDR used by the proxy
Direct Exposure
If you expose Warpbox directly without Caddy, either leave
WARPBOX_TRUSTED_PROXIES empty and ensure clients cannot spoof headers at the
network edge, or set it to a value that does not include public clients. Direct
public exposure is not recommended; use a reverse proxy for TLS and request
normalization.
Ban Behavior
Active bans return:
HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
forbidden
Blocked requests are still written to the JSON logs and appear under
/admin/logs with source=ban.