diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-13 04:10:14 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-13 04:10:14 +0200 |
| commit | ed9fb22ed703db38f9b07c00d17076f90aa4cbc8 (patch) | |
| tree | 448af8bdc7734798607bb33735c2a8439c362c13 /packages/meshbay-node/src/meshbay_node/config.py | |
| parent | ee6573c57f721db8550e34e1c1c79c5922c62a4b (diff) | |
| download | meshbay-ed9fb22ed703db38f9b07c00d17076f90aa4cbc8.tar.gz | |
fix(node)!: remove unauthenticated HTTP file API and TCP transport
Phase 11.5.A — findings C1 and C6 (see second-review.md).
C1: the per-group HTTP file API bound 0.0.0.0 for every configured group,
private ones included, and served two endpoints with no authentication at all:
GET /index (full Mesh Group Index) and GET /file/{id} (raw plaintext file via
FileResponse). Anyone able to reach the port — LAN, forwarded port, permissive
IPv6 — read every private file. This bypassed the entire GEK-proof and node
sovereignty layer. Deleted rather than patched: it duplicated MNP without any
of its controls.
C6: the TCP+TLS chunk server accepted a bare JWT with no GEK proof, leaving a
second non-compliant handshake path. Deleted; QUIC remains and will be brought
to parity with WebRTC by the unified handshake in 11.5.4.
Transport decision recorded in transport/__init__.py: WebRTC/ICE is primary for
browser and native clients (the only NAT traversal validated here — 2 ISPs,
IPv4 STUN + IPv6, 4G CGNAT); QUIC is kept for LAN, port-forwarded and hub-less
group:// access. punch_nat() is a direct-connection helper, not a traversal
stack.
Also removed server_ssl_context()/client_ssl_context() from tls_cert.py (no
remaining callers) and a dead import of the former in quic_server.py.
generate_self_signed_cert() stays: QUIC uses it, and the certificate hash is
the intended channel-binding anchor for 11.5.6, since QUIC has no DTLS
fingerprint to bind the GEK proof to.
BREAKING CHANGE: node.toml keys `port` and `http_port` are gone. Regenerate
config with `meshbay-node init`. Env var MESHBAY_PORT -> MESHBAY_QUIC_PORT.
Tests: 198 passed (209 - 7 test_http_server - 4 test_transport). No other test
changed status. Net -1300 lines.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/config.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/config.py | 29 |
1 files changed, 10 insertions, 19 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/config.py b/packages/meshbay-node/src/meshbay_node/config.py index a7a0785..b681355 100644 --- a/packages/meshbay-node/src/meshbay_node/config.py +++ b/packages/meshbay-node/src/meshbay_node/config.py @@ -26,27 +26,24 @@ url = "https://meshbay.org" username = "myusername" [node] -port = 19000 # TCP+TLS (MNP v1) -quic_port = 19010 # QUIC (MNP v2) -http_port = 19001 # HTTP file API (public content) -ui_port = 18000 # local web UI +quic_port = 19010 # QUIC (MNP) — LAN, port-forwarded, hub-less direct access +ui_port = 18000 # local admin UI (127.0.0.1 only) -# Multiple groups — each with its own directory and ports +# Browser and native clients reach this node over WebRTC DataChannel via hub +# signaling — no inbound port to open. QUIC is the optional direct path. + +# Multiple groups — each with its own directory [[groups]] id = "" # set after joining name = "My Media" shared_dir = "/home/user/Media" -port = 19000 quic_port = 19010 -http_port = 19001 [[groups]] id = "" name = "Public Archive" shared_dir = "/home/user/Archive" -port = 19002 quic_port = 19012 -http_port = 19003 visibility = "public" [keystore] @@ -68,9 +65,7 @@ class HubConfig: @dataclass class NodeConfig: - port: int = 19000 quic_port: int = 19010 - http_port: int = 19001 ui_port: int = 18000 @@ -80,9 +75,7 @@ class GroupConfig: name: str = "" shared_dir: str = "" visibility: str = "private" # public|private - port: int = 19000 # TCP+TLS MNP port for this group quic_port: int = 19010 # QUIC MNP port - http_port: int = 19001 # HTTP file API port @dataclass @@ -121,9 +114,9 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: cfg.hub.username = hub.get("username", cfg.hub.username) nd = raw.get("node", {}) - cfg.node.port = nd.get("port", cfg.node.port) + # `port` (TCP+TLS) and `http_port` no longer exist — both listeners were removed + # in Phase 11.5 (findings C1, C6). Regenerate node.toml with `meshbay-node init`. cfg.node.quic_port = nd.get("quic_port", cfg.node.quic_port) - cfg.node.http_port = nd.get("http_port", cfg.node.http_port) cfg.node.ui_port = nd.get("ui_port", cfg.node.ui_port) # Multi-group: [[groups]] array @@ -134,9 +127,7 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: name=g.get("name", ""), shared_dir=g.get("shared_dir", ""), visibility=g.get("visibility", "private"), - port=g.get("port", cfg.node.port), quic_port=g.get("quic_port", cfg.node.quic_port), - http_port=g.get("http_port", cfg.node.http_port), )) # Back-compat: single [group] section elif "group" in raw: @@ -163,8 +154,8 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config: cfg.hub.url = url if user := os.environ.get("MESHBAY_USERNAME"): cfg.hub.username = user - if port := os.environ.get("MESHBAY_PORT"): - cfg.node.port = int(port) + if port := os.environ.get("MESHBAY_QUIC_PORT"): + cfg.node.quic_port = int(port) return cfg |