diff --git a/src/docker-manager.test.ts b/src/docker-manager.test.ts index e85eb492..7831fbf9 100644 --- a/src/docker-manager.test.ts +++ b/src/docker-manager.test.ts @@ -1906,12 +1906,13 @@ describe('docker-manager', () => { // May fail after writing configs } - // Verify squid.conf includes api-proxy in allowed domains + // Verify squid.conf includes api-proxy hostname and IP in allowed domains const squidConfPath = path.join(testDir, 'squid.conf'); if (fs.existsSync(squidConfPath)) { const content = fs.readFileSync(squidConfPath, 'utf-8'); expect(content).toContain('github.com'); expect(content).toContain('api-proxy'); + expect(content).toContain('172.30.0.30'); // api-proxy IP address } }); diff --git a/src/docker-manager.ts b/src/docker-manager.ts index 989a2642..cdc5d851 100644 --- a/src/docker-manager.ts +++ b/src/docker-manager.ts @@ -1147,9 +1147,10 @@ export async function writeConfigs(config: WrapperConfig): Promise { // Write Squid config // Note: Use container path for SSL database since it's mounted at /var/spool/squid_ssl_db - // When API proxy is enabled and has API keys, add api-proxy to allowed domains so agent can communicate with it + // When API proxy is enabled and has API keys, add api-proxy hostname and IP to allowed domains so agent can communicate with it + // The IP address is necessary because some tools may bypass NO_PROXY settings or use the IP directly const domainsForSquid = config.enableApiProxy && networkConfig.proxyIp && (config.openaiApiKey || config.anthropicApiKey) - ? [...config.allowedDomains, 'api-proxy'] + ? [...config.allowedDomains, 'api-proxy', networkConfig.proxyIp] : config.allowedDomains; const squidConfig = generateSquidConfig({ diff --git a/src/host-iptables.test.ts b/src/host-iptables.test.ts index dfea517e..3985423a 100644 --- a/src/host-iptables.test.ts +++ b/src/host-iptables.test.ts @@ -226,34 +226,6 @@ describe('host-iptables', () => { ]); }); - it('should add api-proxy ACCEPT rule when apiProxyIp is provided', async () => { - mockedExeca.mockResolvedValue({ - stdout: '', - stderr: '', - exitCode: 0, - } as any); - - // Mock chain existence check to return "not exists" (exitCode: 1) - mockedExeca - // Mock getNetworkBridgeName - .mockResolvedValueOnce({ stdout: 'fw-bridge', stderr: '', exitCode: 0 } as any) - // Mock iptables -L DOCKER-USER (permission check) - .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 } as any) - // Mock chain existence check (does not exist) - .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 1 } as any) - // All subsequent calls succeed with default mock - .mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 } as any); - - await setupHostIptables('172.30.0.10', 3128, ['8.8.8.8', '8.8.4.4'], '172.30.0.30'); - - // Verify api-proxy ACCEPT rule was created - expect(mockedExeca).toHaveBeenCalledWith('iptables', [ - '-t', 'filter', '-A', 'FW_WRAPPER', - '-s', '172.30.0.30', - '-j', 'ACCEPT', - ]); - }); - it('should cleanup existing chain before creating new one', async () => { mockedExeca // Mock getNetworkBridgeName