Skip to content

HTTP traffic NAT'd to Squid fails with 'Invalid URL - Missing hostname' #519

@Mossaka

Description

@Mossaka

Problem

When HTTP traffic is NAT'd (DNAT) to Squid proxy, it fails with "Invalid URL - Missing hostname" because Squid is configured in normal proxy mode, not intercept mode.

This causes Codex smoke tests to fail - the rmcp (Rust MCP) client doesn't use HTTP_PROXY environment variables, so its OAuth discovery requests get NAT'd to Squid but fail.

Root Cause

Squid configuration (src/squid-config.ts:411-414):

// Port configuration: Use normal proxy mode (not intercept mode)
let portConfig = `http_port ${port}`;  // port = 3128

iptables NAT rules (containers/agent/setup-iptables.sh:160-161):

iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination "${SQUID_IP}:${SQUID_PORT}"
iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination "${SQUID_IP}:${SQUID_PORT}"

The mismatch:

  • Normal proxy mode expects requests with absolute URLs: GET http://example.com/path
  • NAT'd traffic sends relative URLs: GET /path with Host: example.com

Squid sees GET /path without knowing the target host (it can only use Host header in intercept mode).

Reproduction

  1. Start AWF with --enable-host-access --allow-host-ports 8080
  2. Try to curl without explicit proxy:
    curl http://host.docker.internal:8080/.well-known/oauth-authorization-server
  3. Observe Squid returns "Invalid URL - Missing hostname"

When using explicit proxy, it works:

curl -x $HTTP_PROXY http://host.docker.internal:8080/.well-known/oauth-authorization-server
# Returns 404 page not found (correct!)

Proposed Fix

AWF already has SQUID_INTERCEPT_PORT = 3129 defined but unused. The fix:

  1. squid-config.ts: Add intercept port configuration:

    let portConfig = `http_port ${port}\nhttp_port ${interceptPort} intercept`;
  2. setup-iptables.sh: Change NAT rules to use intercept port:

    iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination "${SQUID_IP}:3129"
    iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination "${SQUID_IP}:3129"

This keeps port 3128 for explicit proxy usage (HTTP_PROXY) and port 3129 for transparent/intercepted traffic.

Impact

This bug causes:

  • Codex smoke tests to fail (OAuth discovery times out)
  • Any HTTP client that doesn't honor HTTP_PROXY env vars to fail
  • AWS SDKs, Go http clients, Rust reqwest (without proxy config) may be affected

Related

  • gh-aw PR #13792 (IP fix for Codex)
  • gh-aw-mcpg issue #672 (OAuth path mismatch - fixed in v0.0.99)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions