Ga naar inhoud

egress (egress-control)

Purpose: default-deny egress for the namespace, with a squid forward-proxy enforcing an explicit FQDN allowlist. True hostname control on a CNI that can't do FQDN policy.

Deploys (manifests/components/egress/): NetworkPolicies + an egress-proxy (squid) Deployment/Service/ConfigMap.

The model: - default-deny-egress (all pods). CI pods (con-ci: "true") may reach only the proxy (allow-ci-to-proxy, :3128) + DNS. The proxy may reach the public internet (:80/:443, not private/cluster ranges). So a proxy misconfig can't open the network — the NetworkPolicy is the L3/L4 backstop. - squid allowlist (proxy-config.yaml, no wildcards): codeberg.org, apps.nextcloud.com, api.anthropic.com, ghcr.io + its blob host pkg-containers.githubusercontent.com + GitHub-releases hosts (Trivy DB), docker.io. semgrep.dev intentionally absent (rules vendored). The con-ci-oci overlay has its own, narrower list — since 2026-07-06 incl. pypi.org/files.pythonhosted.org (handbook docs pipeline), since 2026-07-07 also registry.npmjs.org (npm install inside kaniko image builds) and index.docker.io (kaniko/go-containerregistry normalizes docker.io to index.docker.io, not registry-1.docker.io like podman) + release-assets.githubusercontent.com (GitHub release downloads 302 there now, not to objects.githubusercontent.com — npm postinstall binaries like sharp/libvips), since 2026-07-13 also api.cloudflare.com (wrangler deploys of docs sites to Cloudflare Workers from container jobs; the telemetry host sparrow.cloudflare.com is deliberately absent — workflows set WRANGLER_SEND_METRICS=false).

Calico gotchas (hard-won — keep): - DNS is on port 8053, not 53: kube-dns Service maps 53→8053 and Calico evaluates egress post-DNAT, so allow-dns must permit 8053 to the kube-dns pods. A port-53 rule silently fails. - ipBlock does not match in-cluster destinations on Calico; an empty namespaceSelector {} matches nothing here. Use an explicit kubernetes.io/metadata.name: kube-system + k8s-app: kube-dns selector.

Operate / gotchas: - squid image docker.io/ubuntu/squid runs non-root (uid 13) + readonly rootfs; the ICMP pinger FATAL log line is benign (CAP_NET_RAW dropped) — it still listens on 3128. - Debug egress from the proxy pod: kubectl -n con-ci exec deploy/egress-proxy -- bash -c 'getent hosts codeberg.org; ...'. squid TCP_TUNNEL/200 = good; 503/HIER_NONE = upstream unreachable; TCP_DENIED = allowlist.

Future: Calico supports native domain-based egress (GlobalNetworkSet) — could replace squid.