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
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-06-11 |
Reverse Proxy — Architecture
Current State
Phase 0 (Exploration) — Complete. Phase 1 (Architecture) — In progress.
This project replaces our vulnerable nginx 1.24.0 installation with a memory-safe Rust/axum reverse proxy. The primary motivation is CVE-2026-42945 (unauthenticated RCE in nginx's rewrite module) and the broader pattern of memory corruption bugs in nginx's C codebase.
The proxy supports multiple domains from initial release (git.alk.dev and alk.dev), with per-domain host-based routing and a single multi-domain SAN certificate via ACME.
Architecture Documents
| Document | Status | Description |
|---|---|---|
| overview.md | Draft | Vision, scope, crate dependencies, exports |
| proxy.md | Draft | Reverse proxy handler, request flow, header injection |
| tls.md | Draft | TLS termination, ACME, manual certs, SNI |
| config.md | Draft | TOML config format, static/dynamic split, ArcSwap reload |
| operations.md | Draft | Rate limiting, logging, health check, systemd, shutdown |
ADR Table
| ADR | Title | Status |
|---|---|---|
| 001 | Rust with Axum | Accepted |
| 002 | Custom Proxy Handler | Accepted |
| 003 | TOML Configuration Format | Accepted |
| 004 | ACME-Primary Certificate Management | Accepted |
| 005 | tokio-rustls Directly, Not axum-server | Accepted |
| 006 | Token Bucket Rate Limiting | Accepted |
| 007 | Custom Structured Log Format | Accepted |
| 008 | Static/Dynamic Config Split with ArcSwap | Accepted |
| 009 | Signal Handling Strategy | Accepted |
| 010 | Multi-Site Support in Phase 1 | Accepted |
| 011 | Multi-Domain TLS Configuration | Accepted |
| 012 | Restrict Cipher Suites to nginx Scope | Accepted |
| 013 | Health Check on Separate Local Port | Accepted |
| 014 | Unix Domain Socket Config Reload API | Accepted |
| 015 | Per-Site Upstream Timeouts with Defaults | Accepted |
| 016 | Explicit Bind Address Requirement | Accepted |
| 017 | Upstream Connection Defaults | Accepted |
| 018 | Request Body Size Limit | Accepted |
Open Questions
See open-questions.md for the full tracker.
| OQ | Question | Priority | Status |
|---|---|---|---|
| resolved (ADR-012) | |||
| resolved (ADR-007) | |||
| resolved (ADR-013) | |||
| resolved (ADR-014) | |||
| resolved (single bind_addr sufficient) | |||
| resolved (ADR-015) | |||
| OQ-07 | Should per-site TLS overrides be supported for mixed ACME/manual domains? | low | open |
Document Lifecycle
| Status | Meaning | Transitions |
|---|---|---|
draft |
Under active development. May change significantly. | → reviewed when open questions are resolved |
reviewed |
Architecture is final. Implementation may begin. Changes require review. | → stable when implementation is complete |
stable |
Locked. Changes require review and may warrant an ADR. | → deprecated when superseded |
deprecated |
Superseded. Kept for reference. | Removed when no longer referenced |