Skip to content

Route isolated browser UDP through egress-proxy connect-udp - #494

Draft
hiroTamada wants to merge 2 commits into
mainfrom
hypeship/isp-udp-local-proof
Draft

hiroTamada wants to merge 2 commits into
mainfrom
hypeship/isp-udp-local-proof

Conversation

@hiroTamada

@hiroTamada hiroTamada commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Opt-in headful image experiment under experiments/udp-egress. Normal images and server code are unchanged.
  • Chromium runs in its own network namespace. Its HTTP(S) goes to egress-proxy as an ordinary HTTP proxy (CONNECT with egress-proxy's MITM) through a plain TCP relay. Explicitly configured UDP destinations are captured and sent to the same egress-proxy listener as connect-udp (RFC 9298). This requires the egress-proxy change in kernel/kernel#5056.
  • The container holds no proxy credentials. egress-proxy authorizes both paths by the container's source address and relays UDP through the session's upstream with SOCKS5 UDP ASSOCIATE.
  • An independent forwarding deny rule is installed before the browser gets a route. Desktop, live-view and control traffic stay outside the browser namespace. egress-proxy's MITM CA certificate is added to the browser's NSS store at startup.
  • Replaces the earlier HTTP forwarder and in-container SOCKS5 relay; that version is the previous commit.

Validation

Run locally against an egress-proxy built from kernel/kernel#5056. It used the local development database with source auth and MITM enabled, and a stealth instance routed through a live Byteful ISP endpoint.

  • Unit tests: six Python protocol/configuration/capsule tests pass locally and during the image build.
  • Baseline: with WebRTC UDP suppressed, Chrome 152.0.7977.42 gathered no candidates. The HTTPS echo reported the ISP address with the MITM CA as issuer.
  • UDP enabled: the HTTPS echo source address, the XOR-MAPPED-ADDRESS returned by two independent STUN receivers (transaction IDs matched), and the browser's server-reflexive candidate were the same ISP address. A unique query string kept cached responses out.
  • Captures: no UDP left the container from the browser. The egress host exchanged UDP only with the provider relay, never with the STUN receivers.
  • Fail-closed: with the shim stopped, UDP disabled in egress-proxy, egress-proxy stopped, or the STUN DNAT rule removed, there were no server-reflexive candidates and no direct UDP. The deny counter incremented when DNAT was removed. HTTPS failed when egress-proxy was stopped and kept working otherwise.
  • Restarts: Chromium restart and whole-container restart passed. The container restart came back suppressed until UDP was re-enabled. An egress-proxy restart drained the open association and it reconnected immediately.
  • Revocation: invalidating the instance closed an open association, and reconnects were refused.
  • Live view: video advanced and ICE connected, including while the shim was stopped and while egress-proxy was down.

Limits

  • Disposable local experiment. The in-VM capture is not a production design.
  • UDP destinations are explicitly configured, not discovered through general transparent interception. Only IPv4 is relayed. IPv6 was unavailable in the test kernel, so IPv6 forwarding is untested.
  • Uses the repository's normal headful image, not the deployed stealth browser. One ISP provider and binding type only; no site-unblocking claim is made.

@hiroTamada hiroTamada changed the title Add isolated SOCKS5 UDP browser experiment Route isolated browser UDP through egress-proxy connect-udp Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant