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

Related posts

By

Leave a Reply

Your email address will not be published. Required fields are marked *