TL;DR
Kubernetes Network Policies ermöglichen die ess
Diese Zusammenfassung wurde KI-gestützt erstellt (EU AI Act Art. 52).
Inhaltsverzeichnis (5 Abschnitte)
In einem Standard-Kubernetes-Cluster ohne Network Policies können alle Pods miteinander kommunizieren - jeder kann jeden erreichen. Das ist für die Entwicklung praktisch, aber sicherheitstechnisch ein Problem: ein kompromittierter Pod kann alle anderen Pods im Cluster angreifen. Network Policies implementieren Mikrosegmentierung und das Least-Privilege-Prinzip auf Netzwerkebene.
Grundkonzept
Problem ohne Network Policies:
Namespace: production
Pod: frontend (Port 3000) → API-Anfragen
Pod: backend (Port 8080) → Business-Logik
Pod: database (Port 5432) → PostgreSQL
OHNE Network Policies:
frontend ←→ backend ←→ database ✓ (gewünscht)
frontend → database ✓ (UNERWÜNSCHT! Frontend sollte DB nicht erreichen)
database → frontend ✓ (UNERWÜNSCHT! DB sollte keine ausgehenden Connections machen)
Kompromittiertes Frontend:
→ Angreifer kann direkt auf database:5432 zugreifen
→ Keine zusätzliche Hürde!
MIT Network Policies (richtig konfiguriert):
frontend → backend (8080): ERLAUBT
frontend → database (5432): BLOCKIERT ✓
backend → database (5432): ERLAUBT
database → irgendwo: BLOCKIERT ✓
Network Policy Grundregeln:
→ Policies sind ADDITIV: eine Allow-Regel reicht für Erlaubnis
→ Policies sind WHITELIST-basiert: wenn ein Policy ein Pod selektiert,
wird ALLES andere blockiert was nicht explizit erlaubt ist
→ Kein Policy = kein Restriction (alle Verbindungen erlaubt!)
→ Default-Deny: muss explizit durch Policy implementiert werden
Network Policy Syntax
Grundstruktur einer Network Policy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-policy
namespace: production
spec:
podSelector: # Auf welche Pods wird diese Policy angewendet?
matchLabels:
app: backend
policyTypes: # Was wird spezifiziert?
- Ingress # Eingehender Traffic
- Egress # Ausgehender Traffic
ingress: # Eingehende Traffic-Regeln
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress: # Ausgehende Traffic-Regeln
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
Selektoren im Detail:
podSelector (Pods im gleichen Namespace):
- from:
- podSelector:
matchLabels:
app: frontend
namespaceSelector (Pods aus anderem Namespace):
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
Kombination (Pods in spezifischem Namespace):
- from:
- namespaceSelector:
matchLabels:
environment: production
podSelector: # UND-Verknüpfung (gleicher Listeneintrag!)
matchLabels:
app: prometheus
# ACHTUNG: Zwei getrennte Listeneinträge = ODER-Verknüpfung!
# Gleicher Eintrag = UND-Verknüpfung!
ipBlock (externe IP-Bereiche):
- from:
- ipBlock:
cidr: 10.0.0.0/8
except:
- 10.1.1.0/24 # Diese Range ausschließen
Praktische Policy-Patterns
Pattern 1 - Default-Deny-All (Basis für jede sichere Konfiguration):
# Kein Traffic erlaubt zu diesem Pod (Ingress + Egress)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # Leerer Selektor = ALLE Pods im Namespace
policyTypes:
- Ingress
- Egress
# Keine ingress/egress Regeln = alles verboten!
# Dann gezielt erlauben:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- port: 5432
Pattern 2 - Namespace-Isolation (empfohlen für alle Namespaces):
# Kein Ingress aus anderen Namespaces
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # Nur Pods im GLEICHEN Namespace
# Kein namespaceSelector = nur gleicher Namespace!
Pattern 3 - Zugriff nur vom Monitoring-Namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus-scraping
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- port: 9090 # Metrics-Port
Pattern 4 - DNS-Egress erlauben (häufig vergessen!):
# Pods brauchen DNS-Zugriff!
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {} # Alle Pods
policyTypes:
- Egress
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
# Gleichzeitig kube-dns/CoreDNS erlauben:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
Pattern 5 - Internet-Egress für spezifische Pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-api
namespace: production
spec:
podSelector:
matchLabels:
app: api-client
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0 # Ganzes Internet
except:
- 10.0.0.0/8 # Private Ranges ausschließen
- 172.16.0.0/12 # (Kubernetes-interne Isolation)
- 192.168.0.0/16
ports:
- port: 443
- port: 80
CNI-Plugins und Service Mesh
Kubernetes braucht CNI-Plugin für Network Policy Enforcement:
Nicht alle CNI-Plugins unterstützen Network Policies!
Flannel: KEIN Network Policy Support (nur Layer-3-Routing)
Calico: Full Network Policy Support + erweiterte Features
Cilium: eBPF-basiert, L7-Policies, beste Performance
WeaveNet: Network Policy Support
Canal: Flannel + Calico-Policy-Enforcement
Calico NetworkPolicy (erweiterte Syntax):
# Calico erlaubt mehr als Standard-K8s-Policies:
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-https-only
spec:
selector: app == 'frontend'
types:
- Egress
egress:
- action: Allow
protocol: TCP
destination:
ports: [443]
- action: Deny # Explizites Deny!
Cilium (eBPF-basierte L7-Policies):
# HTTP-Methoden-basierte Policy:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: api-policy
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/.*"
- method: "POST"
path: "/api/v1/orders"
# → Nur GET/POST auf spezifische Pfade erlaubt!
# → Layer-7-Filtering ohne Service Mesh!
Service Mesh (Istio/Linkerd):
Istio AuthorizationPolicy (ergänzend zu K8s Network Policies):
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: backend-policy
spec:
selector:
matchLabels:
app: backend
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/prod/sa/frontend-sa"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
Vorteile Service Mesh vs. Network Policies:
Network Policies: IP/Port-Level, Layer-3/4
Service Mesh: mTLS, L7-Filtering, RBAC, Observability
→ Beste Sicherheit: beides kombinieren!
Troubleshooting und Best Practices
Häufige Fehler und wie man sie vermeidet:
Fehler 1 - ODER statt UND bei Selektoren:
# FALSCH (OR-Semantik!):
ingress:
- from:
- podSelector: # Regel 1: Pods mit app=api
matchLabels:
app: api
- namespaceSelector: # Regel 2: ODER alle aus monitoring-NS
matchLabels:
purpose: monitoring
# RICHTIG (AND-Semantik):
ingress:
- from:
- podSelector: # Pods mit app=api
matchLabels:
app: api
namespaceSelector: # UND im monitoring-NS
matchLabels:
purpose: monitoring
Fehler 2 - DNS vergessen:
→ Default-Deny-Egress → DNS-Auflösung schlägt fehl → App kann Service-Names nicht auflösen
→ IMMER DNS-Egress (Port 53 UDP+TCP) erlauben!
Fehler 3 - Kube-System vergessen:
→ Manche K8s-interne Services im kube-system Namespace
→ Health-Checks, Metrics, Admission Webhooks brauchen Zugriff
→ Testen nach Policy-Deployment ob Cluster-Health OK!
Fehler 4 - NodePort/LoadBalancer vergessen:
→ Externe Anfragen kommen von Node-IP → andere IP als Pod-IP
→ ipBlock mit Cluster-IP-Range nötig für externe Anfragen
Debugging:
# Alle Network Policies im Namespace:
kubectl get networkpolicies -n production
kubectl describe networkpolicy my-policy -n production
# Pod-Konnektivität testen:
kubectl exec -n production frontend-pod -- \
curl -v backend-service:8080/api/health
# Wenn blockiert: Connection refused oder timeout
# Cilium: Netzwerkflüsse beobachten:
cilium monitor --type drop # Zeigt geblockte Verbindungen!
cilium monitor --type trace # Alle Verbindungen
# Calico: Flow-Logs aktivieren (kommerzielles Feature)
# Netreap / Retina (Microsoft): eBPF-basiertes Network-Monitoring
Verifikation der Policy (Policy-Testing):
kubectl auth can-i --list --as=system:serviceaccount:prod:default
# Zeigt ob Service Account erwartete Rechte hat
# Tool: kubectl-np-viewer (Visualisierung):
kubectl np-viewer -n production
Network Policies sind ein unverzichtbares Sicherheitselement in Kubernetes-Produktionsclustern. Der Aufwand für ihre Implementierung zahlt sich durch erheblich reduziertes Lateral-Movement-Risiko aus: ein kompromittierter Pod kann nicht mehr alle anderen Pods und Services erreichen. AWARE7 überprüft Kubernetes-Cluster-Konfigurationen auf fehlende oder zu permissive Network Policies als Teil von Cloud-Security-Assessments.
Nächster Schritt
Unsere zertifizierten Sicherheitsexperten beraten Sie zu den Themen aus diesem Artikel — unverbindlich und kostenlos.
Kostenlos · 30 Minuten · Unverbindlich
