-
Notifications
You must be signed in to change notification settings - Fork 92
Description
Problem Statement
Applications that use WebSocket connections (e.g., Discord bots via the ws npm package) fail inside the sandbox because:
- The sandbox network namespace blocks all direct TCP/UDP via iptables REJECT rules — only traffic to the HTTP proxy (
10.200.0.1:3128) is allowed - DNS (UDP port 53) is also blocked, so
getaddrinfofails withEAI_AGAIN - WebSocket libraries (
ws,@buape/carbon) do not honorHTTPS_PROXY— they make directnet.connectcalls, bypassing the proxy entirely
HTTP-based traffic works fine because Node.js fetch (undici) respects the HTTPS_PROXY environment variable and routes through the proxy, which handles DNS resolution. But WebSocket connections fail at the DNS step since they attempt direct resolution.
This was discovered running the OpenClaw community sandbox (openshell sandbox create --from openclaw). The Discord REST API authenticates successfully through the proxy, but the Discord WebSocket gateway (gateway.discord.gg:443) fails:
[discord] logged in to discord as 1483234567400718446 (ClawBotAppNV)
[discord] discord gateway error: Error: getaddrinfo EAI_AGAIN gateway.discord.gg
[discord] gateway: WebSocket connection closed with code 1006
Confirmed:
- DNS works from the cluster node (
kubectl execcan resolvegateway.discord.gg) - The proxy accepts CONNECT tunnels to
gateway.discord.gg:443(tested withhttp.requestCONNECT, returns 200) NODE_USE_ENV_PROXY=1does not fix it (only affects undici, notws)- Setting
resolv.confto8.8.8.8or10.43.0.10doesn't help — UDP port 53 is REJECT'd by iptables
Proposed Design
Add transparent proxy redirection via iptables REDIRECT or DNAT rules in the sandbox network namespace, so that outbound TCP connections on common ports (443, 80) are transparently routed through the sandbox proxy without requiring application-level proxy support.
This would be implemented in NetworkNamespace::install_bypass_rules (crates/openshell-sandbox/src/sandbox/linux/netns.rs). Instead of (or in addition to) REJECT rules for non-proxy TCP, add:
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 3128
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 3128
The proxy would need to handle transparently redirected connections (detect the original destination via SO_ORIGINAL_DST / getsockopt). This is a standard pattern for transparent HTTP proxies.
For DNS specifically, an alternative is to run a lightweight DNS forwarder inside the sandbox namespace that forwards queries through the proxy via DNS-over-HTTPS, or to allow UDP port 53 to the cluster's CoreDNS (10.43.0.10).
Scope
- Transparent redirect for TCP 443/80 through the sandbox proxy
- DNS resolution support (either allow UDP 53 to CoreDNS, or proxy DNS)
- Policy evaluation still applies — the proxy checks OPA policies on transparently redirected connections the same as CONNECT-tunneled ones
Alternatives Considered
-
Require all applications to honor HTTPS_PROXY — Not feasible. Many libraries (WebSocket, gRPC, database drivers) make direct connections. The bypass monitor hint at
bypass_monitor.rs:96already acknowledges this gap. -
Per-application patching (e.g., Node.js
--requirepreload to monkey-patchnet.Socket) — Fragile, application-specific, and doesn't scale across languages/runtimes. -
Allow DNS (UDP 53) only — Partial fix. Would solve
getaddrinfo EAI_AGAINbut the direct TCP connection togateway.discord.gg:443would still be REJECT'd. Both DNS and transparent TCP redirect are needed. -
Run applications outside the sandbox — Defeats the purpose of sandboxing.
Agent Investigation
Investigated the sandbox network namespace implementation:
crates/openshell-sandbox/src/sandbox/linux/netns.rs:244—install_bypass_rules()installs iptables rules: ACCEPT proxy traffic, ACCEPT loopback, ACCEPT established, LOG+REJECT everything elsecrates/openshell-sandbox/src/bypass_monitor.rs:91-96— bypass monitor detects and logs blocked connections, includes hints for DNS and Node.jscrates/openshell-sandbox/src/lib.rs:259-271— network namespace creation and rule installation- Proxy CONNECT support confirmed working for
gateway.discord.gg:443— the proxy resolves DNS and tunnels successfully - The gap is between the application making a direct TCP connection and the proxy that could handle it