Identity-aware egress relay for multi-tenant Kubernetes clusters behind a corporate proxy
66
An identity-aware egress relay for multi-tenant Kubernetes clusters that reach the internet through a corporate forward proxy.
On-prem clusters usually have exactly one way out: a corporate proxy that authenticates its clients. That leaves two unappealing options.
Host-level allowlists do not rescue the first option either. Once
raw.githubusercontent.com or a shared artifact host is allowed, it is
effectively the whole internet.
Tenants point http_proxy at the relay. For each connection the relay:
EgressPolicy — host, port, and
optionally URL path and HTTP method,The corporate proxy keeps its existing authentication model. It sees one client presenting a different account per tenant, so its logs and quotas stay attributable, and no tenant ever holds a proxy credential.
tenant pod ──http_proxy──▶ relay ──CONNECT + Proxy-Authorization──▶ corporate proxy ──▶ internet
│
├─ identity: pod IP → namespace, pod, service account
├─ policy: EgressPolicy (host, port, path, method)
└─ credential: UpstreamProxy → Secret, per tenant
A CONNECT tunnel shows the relay a host and a port and nothing else, so path
rules require terminating TLS. That is opt-in per destination:
tlsMode: tunnel (default) — bytes are spliced opaquely. Authorization is
host and port only. Cert-pinned clients and client-certificate workloads keep
working.tlsMode: inspect — TLS is terminated at the relay so path and method rules
apply. Workloads must trust the relay CA, which the relay publishes as a
ConfigMap into every namespace an inspect-mode policy selects.The origin leg of an inspected connection is always verified normally, against system roots with hostname checking. Interception never becomes a downgrade.
Plain http:// requests carry their path in the clear, so path rules apply
there with no interception at all.
# 1. CRDs and the relay
helm install relay deploy/helm -n relay-system --create-namespace \
--set denyCIDRs='{10.244.0.0/16,10.96.0.0/12}' # your pod and service CIDRs
# 2. The corporate proxy account for one tenant
kubectl -n relay-system create secret generic corp-team-a \
--from-literal=username=svc-team-a --from-literal=password='...'
# 3. The profile and the grant
kubectl apply -f deploy/examples/
Then, in a tenant pod:
export http_proxy=http://relay.relay-system:3128
export https_proxy=$http_proxy
curl https://api.github.com/zen
Identity rests on the relay seeing the client's real pod IP. Check it:
kubectl run preflight --rm -it --image=cropalato/proxy-relay-control:0.1.0 \
--env POD_IP=... -- preflight --url http://relay.relay-system:9090
A mismatch means something is rewriting the source address — kube-proxy --masquerade-all, a CNI masquerade rule, or a hostNetwork client. See
docs/operations.md.
EgressPolicy and UpstreamProxyv0.1.0. Identity is pod-IP based; ServiceAccount-token and mTLS/SPIFFE providers fit the same interface and are the intended hardening path.
Images are published to Docker Hub
as cropalato/proxy-relay-control.
MIT.
Content type
Image
Digest
sha256:b80e8cb35…
Size
15.3 MB
Last updated
about 1 month ago
docker pull cropalato/proxy-relay-control