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.
2.3 KiB
2.3 KiB
ADR-009: Signal Handling Strategy
Status
Accepted
Context
The proxy needs to handle Unix signals for:
- Graceful shutdown: SIGTERM and SIGINT should stop accepting new connections, drain in-flight requests, then exit.
- Config reload: SIGHUP should trigger a DynamicConfig reload from disk.
Two approaches for signal handling:
tokio::signal: Built into tokio. Handles SIGTERM and SIGINT viactrl_c(). Does not directly handle SIGHUP.signal-hook: External crate. Handles all Unix signals including SIGHUP. More flexible but adds a dependency.
Decision
Use signal-hook for all signal handling. Specifically:
signal-hook::flagto set termination flags on SIGTERM/SIGINTsignal-hookto register a SIGHUP handler that triggers config reload
tokio::signal::ctrl_c() is registered as a secondary shutdown trigger; both
mechanisms converge on the same shutdown path. This is a belt-and-suspenders
approach: signal-hook handles all signals including SIGHUP, while
ctrl_c() provides a fallback for environments where signal handling may not
be fully wired (e.g., container runtimes).
The shutdown sequence:
- On SIGTERM or SIGINT: stop accepting new connections, wait up to 30 seconds for in-flight requests to complete, then exit with code 0.
- On SIGHUP: re-read config file, validate, and swap DynamicConfig if valid. Log the result.
Rationale
- SIGHUP handling is required for config reload —
tokio::signaldoesn't support SIGHUP. signal-hookis well-maintained, widely used, and handles all Unix signals.- Using one signal handling mechanism (rather than mixing
tokio::signalandsignal-hook) is simpler and avoids edge cases. signal-hook::flagis a minimal, safe API for signal-triggered flags.
Consequences
Positive:
- SIGHUP for config reload is simple and well-understood
- Single signal handling mechanism for all signals
- Compatible with systemd (SIGTERM for shutdown) and standard Unix conventions
Negative:
signal-hookis an additional dependency (but a well-established one)- Signal handling requires careful coordination with the tokio runtime (async signal receivers must be properly integrated)