-
Notifications
You must be signed in to change notification settings - Fork 18
[awf] agent-container: NODE_EXTRA_CA_CERTS invalid after chroot breaks ssl-bump TLS trust for Claude Code #1546
Description
Problem
When --ssl-bump is enabled and --chroot is active, Claude Code (and any Node.js process running inside the chroot) fails to make TLS connections through the Squid proxy because NODE_EXTRA_CA_CERTS points to a path that does not exist after chroot /host.
Symptom observed in the Squid audit log: repeated transaction-end-before-headers failures attributed to client: ::1, with NONE_NONE decisions and 0-byte status. Claude Code exhausts 10 API retries and exits with EHOSTUNREACH. MCP servers and other container-level processes work correctly because they run before the chroot activates and the container's /usr/local/share/ca-certificates/awf-ca.crt is still accessible.
Context
Upstream issue: github/gh-aw#23765 (follow-up from #23614).
Reported on:
- gh-aw CLI v0.65.1
- AWF container 0.25.5
- Claude Code CLI 2.1.87
Root Cause
Files involved
src/docker-manager.tslines 962–969 — mounts the per-session CA cert into the agent container at/usr/local/share/ca-certificates/awf-ca.crtand setsNODE_EXTRA_CA_CERTSto that pathcontainers/agent/entrypoint.shlines 106–119 — callsupdate-ca-certificatesand exportsNODE_EXTRA_CA_CERTS="/usr/local/share/ca-certificates/awf-ca.crt"containers/agent/entrypoint.shlines 724–729 — executeschroot /host /bin/bash -c "...", which changes the filesystem root to the host's/hostmount
Why it fails
The CA certificate is a Docker volume mount from the workdir into the container at /usr/local/share/ca-certificates/awf-ca.crt. This path exists on the container's overlay filesystem but is not bind-mounted under /host. After chroot /host, the new root is the host filesystem. Node.js (Claude Code) reads NODE_EXTRA_CA_CERTS and tries to open /usr/local/share/ca-certificates/awf-ca.crt — which is now resolved relative to the host's /, where the AWF CA does not exist.
Squid uses ssl-bump (TLS interception), so after the CONNECT tunnel is established, it presents a dynamically-generated certificate signed by the AWF CA. Because Claude Code cannot load the AWF CA, it rejects the certificate, closes the TLS connection before sending any HTTP headers, and Squid logs transaction-end-before-headers. The client: ::1 label is an artifact of how Squid's ssl-bump internals log the failed inner ssl-bump connection.
Proposed Solution
Apply the same pattern used for one-shot-token.so and get-claude-key.sh (lines 420–474 in entrypoint.sh): copy the CA cert to /host/tmp/awf-lib/ before the chroot activates, then update NODE_EXTRA_CA_CERTS to the chroot-relative path.
In containers/agent/entrypoint.sh, add a block after the get-claude-key.sh copy section (around line 474) and before the capsh check:
# Copy AWF CA certificate to chroot-accessible path for ssl-bump TLS trust
# NODE_EXTRA_CA_CERTS is set to a container path (/usr/local/share/ca-certificates/awf-ca.crt)
# which is NOT accessible after chroot /host. Copy it to /tmp/awf-lib/ (always writable)
# so that Node.js processes (Claude Code, MCP servers) inside the chroot trust the Squid CA.
if [ "\$\{AWF_SSL_BUMP_ENABLED}" = "true" ] && [ -f /usr/local/share/ca-certificates/awf-ca.crt ]; then
if mkdir -p /host/tmp/awf-lib 2>/dev/null; then
if cp /usr/local/share/ca-certificates/awf-ca.crt /host/tmp/awf-lib/awf-ca.crt 2>/dev/null; then
export NODE_EXTRA_CA_CERTS="/tmp/awf-lib/awf-ca.crt"
echo "[entrypoint] AWF CA certificate copied to chroot at /tmp/awf-lib/awf-ca.crt"
echo "[entrypoint] NODE_EXTRA_CA_CERTS updated to \$\{NODE_EXTRA_CA_CERTS}"
else
echo "[entrypoint][WARN] Could not copy AWF CA certificate to chroot — ssl-bump TLS may fail in chroot"
fi
fi
fiAdditionally, to cover non-Node.js tools inside the chroot that rely on the system CA bundle (curl, git, Python requests, etc.), also copy the cert to the host's ca-certificates directory and note that a full update-ca-certificates on the host side is not feasible. For those tools, consider setting SSL_CERT_FILE=/tmp/awf-lib/awf-ca.crt or appending it to the chroot CA bundle (e.g., /etc/ssl/certs/ca-certificates.crt) inside the chroot's /host/etc/ssl/certs/.
The existing CLEANUP_CMD in the chroot exit trap already removes /tmp/awf-lib (line 702), so no extra cleanup is needed.
Also consider adding an integration test that:
- Runs with
--ssl-bump+ chroot mode - Asserts
NODE_EXTRA_CA_CERTSresolves to an accessible path after chroot - Validates that
curl (alloweddomain/redacted)succeeds without certificate errors
Generated by Firewall Issue Dispatcher · ◷