- Authors

- Name
- Phillip Pham
- @ddppham
Kubernetes API Security: Rate Limiting, Authentication und Gateway-Schutz
TL;DR
- Rate Limiting am Ingress Controller ist die einfachste erste Verteidigungslinie -- drei Nginx-Annotations reichen fuer den Anfang.
- JWT-Validation und OAuth2-Proxy gehoeren vor die eigentlichen Services, nicht in den Anwendungscode.
- Ein API Gateway (Kong, Envoy Gateway, APISIX) lohnt sich ab 5+ APIs oder wenn Request-Transformation noetig ist.
- Network Policies und mTLS (Service Mesh) schuetzen die Ost-West-Kommunikation innerhalb des Clusters.
- Monitoring der 429-Responses und Authentication-Fehler ist Pflicht -- ohne Metriken wisst ihr nicht, ob eure Regeln greifen.
Das Problem: APIs als Angriffsflaeche
Jeder Kubernetes-Service, der ueber einen Ingress oder LoadBalancer exponiert wird, ist eine potenzielle Angriffsflaeche. Die haeufigsten Bedrohungen:
- Brute-Force auf Login-Endpunkte -- automatisierte Passwortraten-Angriffe.
- DDoS auf API-Endpunkte -- Ueberflutung mit Anfragen, bis Backend-Pods OOMKilled werden.
- Token-Theft und Replay-Attacks -- gestohlene JWTs werden wiederverwendet.
- Unautorisierte Zugriffe -- fehlende oder fehlerhafte Authentifizierung laesst Endpunkte offen.
Die Loesung ist ein mehrschichtiger Ansatz: Rate Limiting als aeussere Schicht, Authentication/Authorization als mittlere Schicht und Network Policies als innere Schicht.
Rate Limiting am Nginx Ingress Controller
Der Nginx Ingress Controller unterstuetzt Rate Limiting ueber Annotations. Das ist der schnellste Weg, grundlegenden Schutz zu aktivieren.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
# Max 10 Requests pro Sekunde pro Client-IP
nginx.ingress.kubernetes.io/limit-rps: "10"
# Burst: bis zu 20 Requests kurzzeitig erlaubt
nginx.ingress.kubernetes.io/limit-burst-multiplier: "2"
# HTTP 429 zurueckgeben, wenn Limit ueberschritten
nginx.ingress.kubernetes.io/limit-status-code: "429"
# Shared Memory Zone fuer Rate-Limit-State (10 MB)
nginx.ingress.kubernetes.io/limit-zone-size: "10m"
# Rate Limiting nur auf bestimmten Pfad anwenden
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: api-tls
rules:
- host: api.example.com
http:
paths:
- path: /api/v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Rate-Limiting-Strategien im Vergleich
| Strategie | Anwendungsfall | Konfigurationsort | Granularitaet |
|---|---|---|---|
| IP-basiert | DDoS-Schutz, Brute-Force-Abwehr | Ingress Annotations | Pro Client-IP |
| User/API-Key-basiert | Faire Nutzung, Abrechnungsmodelle | API Gateway | Pro authentifiziertem Nutzer |
| Endpunkt-spezifisch | Schutz ressourcenintensiver Endpoints | Ingress/Gateway pro Route | Pro API-Pfad |
| Global (Cluster-weit) | Gesamtkapazitaet schuetzen | Gateway oder Service Mesh | Cluster-weit |
IP-basiertes Limiting faengt die groebsten Angriffe ab. Fuer differenziertere Kontrolle braucht es ein API Gateway mit User-basiertem Limiting.
Authentication vor den Service schieben
Der Anwendungscode sollte sich nicht um Token-Validation kuemmern muessen. Zwei gaengige Ansaetze:
OAuth2-Proxy als Sidecar oder Deployment
OAuth2-Proxy sitzt vor dem eigentlichen Service und prueft, ob ein gueltiges Token vorhanden ist. Ungueltige Requests werden abgewiesen, bevor sie den Service erreichen.
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
spec:
replicas: 2
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
args:
---provider=oidc
---oidc-issuer-url=https://idp.example.com/realms/main
---client-id=kubernetes-api
---client-secret-file=/secrets/client-secret
---cookie-secret-file=/secrets/cookie-secret
---upstream=http://api-service:8080
---email-domain=*
---skip-jwt-bearer-tokens=false
---oidc-email-claim=email
---pass-authorization-header=true
ports:
- containerPort: 4180
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: oauth2-proxy-secrets
Nginx Ingress mit externer Authentication
Der Nginx Ingress Controller kann Requests an einen externen Auth-Service weiterleiten, bevor sie an das Backend gehen:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: protected-api
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://oauth2-proxy.auth.svc.cluster.local:4180/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://api.example.com/oauth2/start?rd=$scheme://$host$request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /api/v1/protected
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Der Vorteil: Die Auth-Logik ist komplett vom Anwendungscode getrennt. Ein Service-Wechsel oder ein neuer Endpunkt braucht keine Code-Aenderungen -- nur eine neue Ingress-Ressource.
Wann ein API Gateway sinnvoll ist
Ein dediziertes API Gateway (Kong, APISIX, Envoy Gateway) bietet mehr als ein Ingress Controller:
| Feature | Ingress Controller | API Gateway |
|---|---|---|
| L7 Routing | Ja | Ja |
| TLS Termination | Ja | Ja |
| Rate Limiting | Basis (IP-basiert) | Erweitert (User, API-Key, Custom) |
| JWT Validation | Ueber Annotations/Snippets | Nativ mit Plugin |
| Request Transformation | Begrenzt | Ja (Header, Body, Query) |
| API Versioning | Manuell | Nativ |
| Developer Portal | Nein | Ja (bei Enterprise-Versionen) |
| Canary/A-B Routing | Begrenzt | Ja |
Faustregel: Bis zu 5 APIs mit einfacher Auth reicht der Nginx Ingress Controller. Ab 5+ APIs, bei Bedarf fuer Request-Transformation oder User-basiertem Rate Limiting lohnt sich ein Gateway.
Ein minimales Kong-Setup in Kubernetes:
# Kong via Helm installieren (OSS-Version)
helm repo add kong https://charts.konghq.com
helm repo update
helm install kong kong/ingress -n kong --create-namespace \
--set gateway.env.plugins="bundled,rate-limiting,jwt,cors" \
--set gateway.env.log_level="info"
# Rate-Limiting-Plugin fuer einen Service aktivieren
kubectl apply -f - <<EOF
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: rate-limit-5rps
config:
minute: 300
second: 5
policy: local
fault_tolerant: true
hide_client_headers: false
plugin: rate-limiting
EOF
# Plugin an einen Ingress haengen
kubectl annotate ingress my-api-ingress konghq.com/plugins=rate-limit-5rps
Ost-West-Sicherheit: mTLS und Network Policies
Rate Limiting und Authentication schuetzen den Nord-Sued-Traffic (extern nach intern). Aber was ist mit der Kommunikation zwischen Services im Cluster?
Zwei Massnahmen greifen hier:
1. Network Policies begrenzen, welche Pods miteinander sprechen duerfen. Siehe dazu den ausfuehrlichen Beitrag zu Kubernetes Network Policies.
2. mTLS ueber ein Service Mesh verschluesselt den Traffic zwischen Pods und verifiziert die Identitaet beider Seiten. Istio und Linkerd bieten das out-of-the-box. Ein Vergleich der beiden steht unter Istio vs. Linkerd.
Die Kombination aus beidem ist der Goldstandard: Network Policies als L3/L4-Firewall, mTLS als L7-Verschluesselung und Identitaetspruefung.
Monitoring: Was ihr messen muesst
Sicherheitsmassnahmen ohne Monitoring sind Blindflug. Mindestens diese Metriken sollten in Prometheus/Grafana landen:
- nginx_ingress_controller_requests mit Status-Code-Label -- Anstieg von 429 zeigt aktives Rate Limiting.
- nginx_ingress_controller_request_duration_seconds -- Latenz-Spikes koennen auf Angriffe hindeuten.
- Authentication-Fehler (401/403) -- gehaeufte Fehler deuten auf Brute-Force hin.
- Gateway-spezifische Metriken -- Kong/APISIX exportieren eigene Prometheus-Metriken zu Plugin-Aktivitaet.
Alerting-Regeln:
# Prometheus AlertRule: Zu viele 429-Responses
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: api-security-alerts
spec:
groups:
- name: api-security
rules:
- alert: HighRateLimitHits
expr: |
sum(rate(nginx_ingress_controller_requests{status="429"}[5m])) > 50
for: 5m
labels:
severity: warning
annotations:
summary: "Hohe Rate-Limit-Treffer: moeglicherweise DDoS oder Fehlkonfiguration"
- alert: AuthenticationFailureSpike
expr: |
sum(rate(nginx_ingress_controller_requests{status=~"401|403"}[5m])) > 20
for: 3m
labels:
severity: critical
annotations:
summary: "Gehaeufte Auth-Fehler: moeglicherweise Brute-Force-Angriff"
Mehr zum Thema Monitoring und Alerting findet ihr unter Kubernetes Monitoring und Observability.
Haeufige Fehler und wie man sie vermeidet
Rate Limits zu aggressiv setzen. Ein Limit von 1 RPS auf einem Health-Check-Endpunkt legt den gesamten Service lahm, weil Kubernetes Liveness Probes fehlschlagen. Testet Limits zuerst im Audit-Modus (nur loggen, nicht blocken).
Authentication nur am Ingress, nicht zwischen Services. Wenn ein Angreifer einen Pod kompromittiert, kann er ohne mTLS frei mit allen anderen Pods kommunizieren. Service Mesh oder zumindest Network Policies sind Pflicht.
Keine Trennung von Public und Internal APIs. Oeffentliche Endpunkte (Login, Registration) brauchen andere Rate Limits als interne Service-to-Service-Calls. Nutzt separate Ingress-Ressourcen oder Gateway-Routes.
Secrets im Cluster-Manifest. JWT-Signing-Keys und OAuth-Client-Secrets gehoeren in einen Secrets Manager (HashiCorp Vault, AWS Secrets Manager), nicht in Kubernetes Secrets. Mehr dazu unter Azure Key Vault vs. Kubernetes Secrets.
Weiter vertiefen
- Kubernetes Network Policies Advanced
- Kubernetes Security Hardening Checkliste
- Kubernetes Runtime Security
- Kubernetes RBAC fuer Enterprise
Fuer eine individuelle Sicherheitsanalyse eurer Cluster-Konfiguration oder Hilfe bei der Gateway-Auswahl steht unser Team unter /kontakt bereit.
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
API Gateway für Kubernetes: Nginx, Kong, Traefik
Kubernetes API Gateways im Vergleich: Nginx Ingress, Kong und Traefik mit Feature-Matrix, Installations-Aufwand und Gateway API HTTPRoute-Beispielen.
Gateway API: Der neue Kubernetes Ingress Standard
Kubernetes Gateway API als moderner Ingress-Ersatz. GatewayClass, Gateway und HTTPRoute konfigurieren, Traffic Splitting und Header-basiertes Routing einrichten.
external-dns: Automatische DNS-Einträge für Kubernetes
external-dns erstellt automatisch DNS-Einträge für Kubernetes Ingress und Services. Schritt-für-Schritt-Setup mit Cloudflare und AWS Route53 per Helm.
Kubernetes Ingress keine Adresse zugewiesen: Lösung
Kubernetes Ingress zeigt keine Address? Ursachen und Lösungen für fehlende IngressClass, nicht installierte Controller und Pending LoadBalancer.
AI Gateway auf Kubernetes: LLM-Routing und Kostenkontrolle
AI Gateway auf Kubernetes einrichten: Zentrales LLM-Routing, Rate Limiting, Kostenkontrolle und Observability für mehrere KI-Modelle.