Skip to content

host.docker.internal unreachable from sandbox on Linux — proxy can't route to Docker bridge #778

@onsails

Description

@onsails

Problem

On Linux, sandbox pods cannot reach services running on the host via host.docker.internal, even with a correctly configured network policy including allowed_ips.

The proxy passes the policy check (no 403 when allowed_ips covers 172.16.0.0/12), but the actual TCP connection times out — the proxy has no route to the Docker bridge gateway (172.17.0.1).

Reproduction

Environment: Linux (NixOS), OpenShell v0.0.24, Docker 28.5.2, fresh gateway (gateway destroy + gateway start)

  1. Start an HTTP server on the host:
python3 -c "
import http.server, threading, time
class H(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200); self.end_headers(); self.wfile.write(b'ok')
    def log_message(self, *a): pass
http.server.HTTPServer(('0.0.0.0', 8100), H).serve_forever()
" &
  1. Verify the host can reach 172.17.0.1:8100:
curl http://172.17.0.1:8100/   # → "ok"
  1. Create a sandbox with this policy:
network_policies:
  myservice:
    endpoints:
      - host: "host.docker.internal"
        port: 8100
        allowed_ips:
          - "172.16.0.0/12"
        protocol: rest
        access: full
    binaries:
      - path: "**"
  1. From inside the sandbox:
# Without allowed_ips → 403 (SSRF blocks private IP)
# With allowed_ips → timeout (proxy can't connect to 172.17.0.1)
curl -v --max-time 8 http://host.docker.internal:8100/
curl -v --max-time 8 https://host.docker.internal:8100/

Analysis

  • host.docker.internal resolves correctly inside the sandbox (/etc/hosts172.17.0.1)
  • Without allowed_ips: proxy returns 403 (SSRF rejects private IP) — expected
  • With allowed_ips: ["172.16.0.0/12"]: proxy accepts the request but TCP connection hangs → timeout
  • The proxy runs inside k3s, which uses flannel networking (10.42.0.0/16). There is no route from the flannel network to the Docker bridge (172.17.0.0/16)
  • From the host network namespace, 172.17.0.1:8100 is reachable. From a k3s pod, it is not.

What works

  • Internet-facing endpoints (e.g., *.anthropic.com:443 with tls: terminate) work fine through the proxy
  • host.docker.internal resolution works (/etc/hosts is correct)
  • allowed_ips correctly bypasses SSRF for private IPs

Expected behavior

host.docker.internal should be reachable from sandboxes on Linux when the policy allows it. This likely requires a routing rule from the k3s pod network to the Docker bridge, or the proxy should connect from the host network namespace rather than the pod namespace.

Related

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