Resolve open questions: - OQ-01: Restrict cipher suites to match nginx scope (4 ECDHE-AES-GCM suites for TLS 1.2 + all TLS 1.3 suites) — ADR-012 - OQ-03: Health check on separate local port (default 9900, localhost only) — ADR-013 - OQ-04: Add Unix domain socket admin API for config reload alongside SIGHUP, with structured success/failure responses — ADR-014 - OQ-06: Per-site upstream timeouts with defaults (5s connect, 60s request), overridable in SiteConfig — ADR-015 Document previously undocumented decisions flagged by architecture review: - ADR-016: Explicit bind address requirement (reject 0.0.0.0) - ADR-017: Upstream connection defaults (HTTP/1.1, no redirects, pooling) - ADR-018: 100 MB body size limit (matches nginx, Gitea compatibility) OQ-07 (per-site TLS overrides) remains open for future consideration. Spec updates: - config.md: add health_check_port, admin_socket_path, per-site timeout fields, update TOML example and validation rules - proxy.md: reference ADR-015/017/018 for timeouts, connection defaults, and body limit decisions - tls.md: replace OQ-01 cipher suite section with ADR-012 decision - operations.md: add local health check port section, admin socket reload - overview.md: update Phase 1 scope with new features, add ADR references - open-questions.md: resolve OQ-01/03/04/06, keep OQ-07 open
1.9 KiB
1.9 KiB
ADR-016: Explicit Bind Address Requirement
Status
Accepted
Context
The proxy's bind_addr configuration field specifies the IP address to bind
to. The default for most network services is 0.0.0.0 (bind all interfaces),
which means the service is accessible on every network interface, including
public-facing ones.
For a reverse proxy that terminates TLS and handles security-sensitive traffic, binding to all interfaces is risky. The proxy should only listen on the intended interface(s) — typically a specific public IP for a single-server deployment.
Decision
The bind_addr field must be an explicit IP address. 0.0.0.0 is rejected
during config validation. The proxy will not start if bind_addr is 0.0.0.0.
Rationale
- A reverse proxy terminating TLS is a security boundary — it should not be accidentally exposed on unintended interfaces
- Single-server deployments have a specific public IP; binding to it deliberately is the correct operational practice
0.0.0.0is often a default in example configurations and can be deployed without the operator realizing the service is accessible on all interfaces- Rejecting it at validation time prevents this common mistake
- If a deployment genuinely needs to bind all interfaces,
0.0.0.0can be overridden with an explicit flag, but this should be a deliberate choice - This matches the principle of explicit over implicit for security-sensitive configuration
Consequences
Positive:
- Prevents accidental exposure on unintended network interfaces
- Forces operators to be deliberate about which interface the proxy serves
- Config validation catches the mistake before deployment
Negative:
- Not suitable for deployments that genuinely need to bind all interfaces (mitigated by explicit override if needed in the future)
- Slightly more configuration required (operator must know their public IP)