Veröffentlicht am

Egress Filtering: Ausgehenden Traffic in Kubernetes kontrollieren

Teilen:
Authors

Egress Filtering in Kubernetes: Ausgehenden Traffic gezielt kontrollieren

TL;DR

  • Default-Deny fuer Egress ist der wichtigste erste Schritt -- ohne ihn kann jeder Pod beliebige externe Ziele erreichen
  • Native NetworkPolicies arbeiten auf Layer 3/4 (IP + Port), Cilium erweitert das um Layer 7 (DNS, HTTP Host)
  • Ein Egress Gateway zentralisiert ausgehenden Traffic und ermoeglicht TLS-Inspektion sowie Logging an einer Stelle
  • Der Rollout sollte schrittweise erfolgen: erst Audit-Modus, dann Deny-All mit expliziten Allow-Regeln
  • Fuer die meisten Cluster reicht Cilium mit DNS-basiertem Egress aus -- ein Service Mesh ist selten noetig

Warum Egress Filtering oft vernachlaessigt wird

Die meisten Kubernetes-Setups konzentrieren sich auf Ingress: Wer darf von aussen auf welchen Service zugreifen? Die Gegenrichtung -- welche externen Ziele ein Pod erreichen darf -- wird erstaunlich oft ignoriert. Das ist ein Problem.

Wenn ein Container kompromittiert wird, ist ausgehender Netzwerkzugriff der primaere Angriffsvektor. Malware kontaktiert Command-and-Control-Server. Daten werden exfiltriert. Cryptominer laden Payloads nach. Ohne Egress-Kontrolle steht dem nichts im Weg.

Dazu kommt die DSGVO: Artikel 32 verlangt technische Massnahmen zur Sicherheit der Verarbeitung. Egress Filtering ist eine der wirksamsten, weil sie verhindert, dass personenbezogene Daten ueberhaupt den Cluster verlassen koennen.

Die drei Ebenen von Egress-Kontrolle

Es gibt nicht die eine Loesung. Je nach Anforderung kommen unterschiedliche Mechanismen zum Einsatz, die sich auch kombinieren lassen.

AnsatzLayerDNS-FilteringTLS-InspektionKomplexitaetTypischer Einsatz
Native NetworkPoliciesL3/L4NeinNeinNiedrigBasis-Absicherung
Cilium NetworkPoliciesL3/L4 + L7JaNeinMittelStandard-Setup
Egress Gateway (Envoy/Squid)L7JaMoeglichHochRegulierte Umgebungen
Service Mesh (Istio)L7JaJa (mTLS)Sehr hochNur wenn bereits vorhanden

Fuer die meisten Produktions-Cluster ist Cilium der beste Kompromiss. Es bietet DNS-basiertes Egress-Filtering ohne den Overhead eines Service Mesh.

Schritt 1: Default-Deny fuer Egress

Der wichtigste Schritt ist eine Default-Deny-Policy fuer den Namespace. Ohne sie erlaubt Kubernetes standardmaessig allen ausgehenden Traffic.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress

Diese Policy blockiert saemtlichen ausgehenden Traffic fuer alle Pods im Namespace production. Das bricht natuerlich erstmal alles -- DNS-Aufloesung, Zugriff auf andere Services, externe APIs. Deshalb ist der naechste Schritt entscheidend.

Schritt 2: DNS und interne Kommunikation erlauben

Pods brauchen DNS-Zugriff und muessen mit Services im gleichen Cluster kommunizieren koennen. Diese Policy erlaubt beides:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-and-internal
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    # DNS (CoreDNS im kube-system Namespace)
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
    # Kommunikation innerhalb des Clusters (Pod CIDR)
    - to:
        - ipBlock:
            cidr: 10.0.0.0/8

Wichtig: Der Pod-CIDR muss an euer Cluster angepasst werden. Bei den meisten Installationen liegt er im 10.0.0.0/8-Bereich, aber prueft das mit kubectl cluster-info dump | grep -i cidr.

Schritt 3: Externe Ziele gezielt freigeben

Jetzt koennt ihr fuer einzelne Workloads spezifische externe Ziele erlauben. Hier ein Beispiel fuer einen Pod, der nur eine externe API auf Port 443 erreichen darf:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-payment-api-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 203.0.113.0/24
      ports:
        - protocol: TCP
          port: 443

Das Problem: Externe APIs aendern ihre IP-Adressen. Wenn der Payment-Provider seine Infrastruktur umzieht, bricht die Verbindung. Hier helfen DNS-basierte Policies.

Cilium: DNS-basiertes Egress Filtering

Cilium erweitert NetworkPolicies um FQDN-basierte Regeln. Statt IP-Adressen koennt ihr Hostnamen verwenden:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-payment-api-fqdn
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: payment-service
  egress:
    - toFQDNs:
        - matchName: "api.stripe.com"
        - matchName: "api.paypal.com"
      toPorts:
        - ports:
            - port: "443"
              protocol: TCP
    - toEndpoints:
        - matchLabels:
            io.kubernetes.pod.namespace: kube-system
            k8s-app: kube-dns
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP

Cilium faengt DNS-Antworten ab und erstellt daraus dynamisch IP-basierte Regeln. Wenn api.stripe.com seine IP aendert, passt sich die Policy automatisch an. Wichtig dabei: DNS-Zugriff muss explizit erlaubt sein, sonst kann Cilium die Hostnamen nicht aufloesen.

Egress Gateway fuer zentrales Logging

Wenn ihr nicht nur kontrollieren, sondern auch auditieren wollt, welche externen Verbindungen aufgebaut werden, bietet sich ein Egress Gateway an. Der gesamte ausgehende Traffic wird durch einen zentralen Proxy geleitet.

Ein einfaches Setup mit Envoy als Egress Proxy:

# Envoy als Egress Gateway deployen
kubectl create namespace egress-gateway

# Envoy Konfiguration als ConfigMap
kubectl create configmap envoy-config \
  --from-file=envoy.yaml=envoy-egress.yaml \
  -n egress-gateway

# NetworkPolicy: Pods duerfen nur zum Egress Gateway
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: force-egress-through-gateway
  namespace: production
spec:
  podSelector:
    matchLabels:
      egress-policy: gateway-required
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: egress-gateway
          podSelector:
            matchLabels:
              app: envoy-egress
      ports:
        - protocol: TCP
          port: 8443
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
EOF

Der Vorteil: Am Gateway habt ihr einen einzelnen Punkt, an dem ihr TLS-Inspektion, Rate Limiting, detailliertes Logging und Content Filtering implementieren koennt. Der Nachteil: Es ist ein Single Point of Failure, den ihr redundant auslegen muesst.

Monitoring: Blockierte Verbindungen erkennen

Egress-Regeln ohne Monitoring sind nutzlos. Ihr muesst wissen, wenn Pods versuchen, unerlaubte Ziele zu erreichen. Cilium liefert dafuer Hubble:

# Hubble CLI installieren und blockierte Flows anzeigen
hubble observe --verdict DROPPED --type l3/l4 \
  --namespace production \
  --since 1h \
  -o json | jq '.flow | {src: .source.labels, dst: .IP.destination, port: .l4.TCP.destination_port}'

Fuer Prometheus-basiertes Alerting definiert ihr eine Rule wie diese:

groups:
  - name: egress-filtering
    rules:
      - alert: EgressPolicyViolation
        expr: sum(rate(hubble_drop_total{reason="POLICY_DENIED", direction="EGRESS"}[5m])) by (namespace) > 0
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Egress Policy Violation in {{ $labels.namespace }}"
          description: "Pods in Namespace {{ $labels.namespace }} versuchen, blockierte externe Ziele zu erreichen."

Haeufige Fehler beim Rollout

DNS vergessen. Die haeufigste Ursache fuer Probleme nach dem Aktivieren von Egress-Policies ist fehlender DNS-Zugriff. Ohne DNS koennen Pods keine Hostnamen aufloesen, und fast alles bricht.

Zu restriktiv starten. Schaltet nicht sofort Default-Deny in Produktion ein. Beginnt in einer Staging-Umgebung oder nutzt Ciliums Policy-Audit-Modus, um zu sehen, welche Verbindungen blockiert wuerden.

Cluster-interne Kommunikation blockieren. Pods muessen mit dem Kubernetes API Server, mit CoreDNS und mit Services in anderen Namespaces kommunizieren koennen. Vergesst nicht, diese Pfade freizugeben.

Keine Automation. Egress-Regeln gehoeren in die CI/CD-Pipeline. Wenn Entwickler neue externe Abhaengigkeiten einfuehren, muss die zugehoerige NetworkPolicy als Code mitgeliefert werden.

Vorgehensweise fuer den Rollout

Ein pragmatischer Plan fuer bestehende Cluster:

Woche 1-2: Bestandsaufnahme. Nutzt Hubble oder tcpdump, um zu erfassen, welche externen Ziele eure Pods aktuell erreichen. Erstellt eine Liste pro Namespace.

Woche 3-4: Policies schreiben. Formuliert Default-Deny und Allow-Regeln basierend auf der Bestandsaufnahme. Testet sie in Staging.

Woche 5-6: Audit-Modus. Aktiviert die Policies im Audit-Modus (Cilium: policyAuditMode=true). Ueberwacht die Logs auf unerwartete Drops.

Woche 7-8: Enforcement. Schaltet auf Enforcement um, Namespace fuer Namespace. Beginnt mit den am wenigsten kritischen Workloads.

Weitergehende Themen

Egress Filtering ist ein Baustein einer umfassenden Netzwerksicherheit. Verwandte Themen, die ihr euch ansehen solltet:

Fazit

Egress Filtering gehoert zu den wirksamsten Sicherheitsmassnahmen in Kubernetes, wird aber zu selten eingesetzt. Mit nativen NetworkPolicies und einem Default-Deny-Ansatz laesst sich bereits ein Grossteil der Angriffflaeche reduzieren. Cilium erweitert das sinnvoll um DNS-basierte Regeln.

Der Aufwand fuer die Implementierung ist ueberschaubar, wenn man schrittweise vorgeht. Der Ertrag -- Schutz vor Datenexfiltration, geringere Blast Radius bei Kompromittierung, bessere Compliance-Nachweise -- ist erheblich.

Wenn ihr Unterstuetzung bei der Planung oder Umsetzung eurer Egress-Strategie braucht, sprecht uns an unter /kontakt.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen