get2knowio / get2knowio/deacon
auto-forward: optional non-loopback (0.0.0.0/LAN) bind, opt-in + security review
- Dominant language
- Rust
- Stars
- 2
- Forks
- 0
- Avg merge
- 2h 36m
- Merged PRs (30d)
- 78
Description
Tracked deferral from `up --auto-forward` (spec `015-auto-forward-ports`, task **T057**; shipped in #188). v1 binds **loopback only**; this adds an explicit opt-in to bind a non-loopback address.
## Goal / acceptance
An explicit opt-in binds host listeners on `0.0.0.0` (or a chosen interface) so other machines on the LAN can reach the forwarded service directly, with a documented security review.
## Hidden issues / gotchas
- **It's a deliberate security downgrade.** v1's `127.0.0.1`-only bind (`crates/core/src/port_forward/registry.rs::try_reserve`, hard-coded `"127.0.0.1"`) is what keeps a container's services off the network. Binding `0.0.0.0` exposes them to anyone routable to the host. Must be **off by default, opt-in, and loud.**
- **Privileged-port story still applies.** We always remap `<1024` to `>=1024` to avoid host root; LAN exposure doesn't change that.
- **Most "remote access" use cases don't need this.** Reaching a forwarded port from a laptop is better done over SSH (`ssh -L laptop:127.0.0.1:host you@devhost`) — SSH resolves the target on the remote host's loopback, so the existing loopback bind already works and stays private. LAN bind is only for *direct, un-tunneled* access by other hosts (teammate on the same network, a phone testing a mobile build).
- **Event-reporting/contract:** `host_ip` in `PORT_EVENT` and the registry/`contracts/*.schema.json` assume `127.0.0.1`; a non-loopback bind must thread the real bind address through reporting (the stderr mapping line and `PortEvent.host_ip`).
## Recommended path forward
1. Add an explicit flag, e.g. `--auto-forward-bind <127.0.0.1|0.0.0.0|IP>` (default `127.0.0.1`), threaded into `registry::allocate`/`try_reserve` and the daemon's dial/report paths.
2. Emit a one-time **WARN** when binding non-loopback, and document the exposure + the SSH-tunnel alternative in `README.md` / `SECURITY.md` (extend the existing "Dynamic port forwarding" section).
3. Update `PORT_EVENT.host_ip` + the stderr mapping line + registry schema docs to carry the actual bind address.
4. Docker integration test: bind `0.0.0.0`, assert reachable via a non-loopback host IP; assert default stays loopback-only.
## Security
Requires security review per the spec's Out-of-Scope note. Recommend defaulting off and gating behind the explicit flag only (no env-var/implicit enablement).
Contributor guide
Assessment
This issue has not been assessed yet.