Resolve 5 open questions, add 7 ADRs for previously undocumented decisions
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
This commit is contained in:
53
docs/architecture/decisions/016-explicit-bind-address.md
Normal file
53
docs/architecture/decisions/016-explicit-bind-address.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 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.0` is 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.0` can 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)
|
||||
|
||||
## References
|
||||
|
||||
- [config.md](../config.md)
|
||||
- [overview.md](../overview.md)
|
||||
Reference in New Issue
Block a user