Files
reverse-proxy/docs/architecture
glm-5.1 ceb59ad9b9 Resolve all architecture review findings (7 critical, 14 warnings, 6 suggestions)
Critical findings resolved:
- C1: Site routing is global (per-listener TOML, global runtime lookup)
- C2: X-Forwarded-For replaces (not appends) — edge proxy model (ADR-021)
- C3: Hop-by-hop header handling rules specified (proxy.md)
- C4: ACME failure behavior defined (tls.md)
- C5: Startup sequence with fail-fast semantics (operations.md)
- C6: Per-listener Router instances with shared global state (overview.md)
- C7: Rate limiter adopts new params on next request, no state clear (operations.md)

Warnings resolved:
- W1: Admin socket wire protocol specified
- W2: Host header port stripped, hostnames only in config
- W3: HTTP redirect URL construction with port handling
- W4: /health on HTTPS matches regardless of Host header
- W5: Static config changes logged as warning during reload
- W6: Reload operations serialized via Mutex
- W7: http_port validation rules added (9 new rules total)
- W8: upstream format validation (host:port required, no scheme)
- W9: TLS error handling table (SNI, version, cipher failures)
- W10: IPv6 rate limited per /64 prefix
- W11: Graceful shutdown sequence specified (6 steps)
- W12: Error response bodies: minimal plain text, no version disclosure
- W13: upstream_scheme HTTPS uses system CA store
- W14: allow_wildcard_bind is OR between config and CLI
- W15: ADR-010 Phase 2 list updated (timeouts moved to Phase 1)
- W17: LoggingConfig static/restart note added

Suggestions applied:
- S2: ConnectInfo propagation note
- S3: Case-insensitive host matching (RFC 7230)
- S5: Response streaming behavior (chunk-by-chunk)
- S6: Token bucket nodelay semantics
- S7: File watching explicitly out of scope
- S8: All paths forwarded without filtering
- S9: shutdown_timeout_secs referenced in shutdown description
- S11: Consolidated defaults table in config.md
2026-06-11 10:56:40 +00:00
..

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
019 Multi-Config Listener Support Accepted
020 Container Deployment Model Accepted
021 X-Forwarded-For Edge Proxy Model Accepted

Open Questions

See open-questions.md for the full tracker.

OQ Question Priority Status
OQ-01 Should cipher suites be restricted beyond rustls defaults? medium resolved (ADR-012)
OQ-02 What log format should fail2ban consume? high resolved (ADR-007)
OQ-03 Should the health check endpoint be on a separate port? low resolved (ADR-013)
OQ-04 Config reload: SIGHUP only or also Unix socket API? low resolved (ADR-014)
OQ-05 Should the proxy bind to multiple addresses? low resolved (single bind_addr sufficient)
OQ-06 Should upstream timeouts be configurable per-site? low resolved (ADR-015)
OQ-07 Should per-site TLS overrides be supported for mixed ACME/manual domains? low resolved (ADR-019)

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