fix: set NO_PROXY for host gateway to bypass Squid for MCP#554
Conversation
The iptables NAT bypass from v0.13.10 prevents DNAT redirection, but HTTP_PROXY env var still causes HTTP clients (like Codex's reqwest) to send MCP traffic through Squid as a forward proxy. Concurrent SSE connections through Squid crash it (comm.cc:1583). Set NO_PROXY with host.docker.internal and the network gateway IP when --enable-host-access is enabled, so MCP gateway traffic bypasses both DNAT and the forward proxy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges... |
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded. |
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
There was a problem hiding this comment.
Pull request overview
This PR fixes an issue where MCP (Model Context Protocol) traffic was being routed through Squid proxy despite iptables NAT bypass rules being in place. The root cause was that the HTTP_PROXY environment variable caused HTTP clients (like reqwest) to use Squid as a forward proxy, leading to Squid crashes when handling concurrent SSE (Server-Sent Events) connections from MCP.
Changes:
- Adds
NO_PROXYandno_proxyenvironment variables when--enable-host-accessis enabled - Computes the network gateway IP (first usable IP in subnet) and includes it in the NO_PROXY list
- Prevents HTTP clients from proxying MCP gateway traffic through Squid
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (config.enableHostAccess) { | ||
| // Compute the network gateway IP (first usable IP in the subnet) | ||
| const subnetBase = networkConfig.subnet.split('/')[0]; // e.g. "172.30.0.0" | ||
| const parts = subnetBase.split('.'); | ||
| const networkGatewayIp = `${parts[0]}.${parts[1]}.${parts[2]}.1`; | ||
| environment.NO_PROXY = `localhost,127.0.0.1,${networkConfig.squidIp},host.docker.internal,${networkGatewayIp}`; | ||
| environment.no_proxy = environment.NO_PROXY; | ||
| } |
There was a problem hiding this comment.
The new NO_PROXY environment variable configuration lacks test coverage. Consider adding a test case in the 'enableHostAccess option' describe block in docker-manager.test.ts to verify that both NO_PROXY and no_proxy are set correctly when enableHostAccess is true, and that they include all the expected hosts (localhost, 127.0.0.1, squid IP, host.docker.internal, and the computed network gateway IP).
Adds NO_PROXY for host gateway IPs to fully bypass Squid for MCP traffic. See github/gh-aw-firewall#554 for details. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
NO_PROXY/no_proxyenv vars when--enable-host-accessis enabledhost.docker.internal, network gateway IP (172.30.0.1), Squid IP, and localhostRoot Cause
v0.13.10 added iptables NAT bypass for 172.30.0.1, which prevents DNAT redirection. But the
HTTP_PROXYenv var still causes HTTP clients to send MCP traffic through Squid as a forward proxy. Concurrent MCP Streamable HTTP (SSE) connections through Squid's forward proxy triggercomm.cc:1583assertion failure and Squid segfaults.Evidence from smoke-codex CI (v0.13.10)
The iptables bypass IS working:
But MCP connections still fail because reqwest uses HTTP_PROXY:
Local Verification
With NO_PROXY set, curl confirms direct bypass:
SSE streams work, concurrent SSE+POSTs complete, Squid stays alive.
Test plan
🤖 Generated with Claude Code