fix(deploy): the tunnel's door binds loopback only (P9a)
Review finding: `--http` parsed whatever address it was given and bound it. The door is the plaintext MCP service with a static bearer token; plan 3.9 and the P9a model put a TLS proxy or tunnel in front of a loopback listener, and no decision authorises exposing the books unencrypted. `--http 0.0.0.0:7411` would have done exactly that. `local::tunnel_address` now accepts only a loopback address (127.0.0.0/8 or ::1; `127.0.0.1:7411` stays the default) and refuses anything else with a message naming loopback and why. `server` refuses while parsing, before it takes the lock or binds a socket; `serve` refuses before it starts a host, so nothing is left half-open. The bind-failure behaviour for a loopback address is unchanged (said, not fatal, 3.9), as is the unit's hardening. The test `the_tunnel_door_binds_loopback_only` refuses 0.0.0.0, a public sample address and [::] through `server`, checks no socket or host was left behind, refuses through `serve`, then starts a loopback listener and reaches `books.start` with the bearer. No accounting code, report or figure changes.
This commit is contained in:
1 parent
47951e5734
commit
c8541ea9fc
7 files changed
+156
-29
No files matched your search
+16
-8
@@ -2993,6 +2993,11 @@ loopback door (`--http`) for Caddy or a tunnel.
|
||||
already running keeps the flags it was started with (documented in
|
||||
`deploy/README.md` and the opener's comment).
|
||||
- **`crates/ledger-cli/tests/two_user.rs`:**
|
||||
`the_tunnel_door_binds_loopback_only` (a network address — `0.0.0.0`,
|
||||
a public sample address, `[::]` — is refused by `server` with a message
|
||||
naming loopback, before any socket or lock exists, and by `serve` before
|
||||
a host starts; a loopback address still starts and answers with the
|
||||
bearer);
|
||||
`isolation_label_is_enforced_under_the_unit` (a server with no flag says
|
||||
`same_user (advisory)`; with `--isolation enforced --http` it says
|
||||
`service_user (enforced)` over the Unix socket and over the loopback
|
||||
@@ -3034,11 +3039,14 @@ loopback door (`--http`) for Caddy or a tunnel.
|
||||
would report the advisory truth on the enforced machine);
|
||||
`Isolation::label`'s two strings; `start_out`'s `self.isolation.label()`
|
||||
(it replaced a literal, and a mutant that restores a literal must fail the
|
||||
two-door test); the `--http` arm's `args.peek()` guard and the default
|
||||
`127.0.0.1:7411` (binding the wrong interface, or consuming the next flag,
|
||||
must fail); `tunnel.is_some()` and the bind failure path (ready must still
|
||||
come after the try, and a failed bind must not be fatal); `open_with`'s
|
||||
`isolation` into `Served` and `BooksServer::new`'s copy (a dropped field
|
||||
must fail `isolation_label_is_enforced_under_the_unit`); the host's
|
||||
`server_flags` extension and `parse_args`' passthrough of `--isolation`
|
||||
and its optional `--http` value.
|
||||
two-door test); `local::tunnel_address`'s `is_loopback` test (a mutant
|
||||
that accepts any address must fail `the_tunnel_door_binds_loopback_only`,
|
||||
and one that rejects loopback must fail its second half); the `--http`
|
||||
arm's `args.peek()` guard and the default `127.0.0.1:7411` (binding the
|
||||
wrong interface, or consuming the next flag, must fail); `tunnel.is_some()`
|
||||
and the bind failure path (ready must still come after the try, and a
|
||||
failed bind must not be fatal); `open_with`'s `isolation` into `Served`
|
||||
and `BooksServer::new`'s copy (a dropped field must fail
|
||||
`isolation_label_is_enforced_under_the_unit`); the host's `server_flags`
|
||||
extension and `parse_args`' passthrough of `--isolation` and its optional
|
||||
`--http` value.
|
||||
Reference in new issue
Block a user