Skip to content

Commit 54fd26e

Browse files
Mossakaclaude
andauthored
fix: remove HTTP_PROXY/HTTPS_PROXY env vars from agent container (#524)
Intercept mode (iptables DNAT 80/443 → squid:3129) handles all routing transparently. Port 3128 is unreachable from the agent container, causing Codex (Rust/reqwest) to fail with "Connection refused" when it honors the HTTP_PROXY env var. - Remove HTTP_PROXY/HTTPS_PROXY from the agent container environment - Add proxy vars (upper and lowercase) to EXCLUDED_ENV_VARS to prevent host proxy settings from leaking via --env-all - Update entrypoint.sh logging to reflect intercept mode - Users can still override via --env HTTP_PROXY=... if needed Fixes #523 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6b94b0b commit 54fd26e

3 files changed

Lines changed: 60 additions & 7 deletions

File tree

containers/agent/entrypoint.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,13 @@ fi
115115
/usr/local/bin/setup-iptables.sh
116116

117117
# Print proxy environment
118-
echo "[entrypoint] Proxy configuration:"
119-
echo "[entrypoint] HTTP_PROXY=$HTTP_PROXY"
120-
echo "[entrypoint] HTTPS_PROXY=$HTTPS_PROXY"
118+
echo "[entrypoint] Proxy configuration: intercept mode (iptables DNAT 80/443 -> squid:${SQUID_INTERCEPT_PORT})"
119+
if [ -n "$HTTP_PROXY" ]; then
120+
echo "[entrypoint] HTTP_PROXY=$HTTP_PROXY (user-provided)"
121+
fi
122+
if [ -n "$HTTPS_PROXY" ]; then
123+
echo "[entrypoint] HTTPS_PROXY=$HTTPS_PROXY (user-provided)"
124+
fi
121125

122126
# Print network information
123127
echo "[entrypoint] Network information:"

src/docker-manager.test.ts

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,12 @@ describe('docker-manager', () => {
479479
const agent = result.services.agent;
480480
const env = agent.environment as Record<string, string>;
481481

482-
expect(env.HTTP_PROXY).toBe('http://172.30.0.10:3128');
483-
expect(env.HTTPS_PROXY).toBe('http://172.30.0.10:3128');
482+
// HTTP_PROXY/HTTPS_PROXY are NOT set; intercept mode (iptables DNAT) handles routing
483+
expect(env.HTTP_PROXY).toBeUndefined();
484+
expect(env.HTTPS_PROXY).toBeUndefined();
484485
expect(env.SQUID_PROXY_HOST).toBe('squid-proxy');
485486
expect(env.SQUID_PROXY_PORT).toBe('3128');
487+
expect(env.SQUID_INTERCEPT_PORT).toBe('3129');
486488
});
487489

488490
it('should mount required volumes in agent container (default behavior)', () => {
@@ -925,6 +927,51 @@ describe('docker-manager', () => {
925927
}
926928
});
927929

930+
it('should exclude proxy env vars when envAll is enabled', () => {
931+
const originalHttpProxy = process.env.HTTP_PROXY;
932+
const originalHttpsProxy = process.env.HTTPS_PROXY;
933+
const originalHttpProxyLower = process.env.http_proxy;
934+
const originalHttpsProxyLower = process.env.https_proxy;
935+
936+
process.env.HTTP_PROXY = 'http://host-proxy:8080';
937+
process.env.HTTPS_PROXY = 'http://host-proxy:8080';
938+
process.env.http_proxy = 'http://host-proxy:8080';
939+
process.env.https_proxy = 'http://host-proxy:8080';
940+
941+
try {
942+
const configWithEnvAll = { ...mockConfig, envAll: true };
943+
const result = generateDockerCompose(configWithEnvAll, mockNetworkConfig);
944+
const env = result.services.agent.environment as Record<string, string>;
945+
946+
// Proxy vars must NOT leak from host (intercept mode handles routing)
947+
expect(env.HTTP_PROXY).toBeUndefined();
948+
expect(env.HTTPS_PROXY).toBeUndefined();
949+
expect(env.http_proxy).toBeUndefined();
950+
expect(env.https_proxy).toBeUndefined();
951+
} finally {
952+
if (originalHttpProxy !== undefined) {
953+
process.env.HTTP_PROXY = originalHttpProxy;
954+
} else {
955+
delete process.env.HTTP_PROXY;
956+
}
957+
if (originalHttpsProxy !== undefined) {
958+
process.env.HTTPS_PROXY = originalHttpsProxy;
959+
} else {
960+
delete process.env.HTTPS_PROXY;
961+
}
962+
if (originalHttpProxyLower !== undefined) {
963+
process.env.http_proxy = originalHttpProxyLower;
964+
} else {
965+
delete process.env.http_proxy;
966+
}
967+
if (originalHttpsProxyLower !== undefined) {
968+
process.env.https_proxy = originalHttpsProxyLower;
969+
} else {
970+
delete process.env.https_proxy;
971+
}
972+
}
973+
});
974+
928975
it('should configure DNS to use Google DNS', () => {
929976
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
930977
const agent = result.services.agent;

src/docker-manager.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,16 @@ export function generateDockerCompose(
319319
'SUDO_USER', // Sudo metadata
320320
'SUDO_UID', // Sudo metadata
321321
'SUDO_GID', // Sudo metadata
322+
'HTTP_PROXY', // Intercept mode handles routing; explicit proxy is unreachable
323+
'HTTPS_PROXY', // Intercept mode handles routing; explicit proxy is unreachable
324+
'http_proxy', // Lowercase variant
325+
'https_proxy', // Lowercase variant
322326
]);
323327

324328
// Start with required/overridden environment variables
325329
// For chroot mode, use the real user's home (not /root when running with sudo)
326330
const homeDir = config.enableChroot ? getRealUserHome() : (process.env.HOME || '/root');
327331
const environment: Record<string, string> = {
328-
HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
329-
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
330332
SQUID_PROXY_HOST: 'squid-proxy',
331333
SQUID_PROXY_PORT: SQUID_PORT.toString(),
332334
SQUID_INTERCEPT_PORT: SQUID_INTERCEPT_PORT.toString(),

0 commit comments

Comments
 (0)