feat(docker): add isolated Claude Code environment with proxy sidecar

Two-container setup: claude (UID 1000, internal-only network) and proxy
(Squid, UID 13). The internal Docker network uses internal: true so the
claude container has no direct internet route. All egress is tunnelled
through the Squid sidecar which enforces a domain allowlist. Both
containers drop all capabilities and set no-new-privileges. claude.sh
provides start/stop/run/update/logs/status/shell lifecycle management.
This commit is contained in:
docker-claude 2026-04-14 17:23:02 +02:00
commit e0e5e03e58
10 changed files with 554 additions and 0 deletions

44
proxy/squid.conf Normal file
View file

@ -0,0 +1,44 @@
# ─────────────────────────────────────────────────────────────────────────────
# Squid forward-proxy sidecar — allowlist-only egress for Claude Code
# ─────────────────────────────────────────────────────────────────────────────
http_port 3128
# PID must be writable by the non-root proxy user
pid_filename /tmp/squid.pid
# ─── Logging (container-friendly: stdout/stderr) ──────────────────────────────
access_log stdio:/dev/stdout combined
cache_log stdio:/dev/stderr
cache_store_log none
# ─── No disk cache ────────────────────────────────────────────────────────────
cache deny all
coredump_dir /var/spool/squid
# ─── ACL Definitions ──────────────────────────────────────────────────────────
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl CONNECT method CONNECT
# ─── Egress allowlist ─────────────────────────────────────────────────────────
# Add domains here as needed. Leading dot matches all subdomains.
acl allowed_sites dstdomain api.anthropic.com
acl allowed_sites dstdomain statsig.anthropic.com
# ─── Access rules ─────────────────────────────────────────────────────────────
# Block requests to non-standard ports
http_access deny !Safe_ports
# Block CONNECT to non-SSL ports
http_access deny CONNECT !SSL_ports
# Allow HTTPS tunnels only to allowlisted destinations
http_access allow CONNECT allowed_sites
# Allow plain HTTP only to allowlisted destinations
http_access allow allowed_sites
# Deny everything else — default deny
http_access deny all