feat(cli): v3.2 multi-hop — per-hop cert, cell padding, 3-hop, CIDR whitelist
Closes the v3.1 unlinkability gap and resists volume/timing correlation:
1) Per-hop client cert (identity-unlinkable hops). [[client.circuit.hops]]
now accepts {addr, cert_path, key_path, [server_name]} per hop — each
hop sees a different CN, so a relay and an exit cannot correlate the
same client by certificate. Old flat `hops = ["ip:port"]` form still
parses (serde untagged enum) and falls back to [pki] cert/key.
`aura provision-client --circuit-hops N` mints N fresh UUIDv4 certs.
2) Cell padding. CellPaddingConn wrapper pads every outgoing packet to a
fixed size (default 1280 bytes; `cell_size = N` configurable) before
it hits the inner AEAD. Format: u16_be(real_len) || pkt || zero_pad.
On-wire sizes become constant -> defeats volume/timing fingerprints.
Opt-in via [client.circuit] cell_padding = true and the mirror
[server] cell_padding_for_circuit_clients = true.
3) 3-hop support. dial_circuit now accepts N >= 2 hops; iterative
ExtendBridge nests N-1 forwarders and N handshakes. Client owns the
full chain via CircuitConnection (forwarders abort on drop).
New integration test multihop_v3_2_three_hops_end_to_end runs three
in-process actors (A relay -> B relay -> C exit) on loopback and
verifies peer_id == C's CN.
4) CIDR whitelist. [server.relay] allow_extend_to entries accept
"10.0.0.0/24" (subnet, any port), "10.0.0.0/24:443" (subnet + port),
"[2001:db8::/32]:443" (IPv6 with port), as well as exact IP:port.
Empty list keeps the v3.1 open-relay (warn).
19 new tests; workspace 276 passed (+19), clippy -D warnings clean, fmt clean.
257 baseline tests untouched; all v2 / v3.1 / LE configs work as before.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -151,11 +151,28 @@ jitter = 0.5
|
||||
# Omitting the whole [server.relay] section (or `enabled = false`) keeps the v2 behaviour intact.
|
||||
# [server.relay]
|
||||
# enabled = true
|
||||
# Whitelist of allowed downstream exit addresses. ONLY literal IP:port entries; DNS resolution
|
||||
# is NOT performed in v3.1 (unparsable entries are logged at WARN and skipped). An empty list
|
||||
# turns this server into an OPEN relay accepting any downstream — dangerous; the runtime logs
|
||||
# a WARN on each accepted bridge.
|
||||
# Whitelist of allowed downstream destinations. v3.2 accepts three entry formats:
|
||||
# * "IP:port" — exact literal SocketAddr (the v3.1 form).
|
||||
# * "10.0.0.0/24" — bare CIDR; matches ANY port at any IP in the subnet.
|
||||
# * "10.0.0.0/24:443" — CIDR with explicit port; matches that port on any IP in the subnet.
|
||||
# * "[2001:db8::/32]:443" — square-bracket IPv6 CIDR with port.
|
||||
# * "2001:db8::/32" — bare IPv6 CIDR (any port).
|
||||
# Unparseable entries are logged at WARN and skipped. An empty list turns this server into an
|
||||
# OPEN relay accepting any downstream — dangerous; the runtime logs a WARN on each accepted bridge.
|
||||
# allow_extend_to = [
|
||||
# "198.51.100.5:443", # the exit you operate
|
||||
# "203.0.113.10:443",
|
||||
# "198.51.100.5:443", # the exit you operate (exact)
|
||||
# "203.0.113.0/24", # a whole /24 of trusted exits (any port)
|
||||
# "10.0.0.0/16:443", # a /16 of relays on port 443 only
|
||||
# ]
|
||||
#
|
||||
# v3.2 cell padding: opt-in. The relay itself does NOT decode cells — it just forwards bytes.
|
||||
# These knobs are documented here for symmetry; the actual decode happens on the EXIT (see
|
||||
# [server] cell_padding_for_circuit_clients below).
|
||||
# cell_padding = false
|
||||
# cell_size = 1280
|
||||
|
||||
# v3.2 EXIT-side cell padding. When an exit-server serves cell-padded circuit clients (i.e. the
|
||||
# clients have `[client.circuit] cell_padding = true`), add the following field to the [server]
|
||||
# block at the top of this file so the inner-handshake session's recv decodes the constant-size
|
||||
# cells and the send re-pads on the way back. Defaults to `false` for v3.1 compatibility.
|
||||
# cell_padding_for_circuit_clients = true
|
||||
|
||||
Reference in New Issue
Block a user