# Restrict who may reach the echo pods. # # Traefik is configured to trust X-Forwarded-* from the whole pod CIDR, and the # app's Tomcat valve trusts every private range by default. Both are IP-range # decisions, so any pod in the cluster can forge those headers by talking to the # Service directly and bypassing Traefik entirely. Measured, not hypothetical: # # kubectl -n header-lab run t --rm -i --restart=Never --image=curlimages/curl -- \ # curl -s http://echo:8081/api/echo -H 'X-Forwarded-Host: evil.example.com' # → serverName evil.example.com, remoteAddr 1.2.3.4 # # A NetworkPolicy closes that path. It selects by label rather than IP, so it # survives pod restarts and rescheduling — unlike the trustedIPs list, which # could not name Traefik because its IP changes. # # "Trusting forwarded headers" and "guaranteeing a proxy sits in front" are a # pair. Doing only the first leaves this hole. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: echo-allow-traefik-only namespace: header-lab spec: podSelector: matchLabels: app: echo policyTypes: - Ingress ingress: # The proxy itself. namespaceSelector and podSelector in one list item are # ANDed, so this is "traefik pods in kube-system" and nothing else. - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: app.kubernetes.io/name: traefik ports: - protocol: TCP port: 8081 # kubelet readiness/liveness probes originate from the node, not from a pod, # so they need their own rule. Without it the probes fail and the pods are # restarted in a loop. # # The probe's source address is the node's flannel bridge (cni0), which # holds the first address of that node's /24: # kc-lab-1 10.42.0.1 kc-lab-2 10.42.1.1 # Listing them as /32 keeps this rule from re-admitting arbitrary pods, # which a broader 10.42.0.0/16 block would do and would undo the policy. # # Adding a node means adding its gateway here. Verify with: # kubectl get nodes -o jsonpath='{range .items[*]}{.spec.podCIDR}{"\n"}{end}' - from: - ipBlock: cidr: 10.42.0.1/32 - ipBlock: cidr: 10.42.1.1/32 ports: - protocol: TCP port: 8081