# 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:

```Caddyfile
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. Use proxy IPs only.

```env
WARPBOX_TRUSTED_PROXIES=127.0.0.1,::1,172.30.0.1
```

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/Podman bridge gateway: add the exact gateway IP, for example `172.30.0.1`
- Docker bridge networks: use a CIDR such as `172.16.0.0/12` only if the exact gateway changes often
- Private reverse-proxy networks: add the exact private CIDR used by the proxy

Warpbox prefers the first public address in `X-Forwarded-For` when a trusted
proxy sends a chain. Loopback addresses and trusted proxy addresses are also
protected from manual and automatic bans so a bad header setup cannot ban Caddy,
the container gateway, or Warpbox itself.

## 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.

## Large Uploads

Multi-GB uploads must not use whole-body read/write deadlines. Keep these
Warpbox values for production unless you intentionally want a hard wall-clock
upload limit:

```env
WARPBOX_READ_HEADER_TIMEOUT=15s
WARPBOX_READ_TIMEOUT=0s
WARPBOX_WRITE_TIMEOUT=0s
```

`WARPBOX_READ_HEADER_TIMEOUT` protects request headers. `WARPBOX_READ_TIMEOUT`
and `WARPBOX_WRITE_TIMEOUT` cover the whole upload/response lifetime in Go, so
small values can cause browser errors such as `NS_ERROR_NET_INTERRUPT` during
large transfers. Upload size, daily, storage, and box limits still enforce abuse
controls independently of these timeout values.

## Ban Behavior

Active bans return:

```text
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`.
