Was macht Auditing von Kubernetes-Cluster RBAC?
Wann verwenden
- Bei Sicherheitsbewertungen von Kubernetes-Clustern (EKS, GKE, AKS oder selbstverwaltet)
- Bei der Validierung, dass RBAC-Richtlinien das Least-Privilege-Prinzip für Benutzer und Service Accounts durchsetzen
- Bei der Untersuchung möglicher lateraler Bewegung oder Privilegieneskalation innerhalb eines Kubernetes-Clusters
- Wenn Compliance-Audits eine Dokumentation der Zugriffskontrollen und Berechtigungen erfordern
- Beim Onboarding neuer Teams in einen gemeinsam genutzten Cluster und der Definition geeigneter RBAC-Richtlinien
Nicht verwenden für die Überprüfung von Netzwerkrichtlinien (dafür Cilium- oder Calico-Netzwerkrichtlinien-Tools), für das Scannen von Container-Images (dafür Trivy oder Grype) oder für die Laufzeit-Sicherheitsüberwachung (dafür Falco oder Sysdig Secure).
Voraussetzungen
- kubectl mit Cluster-Admin- oder gleichwertigen Leseberechtigungen für den Zielcluster konfiguriert
- rbac-tool installiert (
kubectl krew install rbac-tooloder Binary von GitHub) - KubiScan installiert (
pip install kubiscan) - Kubeaudit installiert (
brew install kubeauditoder von GitHub-Releases) - Zugriff auf die Audit-Logs des Clusters, um RBAC-Ergebnisse mit tatsächlichem API-Zugriff korrelieren zu können
Workflow
Schritt 1: Aufzählen von ClusterRoles und Roles mit gefährlichen Berechtigungen
Identifiziere Rollen mit Wildcard-Berechtigungen, Secret-Zugriff, Pod-Exec oder Eskalationsfähigkeiten.
# Alle ClusterRoles mit Wildcard-Verb-Zugriff auflisten
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
verbs = rule.get('verbs', [])
resources = rule.get('resources', [])
if '*' in verbs or '*' in resources:
print(f'ClusterRole: {name}')
print(f' Verbs: {verbs}')
print(f' Resources: {resources}')
print(f' API Groups: {rule.get(\"apiGroups\", [])}')
print()
"
# Rollen finden, die Secrets lesen können
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
resources = rule.get('resources', [])
verbs = rule.get('verbs', [])
if ('secrets' in resources or '*' in resources) and ('get' in verbs or 'list' in verbs or '*' in verbs):
if not name.startswith('system:'):
print(f'ClusterRole: {name} -> kann auf Secrets zugreifen (verbs: {verbs})')
"
# Rollen mit pod/exec-Berechtigungen finden (Container-Escape-Risiko)
kubectl get clusterroles -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for role in data['items']:
name = role['metadata']['name']
for rule in role.get('rules', []):
resources = rule.get('resources', [])
if 'pods/exec' in resources or 'pods/*' in resources:
print(f'ClusterRole: {name} -> hat pods/exec-Zugriff')
"
Schritt 2: Überprüfen von ClusterRoleBindings und RoleBindings
Überprüfe Bindungen, um zu identifizieren, wer erhöhten Zugriff hat, und erkenne zu weit gefasste Gruppenvergaben.
# Alle ClusterRoleBindings mit den Subjekten auflisten
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
name = binding['metadata']['name']
role = binding['roleRef']['name']
subjects = binding.get('subjects', [])
for subject in subjects:
kind = subject.get('kind', '')
subj_name = subject.get('name', '')
ns = subject.get('namespace', 'cluster-weit')
print(f'{name} -> Rolle: {role} | {kind}: {subj_name} ({ns})')
" | sort
# Bindungen an cluster-admin finden
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
if binding['roleRef']['name'] == 'cluster-admin':
print(f\"Binding: {binding['metadata']['name']}\")
for subject in binding.get('subjects', []):
print(f\" {subject.get('kind')}: {subject.get('name')} (ns: {subject.get('namespace', 'N/A')})\")
"
# Bindungen finden, die allen authentifizierten Benutzern Zugriff gewähren
kubectl get clusterrolebindings -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for binding in data['items']:
for subject in binding.get('subjects', []):
if subject.get('name') in ['system:authenticated', 'system:unauthenticated']:
print(f\"WARNUNG: {binding['metadata']['name']} gewährt {binding['roleRef']['name']} an {subject['name']}\")
"
Schritt 3: Scannen mit rbac-tool für umfassende Analyse
Verwende rbac-tool für die automatisierte RBAC-Analyse, einschließlich Who-Can-Abfragen und Richtlinien-Generierung.
# Wer kann über alle Namespaces hinweg Secrets abrufen?
kubectl rbac-tool who-can get secrets
# Wer kann Pods erstellen (Potential für Container-Escape)?
kubectl rbac-tool who-can create pods
# Wer kann in Pods exec ausführen?
kubectl rbac-tool who-can create pods/exec
# Wer kann Berechtigungen eskalieren (bind/escalate-Verben)?
kubectl rbac-tool who-can bind clusterroles
kubectl rbac-tool who-can escalate clusterroles
# RBAC-Richtlinienbericht generieren
kubectl rbac-tool analysis
# RBAC-Beziehungen visualisieren
kubectl rbac-tool viz --outformat dot > rbac-graph.dot
dot -Tpng rbac-graph.dot -o rbac-graph.png
Schritt 4: KubiScan für die Erkennung riskanter Berechtigungen ausführen
Verwende KubiScan, um automatisch riskante Service Accounts, Pods und RBAC-Konfigurationen zu identifizieren.
# KubiScan ausführen, um riskante Rollen zu finden
python3 -m kubiscan -rroles # Riskante Rollen auflisten
python3 -m kubiscan -rcr # Riskante ClusterRoles auflisten
python3 -m kubiscan -rrb # Riskante RoleBindings auflisten
python3 -m kubiscan -rcrb # Riskante ClusterRoleBindings auflisten
# Riskante Service Accounts finden
python3 -m kubiscan -rs # Riskante Service Accounts
# Pods finden, die mit riskanten Service Accounts laufen
python3 -m kubiscan -rp # Riskante Pods
# Auf Privilegieneskalationspfade prüfen
python3 -m kubiscan -pe # Privilegieneskalationsvektoren
# Vollständigen Bericht generieren
python3 -m kubiscan -a # Alle Prüfungen
Schritt 5: Überprüfen des Einbindens und der Nutzung von Service-Account-Tokens
Prüfe auf unnötige Service-Account-Token-Einhängungen, die laterale Bewegung von kompromittierten Pods aus ermöglichen könnten.
# Pods mit automatisch eingehängten Service-Account-Tokens finden
kubectl get pods --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pod in data['items']:
name = pod['metadata']['name']
ns = pod['metadata']['namespace']
sa = pod['spec'].get('serviceAccountName', 'default')
automount = pod['spec'].get('automountServiceAccountToken', True)
if automount and sa != 'default':
print(f'{ns}/{name} -> SA: {sa} (Token automatisch eingehängt)')
"
# Service Accounts mit nicht standardmäßigen Token-Secrets finden
kubectl get serviceaccounts --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for sa in data['items']:
name = sa['metadata']['name']
ns = sa['metadata']['namespace']
secrets = sa.get('secrets', [])
if name != 'default' and len(secrets) > 0:
print(f'{ns}/{name}: {len(secrets)} Secret(s) gebunden')
"
# Prüfen, ob Pods privilegiert oder mit Host-Zugriff laufen
kubectl get pods --all-namespaces -o json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pod in data['items']:
name = pod['metadata']['name']
ns = pod['metadata']['namespace']
for container in pod['spec'].get('containers', []):
sc = container.get('securityContext', {})
if sc.get('privileged', False) or sc.get('runAsUser', 1) == 0:
print(f'RISIKO: {ns}/{name}/{container[\"name\"]} - privilegiert={sc.get(\"privileged\",False)} runAsRoot={sc.get(\"runAsUser\",\"nicht gesetzt\")==0}')
"
Schritt 6: Kubeaudit für die Validierung von RBAC- und Sicherheitsrichtlinien ausführen
Führe Kubeaudit für umfassende Sicherheitsprüfungen einschließlich RBAC-bezogener Ergebnisse aus.
# Alle Kubeaudit-Prüfungen ausführen
kubeaudit all --kubeconfig ~/.kube/config
# Bestimmte RBAC-bezogene Prüfungen ausführen
kubeaudit privesc # Prüfen auf allowPrivilegeEscalation
kubeaudit rootfs # Prüfen auf readOnlyRootFilesystem
kubeaudit nonroot # Prüfen auf runAsNonRoot
kubeaudit capabilities # Prüfen auf gefährliche Capabilities
# Ausgabe als JSON zur Verarbeitung
kubeaudit all --kubeconfig ~/.kube/config -f json > kubeaudit-results.json
Schlüsselkonzepte
| Begriff | Definition |
|---|---|
| RBAC | Rollenbasierte Zugriffskontrolle in Kubernetes, eine Methode zur Regelung des Zugriffs auf Cluster-Ressourcen basierend auf Rollen einzelner Benutzer oder Service Accounts |
| ClusterRole | Clusterweite Rollendefinition, die Berechtigungen (Verben auf Ressourcen) festlegt, die über alle Namespaces hinweg gelten |
| ClusterRoleBinding | Verknüpft eine ClusterRole mit Subjekten (Benutzer, Gruppen, Service Accounts) auf Clusterebene |
| Service Account | Identität, die Pods zugeordnet wird, um sich beim Kubernetes-API-Server zu authentifizieren; wird standardmäßig eingehängt, sofern nicht deaktiviert |
| automountServiceAccountToken | Pod-Spec-Feld, das steuert, ob das Service-Account-Token automatisch in das Dateisystem des Pods eingehängt wird |
| Privilegieneskalation | RBAC-Verben (bind, escalate, impersonate), die es einem Benutzer erlauben, sich selbst oder anderen erhöhte Berechtigungen zu gewähren |
Tools und Systeme
- kubectl: Primäre CLI zum Abfragen von Kubernetes-RBAC-Ressourcen (Rollen, Bindungen, Service Accounts)
- rbac-tool: kubectl-Plugin für RBAC-Analyse, einschließlich Who-Can-Abfragen, Visualisierung und Richtlinien-Generierung
- KubiScan: Python-Tool zum Scannen von Kubernetes-RBAC auf riskante Berechtigungen und Privilegieneskalationspfade
- Kubeaudit: Sicherheits-Audit-Tool, das Pods und Workloads auf Sicherheits-Antipatterns einschließlich RBAC-Problemen prüft
- rakkess: kubectl-Plugin, das die Zugriffsmatrix des aktuellen Benutzers auf alle Ressourcentypen anzeigt
Häufige Szenarien
Szenario: Überprüfung eines EKS-Clusters, der von mehreren Entwicklungsteams gemeinsam genutzt wird
Kontext: Ein gemeinsam genutzter EKS-Cluster bedient vier Entwicklungsteams. RBAC wurde während der Ersteinrichtung konfiguriert, aber seit 12 Monaten nicht überprüft. Teams berichten, dass sie auf die Namespaces anderer Teams zugreifen können.
Vorgehen:
- Alle ClusterRoleBindings auflisten, um Bindungen zu identifizieren, die authentifizierten Benutzern breiten Zugriff gewähren
kubectl rbac-tool who-can get secretsausführen, um Subjekte zu finden, die Secrets über Namespaces hinweg lesen können- Entdecken, dass eine ClusterRoleBinding
editansystem:authenticatedvergibt, wodurch alle Benutzer clusterweit Schreibzugriff haben - KubiScan ausführen, um Service Accounts mit riskanten Berechtigungen und Pods mit erhöhten Service Accounts zu identifizieren
- Die ClusterRoleBinding durch namespace-bezogene RoleBindings für jedes Team ersetzen
- automountServiceAccountToken für Workloads deaktivieren, die keinen API-Zugriff benötigen
- Eine NetworkPolicy erstellen, um den Namespace-Datenverkehr zwischen Teams zu isolieren
Fallstricke: Das Entfernen von ClusterRoleBindings kann CI/CD-Pipelines und Operatoren beschädigen, die auf clusterweiten Zugriff angewiesen sind. Vor dem Entfernen sollte immer überprüft werden, welche Workloads die Bindungen verwenden. EKS bildet IAM-Rollen über die aws-auth-ConfigMap auf Kubernetes-Gruppen ab, daher müssen RBAC-Änderungen mit IAM-Rollenzuordnungen koordiniert werden.
Ausgabeformat
Kubernetes RBAC Audit-Bericht
===============================
Cluster: production-eks (EKS 1.28)
Audit-Datum: 2026-02-23
Namespaces: 12
RBAC-BESTANDSAUFNAHME:
ClusterRoles: 48 (18 benutzerdefiniert, 30 system)
ClusterRoleBindings: 32 (12 benutzerdefiniert, 20 system)
Roles (namespace-bezogen): 24
RoleBindings (namespace-bezogen): 36
Service Accounts: 67
KRITISCHE FESTSTELLUNGEN:
[RBAC-001] ClusterRoleBinding gewährt edit an system:authenticated
Bindung: authenticated-edit
Auswirkung: ALLE authentifizierten Benutzer haben Edit-Zugriff über ALLE Namespaces hinweg
Risiko: Jeder Benutzer kann Ressourcen in jedem Namespace ändern
Abhilfe: Ersetzen durch namespace-bezogene RoleBindings pro Team
[RBAC-002] Benutzerdefinierte ClusterRole mit Wildcard-Berechtigungen
ClusterRole: developer-admin
Regeln: verbs=["*"], resources=["*"], apiGroups=["*"]
Bindungen: 4 Benutzer über developer-admin-binding
Risiko: Äquivalent zu cluster-admin, ohne den Namen zu tragen
Abhilfe: Auf spezifische Ressourcen und benötigte Verben eingrenzen
ZUSAMMENFASSUNG:
Subjekte mit cluster-admin: 6 (empfohlen: <= 3)
Rollen mit Wildcard-Berechtigungen: 4
Service Accounts mit Secret-Zugriff: 12
Pods mit automatisch eingehängten Tokens: 45 / 67
Privilegierte Container: 8