Skip to content

Node has no per-IP flood defense before the TLS handshake + cover proxy #186

Description

@davvd

The node's only overload protection is a single global socket cap: the intake counter is capped at capacity*2 (default 50 -> 100 sockets) in node/internal/server/server.go:181 (s.intake.enter closes anything over the cap; newIntake at server.go:77, logic in node/internal/server/intake.go), plus a soft client cap that returns an "overloaded" welcome once roster.count() >= capacity (server.go:249). There is no per-IP rate limit, connection throttle, cryptographic cookie, or proof-of-work anywhere — node/internal/server/connections.go only counts /proc/net/tcp for telemetry and enforces nothing.

This is a real availability gap because every unauthenticated or foreign connection still gets a full TLS handshake and is then bridged to the real cover site (node/internal/server/gate.go:63, cover.go, proxy.go) — expensive CPU plus an outbound connection per bogus client. A flood of valid-looking ClientHellos from a censor's active prober therefore consumes handshake + cover-bridge work all the way up to the 100-socket ceiling and locks out real clients, at no cost to the attacker. WireGuard handles this with its cookie mechanism: it stays silent without a valid MAC1 and, under load, demands MAC2 = a cookie bound to the initiator's source IP (server_secret rotated every 120s, cookie AEAD-encrypted), which proves source-IP ownership cheaply and enables token-bucket per-IP rate limiting (wireguard-go device/cookie.go).

Add a per-source-IP token bucket in the pre-handshake gate (node/internal/server/gate.go, where reality.Inspect runs) that sheds or delays connections from an IP exceeding a rate, before the full TLS handshake and cover proxy are committed. We cannot go silent like WireGuard without breaking the HTTPS cover, but capping per-IP handshake+proxy spend stops one source from exhausting the global socket budget; keep the cover-bridge behavior for connections within the allowed rate. Filing per a WireGuard comparison review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions