diff --git a/src/services/agent-environment/proxy-environment.test.ts b/src/services/agent-environment/proxy-environment.test.ts index f2caa443b..ec91027ea 100644 --- a/src/services/agent-environment/proxy-environment.test.ts +++ b/src/services/agent-environment/proxy-environment.test.ts @@ -57,6 +57,34 @@ describe('buildProxyEnvironment', () => { expect(env.NO_PROXY.split(',')).toContain('awmg-cli-proxy'); }); + it('strips port suffix from difcProxyHost', () => { + const env = run({ + ...baseConfig, + networkIsolation: true, + difcProxyHost: 'awmg-cli-proxy:8443', + }); + expect(env.NO_PROXY.split(',')).toContain('awmg-cli-proxy'); + expect(env.NO_PROXY.split(',')).not.toContain('awmg-cli-proxy:8443'); + }); + + it('strips scheme and port from a scheme-prefixed difcProxyHost', () => { + const env = run({ + ...baseConfig, + networkIsolation: true, + difcProxyHost: 'https://proxy.internal:443', + }); + expect(env.NO_PROXY.split(',')).toContain('proxy.internal'); + }); + + it('strips brackets and port from a bracketed IPv6 difcProxyHost', () => { + const env = run({ + ...baseConfig, + networkIsolation: true, + difcProxyHost: '[::1]:18443', + }); + expect(env.NO_PROXY.split(',')).toContain('::1'); + }); + it('does NOT exempt topology peers outside network-isolation mode', () => { const env = run({ ...baseConfig, diff --git a/src/services/agent-environment/proxy-environment.ts b/src/services/agent-environment/proxy-environment.ts index 885153dfa..bfca76859 100644 --- a/src/services/agent-environment/proxy-environment.ts +++ b/src/services/agent-environment/proxy-environment.ts @@ -2,6 +2,7 @@ import { WrapperConfig } from '../../types'; import { NetworkConfig } from '../squid-service'; import { buildNoProxyValue } from '../no-proxy-utils'; import { runtimeUsesIptables, runtimeUsesComposeAgent } from '../../container-runtime'; +import { parseDifcProxyHost } from '../../host-env'; interface ProxyEnvironmentParams { config: WrapperConfig; @@ -35,6 +36,14 @@ export function buildProxyEnvironment(params: ProxyEnvironmentParams): void { if (config.topologyAttach) { noProxyHosts.push(...config.topologyAttach); } + // The DIFC/cli-proxy host is addressed by proxy-aware clients directly and + // must bypass Squid even when it isn't listed in topologyAttach. + // Use parseDifcProxyHost to correctly strip scheme prefixes and handle + // bracketed IPv6 (e.g. https://proxy.internal:443, [::1]:18443), since + // undici matches NO_PROXY against the hostname only. + if (config.difcProxyHost) { + noProxyHosts.push(parseDifcProxyHost(config.difcProxyHost).host); + } } // The MCP gateway is served on the network gateway (e.g. 172.30.0.1). In