Phase 1 architecture docs covering proxy handler, TLS termination (ACME + manual), TOML config with static/dynamic split (ArcSwap), and operations (rate limiting, logging, health check, systemd, graceful shutdown). Nine ADRs documenting key decisions: Rust/axum, custom proxy handler, TOML config, rustls-acme for cert management, tokio-rustls direct, token bucket rate limiting, custom log format for fail2ban, static/dynamic config split, and signal handling strategy. Includes threat landscape research documenting the nginx CVEs motivating this project.
1.9 KiB
1.9 KiB
ADR-002: Custom Proxy Handler
Status
Accepted
Context
We need to implement HTTP reverse proxying — receiving requests and forwarding them to an upstream service (Gitea on localhost:3000). Two approaches are available:
axum-reverse-proxycrate: Provides path-based routing, header forwarding, round-robin load balancing, TLS support, retry mechanisms, and RFC 9110 compliance.- Custom handler (Felix Knorr pattern): Build a handler using hyper's
Clientto forward requests. ~50-100 lines of Rust for our needs.
Our use case is minimal: single upstream per domain, single domain, no load balancing, no retry, no HTTP/2 proxying.
Decision
Implement a custom proxy handler using hyper's Client for request forwarding,
following the pattern demonstrated by Felix Knorr and used in the alknet
project's channel proxy.
Rationale
axum-reverse-proxyadds complexity we don't need (load balancing, retry, path-based routing to multiple backends)- Our proxy case is the simplest possible: match a Host header, forward the entire request to a single upstream, stream the response back
- The Felix Knorr pattern is proven, idiomatic, and ~50-100 lines
- We maintain full control over header injection, error handling, and upstream connection behavior
- If requirements grow, we can adopt
axum-reverse-proxylater
Consequences
Positive:
- Minimal dependencies
- Full control over proxy behavior
- Easy to understand and audit (~100 lines of proxy code)
- No unnecessary abstraction layers
Negative:
- We implement and maintain proxy logic ourselves (but it's trivial for our use case)
- If requirements grow to load balancing or retry, we'd need to add that
ourselves or switch to
axum-reverse-proxy
References
- proxy.md
- Felix Knorr, "Replacing nginx with axum" (felix-knorr.net/posts/2024-10-13-replacing-nginx-with-axum.html)