Files
57_Wolve e7ba68790b Done — the Squid deployment is fully built, wired in, and statically verified on the feat/squid-proxy branch. ## What landed deployments/squid/ (13 files) plus wiring into [automations.sh](automations.sh:51), [README.md](README.md), and [.gitignore](.gitignore). All six approved design decisions are implemented: - **Self-built minimal Alpine image** — apk add squid (ssl-bump compiled in), openssl/tini. [entrypoint.sh](deployments/squid/entrypoint.sh) renders squid.conf and generates the cache policy from the lists at start. - **SSL-bump** peek→splice→bump with [splice-domains.txt](deployments/squid/splice-domains.txt) passthrough. - **Wildcard hostname caching** — leading-dot [cache-domains.txt](deployments/squid/cache-domains.txt) + optional regex; CACHE_ONLY_LISTED boost/allowlist toggle. - **HTML/dynamic storage gate**, with query strings exempt on boosted domains. - **CA lifecycle** — generated on first deploy via the built image, key 0600 on the host, staged to tmpfs for the container, never embedded, git-ignored. - **Deny-by-default http_access + BIND_ADDR pinning** as the real access gate (Docker bypasses INPUT). ## One bug caught & fixed The test of the entrypoint's policy generation showed it emitting ubuntu.com with an **unescaped dot** — the s/\./\\./g double-backslash is sed-implementation-dependent and silently failed. Switched to a [.] character class (ubuntu[.]com), portable across busybox/git-bash, re-embedded, re-audited. ## Verified vs. pending **Verified locally:** bash -n on all scripts, LF endings, launcher parses, embedded archive byte-matches the loose files, and the cache-policy generation produces correct Squid directives in both modes. **Pending a Docker host** (this Windows box has none, as the plan anticipated): the container functional smoke test — build, CA mint, a bumped HTTPS fetch, a TCP_HIT, and a splice check. A few version-sensitive specifics get confirmed there: tls-cert=/tls-key= option names, the security_file_certgen path, busybox install -o/-g, ssl::server_name subdomain matching, and the squid -z flag. (All isolated and easy to adjust if any differ.) ## Commit (for you to GPG-sign) Staged and ready. Per your convention I haven't committed — here's the message: `` feat(squid): add SSL-bump caching forward-proxy deployment New deployments/squid/: an explicit forward proxy with SSL-bump TLS interception (local CA, generated on first deploy) and hostname-targeted static-content caching. Unlike the other stacks it is a forward proxy, not a Caddy/Let's-Encrypt inbound site. - Self-built minimal Alpine image (apk squid ships ssl-bump); entrypoint renders squid.conf and generates the cache policy from the domain lists. - Wildcard hostname caching (cache-domains.txt leading-dot + optional cache-domains.regex); boost vs strict-allowlist toggle (CACHE_ONLY_LISTED). - Storage gate never caches HTML or dynamic content; query strings exempt on boosted domains so versioned static assets still cache. - splice-domains.txt passthrough for pinned/banking domains. - Deny-by-default http_access (TRUSTED_CIDR) + BIND_ADDR pinning; CA key 0600 on host, never embedded, git-ignored. - Wired into automations.sh, README, .gitignore; cloud-init for fresh VMs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> ` `bash git commit -S -F- <<'EOF' <paste message above> EOF ` Want me to **push feat/squid-proxy** once you've committed (you'd open the PR in Gitea), or hold? And if you can point me at a Docker host (or run docker compose build in /srv/squid` after a test deploy), I'll drive the functional smoke test and fix anything the live Squid version flags.
New deployments/squid/: an explicit forward proxy with SSL-bump TLS
interception (local CA, generated on first deploy) and hostname-targeted
static-content caching. Unlike the other stacks it is a forward proxy, not
a Caddy/Let's-Encrypt inbound site.
- Self-built minimal Alpine image (apk squid ships ssl-bump); entrypoint
  renders squid.conf and generates the cache policy from the domain lists.
- Wildcard hostname caching (cache-domains.txt leading-dot + optional
  cache-domains.regex); boost vs strict-allowlist toggle (CACHE_ONLY_LISTED).
- Storage gate never caches HTML or dynamic content; query strings exempt on
  boosted domains so versioned static assets still cache.
- splice-domains.txt passthrough for pinned/banking domains.
- Deny-by-default http_access (TRUSTED_CIDR) + BIND_ADDR pinning; CA key 0600
  on host, never embedded, git-ignored.
- Wired into automations.sh, README, .gitignore; cloud-init for fresh VMs.
2026-06-22 16:32:25 -05:00

77 lines
3.4 KiB
Cheetah

# squid.conf.tmpl
#
# Rendered to /etc/squid/squid.conf by entrypoint.sh at container start:
# - @VAR@ placeholders are substituted from the environment (.env);
# - the cache policy (boost ACLs, storage gate, per-domain refresh_patterns)
# is generated from cache-domains.txt / .regex into the include below.
#
# Role: EXPLICIT forward proxy with SSL-bump. Clients set HTTP(S)_PROXY to this
# host:3128. (Transparent/intercepting mode is future work -- see README.)
visible_hostname @VISIBLE_HOSTNAME@
# ── Listener: explicit proxy, SSL-bump enabled ──────────────────────────────
# tls-cert/tls-key are the local CA used to mint per-host leaf certs on the fly.
# The key is staged into /run by the entrypoint so the squid user can read it
# while the on-host key file stays 0600 root.
http_port 3128 ssl-bump \
tls-cert=/run/squid/ca-cert.pem \
tls-key=/run/squid/ca-key.pem \
generate-host-certificates=on \
dynamic_cert_mem_cache_size=@DYNAMIC_CERT_MEM_MB@MB
sslcrtd_program /usr/lib/squid/security_file_certgen -s /var/lib/squid/ssl_db -M @DYNAMIC_CERT_MEM_MB@MB
sslcrtd_children 8 startup=1 idle=1
# Validate UPSTREAM certificates -- never silently MITM a broken origin cert.
sslproxy_cert_error deny all
# ── SSL-bump policy: peek at SNI → splice allowlist → bump everything else ──
acl step1 at_step SslBump1
acl splice_dom ssl::server_name "/etc/squid/splice-domains.txt"
ssl_bump peek step1
ssl_bump splice splice_dom
ssl_bump bump all
# ── Access control: deny-by-default, trusted clients only ───────────────────
acl SSL_ports port 443
acl Safe_ports port 80 443 21 70 210 1025-65535 280 488 591 777
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# Cache manager: localhost only (used by the container healthcheck).
http_access allow localhost manager
http_access deny manager
acl trusted_clients src @TRUSTED_CIDR@
http_access allow localhost
http_access allow trusted_clients
http_access deny all
# ── Cache sizing ────────────────────────────────────────────────────────────
cache_mem @CACHE_MEM_MB@ MB
maximum_object_size_in_memory 1 MB
maximum_object_size @MAX_OBJECT_SIZE_MB@ MB
cache_dir ufs /var/cache/squid @CACHE_SIZE_MB@ 16 256
coredump_dir /var/cache/squid
# ── Cache policy (generated: boost ACLs, storage gate, per-domain TTLs) ─────
include /etc/squid/conf.d/cache-policy.conf
# Base refresh patterns (fallbacks; per-domain boosts live in the include and
# are matched first). Packages get long, confident TTLs; everything else is
# conservative and revalidates.
refresh_pattern -i \.(deb|rpm|apk|pkg|tar\.(gz|xz|zst|bz2)|whl|jar)$ 10080 100% 43200
refresh_pattern . 0 20% 4320
# ── Logging ─────────────────────────────────────────────────────────────────
access_log stdio:/var/log/squid/access.log
cache_log /var/log/squid/cache.log
logfile_rotate 7
# ── Privilege drop / lifecycle ──────────────────────────────────────────────
cache_effective_user squid
pid_filename /run/squid.pid
shutdown_lifetime 5 seconds