Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions containers/agent/setup-iptables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ fi
echo "[iptables] Allow traffic to Squid proxy (${SQUID_IP}:${SQUID_PORT})..."
iptables -t nat -A OUTPUT -d "$SQUID_IP" -j RETURN

# Bypass Squid for host.docker.internal when host access is enabled.
# MCP gateway traffic to host.docker.internal gets DNAT'd to Squid,
# where Squid fails with "Invalid URL" because rmcp sends relative URLs.
if [ -n "$AWF_ENABLE_HOST_ACCESS" ]; then
HOST_GATEWAY_IP=$(getent hosts host.docker.internal | awk 'NR==1 { print $1 }')
if [ -n "$HOST_GATEWAY_IP" ]; then
echo "[iptables] Allow direct traffic to host gateway (${HOST_GATEWAY_IP}) - bypassing Squid..."
iptables -t nat -A OUTPUT -d "$HOST_GATEWAY_IP" -j RETURN
iptables -A OUTPUT -d "$HOST_GATEWAY_IP" -j ACCEPT
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OUTPUT filter chain rule (line 132) is placed in the middle of the NAT table configuration section, which makes the script structure harder to follow. According to the script's organization pattern (as documented by the "OUTPUT filter chain rules" comment at line 203), all filter chain rules should be grouped together after the NAT table rules are configured. While this works functionally (iptables evaluates NAT first, then filter), consider moving this ACCEPT rule to the OUTPUT filter chain section (after line 221) alongside the other filter rules for better code organization and maintainability.

Copilot uses AI. Check for mistakes.
else
echo "[iptables] WARNING: host.docker.internal could not be resolved, skipping host gateway bypass"
fi
fi

# Block dangerous ports at NAT level (defense-in-depth with Squid ACL filtering)
# These ports are explicitly blocked to prevent access to sensitive services
# even if Squid ACL filtering fails. The ports RETURN from NAT (not redirected)
Expand Down
23 changes: 23 additions & 0 deletions src/docker-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,29 @@ describe('docker-manager', () => {
expect(agent.extra_hosts).toBeUndefined();
expect(squid.extra_hosts).toBeUndefined();
});

it('should set AWF_ENABLE_HOST_ACCESS when enableHostAccess is true', () => {
const config = { ...mockConfig, enableHostAccess: true };
const result = generateDockerCompose(config, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;

expect(env.AWF_ENABLE_HOST_ACCESS).toBe('1');
});

it('should NOT set AWF_ENABLE_HOST_ACCESS when enableHostAccess is false', () => {
const config = { ...mockConfig, enableHostAccess: false };
const result = generateDockerCompose(config, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;

expect(env.AWF_ENABLE_HOST_ACCESS).toBeUndefined();
});

it('should NOT set AWF_ENABLE_HOST_ACCESS when enableHostAccess is undefined', () => {
const result = generateDockerCompose(mockConfig, mockNetworkConfig);
const env = result.services.agent.environment as Record<string, string>;

expect(env.AWF_ENABLE_HOST_ACCESS).toBeUndefined();
});
});

describe('allowHostPorts option', () => {
Expand Down
1 change: 1 addition & 0 deletions src/docker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ export function generateDockerCompose(
// Enable host.docker.internal for agent when --enable-host-access is set
if (config.enableHostAccess) {
agentService.extra_hosts = ['host.docker.internal:host-gateway'];
environment.AWF_ENABLE_HOST_ACCESS = '1';
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value '1' is inconsistent with other boolean AWF environment variables in this codebase. AWF_CHROOT_ENABLED and AWF_SSL_BUMP_ENABLED both use 'true' as their value (see lines 393 and 488). While the current implementation works because setup-iptables.sh checks with [ -n "$AWF_ENABLE_HOST_ACCESS" ] (which accepts any non-empty value), using 'true' would be more consistent with established patterns and would prevent potential confusion if the checking logic changes in the future.

Suggested change
environment.AWF_ENABLE_HOST_ACCESS = '1';
environment.AWF_ENABLE_HOST_ACCESS = 'true';

Copilot uses AI. Check for mistakes.
}

// Use GHCR image or build locally
Expand Down
Loading