Skip to content

Commit 850e7a0

Browse files
lpcoxCopilotCopilot
authored
fix: disable IPv6 in agent container to prevent squid proxy bypass (#1544)
* fix: disable IPv6 in agent container to prevent squid proxy bypass Always disable IPv6 via sysctl in setup-iptables.sh regardless of ip6tables availability. The awf-net Docker network is IPv4-only and Squid only listens on IPv4, so IPv6 serves no purpose in the agent container. Leaving it enabled causes Node.js happy-eyeballs to prefer IPv6, resulting in connections to ::1 that Squid rejects with transaction-end-before-headers. Also add IPv6 listeners to Squid config (http_port [::]:3128) as defense-in-depth, so any residual IPv6 traffic is handled rather than silently rejected. Closes #1543 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update src/squid-config.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update containers/agent/setup-iptables.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent b4acb6b commit 850e7a0

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

containers/agent/setup-iptables.sh

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,23 @@ IP6TABLES_AVAILABLE=false
3131
if has_ip6tables; then
3232
IP6TABLES_AVAILABLE=true
3333
echo "[iptables] ip6tables is available"
34-
else
35-
echo "[iptables] WARNING: ip6tables is not available, disabling IPv6 via sysctl to prevent unfiltered bypass"
36-
sysctl -w net.ipv6.conf.all.disable_ipv6=1 2>/dev/null || echo "[iptables] WARNING: failed to disable IPv6 (net.ipv6.conf.all.disable_ipv6)"
37-
sysctl -w net.ipv6.conf.default.disable_ipv6=1 2>/dev/null || echo "[iptables] WARNING: failed to disable IPv6 (net.ipv6.conf.default.disable_ipv6)"
3834
fi
3935

36+
# Always disable IPv6 in the agent network namespace.
37+
# The Docker awf-net network and our iptables DNAT rules are IPv4-based, so
38+
# IPv6 connectivity would serve mainly as a way to bypass those controls.
39+
# Disabling IPv6 here:
40+
# 1. Removes IPv6 addresses/routes so traffic cannot egress over IPv6 paths
41+
# 2. Prevents IPv6 connections (including ::1 loopback) that would not be
42+
# intercepted by IPv4-only iptables DNAT rules to the Squid proxy
43+
# 3. Avoids applications preferring IPv6 paths that would bypass or conflict
44+
# with the intended IPv4 proxy/NAT behavior (e.g., Happy Eyeballs)
45+
# Note: This does not change upstream DNS responses; it only disables IPv6
46+
# connectivity inside the container. See: https://github.com/github/gh-aw-firewall/issues/1543
47+
echo "[iptables] Disabling IPv6 inside container to prevent IPv6 egress / proxy bypass..."
48+
sysctl -w net.ipv6.conf.all.disable_ipv6=1 2>/dev/null || echo "[iptables] WARNING: failed to disable IPv6 (net.ipv6.conf.all.disable_ipv6)"
49+
sysctl -w net.ipv6.conf.default.disable_ipv6=1 2>/dev/null || echo "[iptables] WARNING: failed to disable IPv6 (net.ipv6.conf.default.disable_ipv6)"
50+
4051
# Get Squid proxy configuration from environment
4152
SQUID_HOST="${SQUID_PROXY_HOST:-squid-proxy}"
4253
SQUID_PORT="${SQUID_PROXY_PORT:-3128}"

src/squid-config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,19 @@ function generateSslBumpSection(
183183
184184
# HTTP port with SSL Bump enabled for HTTPS interception
185185
# This handles both HTTP requests and HTTPS CONNECT requests
186+
# Listen on both IPv4 and IPv6 as defense-in-depth (see: gh-aw-firewall issue #1543)
186187
http_port 3128 ssl-bump \\
187188
cert=${caFiles.certPath} \\
188189
key=${caFiles.keyPath} \\
189190
generate-host-certificates=on \\
190191
dynamic_cert_mem_cache_size=16MB \\
191192
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1
193+
http_port [::]:3128 ssl-bump \\
194+
cert=${caFiles.certPath} \\
195+
key=${caFiles.keyPath} \\
196+
generate-host-certificates=on \\
197+
dynamic_cert_mem_cache_size=16MB \\
198+
options=NO_SSLv3,NO_TLSv1,NO_TLSv1_1
192199
193200
# SSL certificate database for dynamic certificate generation
194201
# Using 16MB for certificate cache (sufficient for typical AI agent sessions)
@@ -420,7 +427,8 @@ export function generateSquidConfig(config: SquidConfig): string {
420427
// Port configuration: Use normal proxy mode (not intercept mode)
421428
// With targeted port redirection in iptables, traffic is explicitly redirected
422429
// to Squid on specific ports (80, 443, + user-specified), maintaining defense-in-depth
423-
let portConfig = `http_port ${port}`;
430+
// Listen on both IPv4 and IPv6 as defense-in-depth (see #1543)
431+
let portConfig = `http_port ${port}\nhttp_port [::]:${port}`;
424432

425433
// For SSL Bump, we need to check hasPlainDomains and hasPatterns for the 'both' protocol domains
426434
// since those are the ones that go into allowed_domains / allowed_domains_regex ACLs

0 commit comments

Comments
 (0)