TL;DR
A straightforward pattern uses a Squid HTTP/HTTPS proxy inside Kubernetes and a NetworkPolicy to force outbound traffic through it. The approach provides centralized logging and enforcement without adding service meshes, CNI plugins, or CRDs.
What happened
The author tested a minimal egress-control setup on k3s (and kind for development) by deploying Squid in an isolated egress-proxy namespace and restricting workloads so they can only send outbound traffic to that proxy. Workloads set HTTP_PROXY and HTTPS_PROXY to point at squid.egress-proxy.svc.cluster.local:3128 and use NO_PROXY to keep internal calls local. A NetworkPolicy in the workload namespace blocks direct egress except for DNS (TCP/UDP port 53 to kube-system) and TCP port 3128 to namespaces labeled purpose=egress-control, making the proxy mandatory. The Squid deployment uses a ConfigMap for squid.conf (no caching, access_log and cache_log paths set, RFC1918 localnet ACLs), an init container to chown the log directory, and a log-streamer sidecar that tails /var/log/squid/access.log. Logs are written to a hostPath (/var/log/squid-egress) for persistence and offline analysis. The author validated the pattern with a small Common Lisp app, Horizons, which makes real HTTPS calls to NASA’s JPL Horizons API.
Why it matters
- Visibility: Squid records each outbound connection (timestamps, destinations, bytes) for auditing and analysis.
- Enforcement: NetworkPolicy prevents direct egress, ensuring workloads must use the proxy.
- Simplicity: The pattern avoids additional cloud-native layers like service meshes, extra CNI features, or CRDs.
- Compliance-friendly: Centralized proxying aligns with common requirements in regulated environments that mandate proxied outbound traffic.
Key facts
- Squid listens on HTTP port 3128 according to the provided configuration.
- The squid.conf in the example disables caching (cache deny all) and logs to /var/log/squid/access.log and /var/log/squid/cache.log.
- ACLs in the example allow RFC1918 private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16); the author notes tightening to a specific pod CIDR is recommended for production.
- The Squid deployment includes an initContainer that chowns /var/log/squid to UID:GID 13:13 and a log-streamer sidecar that tails the access log to stdout.
- Logs are persisted on the node using a hostPath volume at /var/log/squid-egress for offline analysis or aggregation.
- A NetworkPolicy named enforce-egress-proxy blocks egress from the workloads namespace except for DNS (TCP/UDP port 53 to the kube-system namespace) and TCP port 3128 to namespaces labeled purpose=egress-control.
- Workloads set HTTP_PROXY and HTTPS_PROXY environment variables to http://squid.egress-proxy.svc.cluster.local:3128 and include a NO_PROXY value to exclude local addresses and cluster service domains.
- Not all HTTP clients automatically honor HTTP_PROXY/HTTPS_PROXY environment variables; the author encountered a client (Drakma) that required explicit configuration.
What to watch next
- Whether application HTTP clients respect HTTP_PROXY/HTTPS_PROXY—some libraries may need explicit proxy configuration rather than relying on environment variables.
- Log retention and aggregation: hostPath-based logs require node-level management or external collection to avoid loss and to enable analysis at scale.
- ACL scope and least privilege: tighten the allowed localnet/pod CIDR ranges in squid.conf in production to reduce exposure.
Quick glossary
- Squid: A long-standing caching and forwarding HTTP proxy that can log, filter, and control outbound HTTP/HTTPS traffic.
- NetworkPolicy: A Kubernetes resource that controls network traffic to and from pods, allowing operators to restrict egress and ingress flows.
- HTTP_PROXY / HTTPS_PROXY: Environment variables commonly used to direct HTTP/HTTPS client libraries to route requests through a proxy server.
- hostPath volume: A Kubernetes volume type that mounts a file or directory from the node’s filesystem into a pod; useful for node-local persistence but operationally sensitive.
Reader FAQ
Does this approach require a service mesh or special CNI plugin?
No. The example intentionally avoids service meshes, additional CNI plugins, and CRDs; it uses a proxy plus NetworkPolicy for enforcement.
How are outbound requests logged and persisted?
Squid writes access and cache logs to /var/log/squid inside the pod, which in the example is backed by a hostPath at /var/log/squid-egress on the node for persistence.
Will all applications automatically use the proxy when HTTP_PROXY is set?
Not always. Many common clients honor these variables, but some libraries or language clients require explicit proxy configuration; the author noted Drakma needed manual setup.
Can this setup intercept or decrypt HTTPS traffic for inspection?
not confirmed in the source
Next: Datastar and Common Lisp for web development, Up: Posts [Contents][Index][Top] Kubernetes Egress Control with Squid proxy 2025-12-28 This Way to the Egress! — Sign at P.T. Barnum’s Americam…
Sources
- Kubernetes egress control with squid proxy
- Kubernetes Native FQDN Based Egress Network Policies
- Simulating a corporate proxy environment using Kubernetes …
- Network Policies
Related posts
- How Tor adapted anti-censorship tools in 2025 against Iran and Russia
- Tor’s 2025 anti-censorship push: lessons from Iran and Russia
- NextDNS: My new favourite DNS service for privacy, blocking and speed