Was das Kubernetes-Audit-Log verrät
Jeder Request an den Kubernetes-API-Server — von kubectl, Controllern, Kubelets oder einem gestohlenen Token — kann als Audit-Event erfasst werden: wer (Benutzer, Gruppen, Service Account), von wo (Quell-IPs, User Agent), was (Verb, Ressource, Namespace, Name, Subressource), ob es erlaubt wurde und warum (das RBAC-Binding) und auf höheren Stufen der Request-Body selbst.
Das macht es zum wichtigsten Beweismittel zur Beantwortung der Frage "Wurde unser Cluster kompromittiert?": Ein gestohlenes Service-Account-Token, ein privilegierter Pod, der den Node mountet, ein neues cluster-admin-Binding oder ein Crypto-Miner-CronJob hinterlassen alle API-Aufrufe, selbst wenn die Workloads selbst nicht mehr existieren.
Was dieses Tool erkennt
- Execution: pods/exec und pods/attach (insbesondere durch Service Accounts), Port-Forward, Kubelet-Zugriff über nodes/proxy.
- Credential Access: namespace-übergreifend aufgelistete Secrets, Häufungen von Secret-Lesezugriffen, mit TokenRequest ausgestellte Service-Account-Tokens.
- Privilege Escalation und Container-Escape: privilegierte Container, hostPID/hostNetwork/hostIPC, hostPath-Mounts von / oder Runtime-Sockets, DaemonSets in kube-system.
- RBAC-Missbrauch: neue Bindings an cluster-admin, Rollen mit escalate/bind/impersonate oder Wildcards, Impersonation, für anonyme Benutzer gewährter Zugriff.
- Recon: kubectl-auth-can-i-Häufungen (SelfSubjectAccessReviews / RulesReviews), Häufungen von 403-Antworten, mit kubectl oder curl bzw. von öffentlichen IPs verwendete Service-Account-Tokens, bekannte User Agents von Angriffstools.
- Impact und Persistence: Crypto-Miner-Images und -Befehle, Images aus unüblichen Registries, CronJobs, gelöschte Kubernetes-Events. Optionale Falco-Alerts werden auf derselben Timeline korreliert.
- Erkennungen sind Daten: eine geprüfte JSON-Regeldatei (Sigma-ähnliche Bedingungen), zugeordnet zur MITRE-ATT&CK-Containers-Matrix, sodass sie gelesen, geprüft und in anderen Tools wiederverwendet werden können.
So exportieren Sie Kubernetes-Audit-Logs
Audit-Logging muss vor einem Incident aktiviert sein, um nützlich zu sein. Exportieren Sie den gesamten relevanten Zeitraum (idealerweise einige Tage vor dem ersten verdächtigen Event) als JSON; gzip und ZIP sind unterstützt.
Self-managed (kubeadm, k3s, RKE2, On-Premises)
- Der API-Server schreibt Audit-Events, wenn er mit --audit-policy-file und --audit-log-path gestartet wird (zum Beispiel /var/log/kubernetes/audit/audit.log).
- Kopieren Sie auf jedem Control-Plane-Node die aktuelle audit.log und deren rotierte Dateien (audit-*.log, ggf. .gz).
- Wenn Sie Audit-Events über das Webhook-Backend versenden (Fluent Bit, Vector, ein SIEM), exportieren Sie diese von dort als JSON Lines.
- Legen Sie die Dateien oder den ganzen Ordner hier ab.
Amazon EKS
- Das Control-Plane-Logging muss den Log-Typ "audit" enthalten (EKS-Konsole → Cluster → Observability → Control plane logging).
- Die Events liegen in CloudWatch Logs, Log-Gruppe /aws/eks/<cluster>/cluster, Streams kube-apiserver-audit-*.
- Für kleine Zeiträume: aws logs filter-log-events --log-group-name /aws/eks/<cluster>/cluster --log-stream-name-prefix kube-apiserver-audit --start-time <ms> --end-time <ms> > eks-audit.json
- Für große Zeiträume: einen Export-Task nach S3 anlegen (aws logs create-export-task), die .gz-Dateien herunterladen und den Ordner ablegen. Als JSON exportierte CloudWatch-Logs-Insights-Ergebnisse funktionieren ebenfalls.
Google GKE
- Admin-Activity-Audit-Logs sind immer aktiv; Data-Access-Logs (get/list, Secret-Lesezugriffe) müssen für die Kubernetes Engine API unter IAM → Audit Logs aktiviert werden.
- Export mit gcloud: gcloud logging read 'resource.type="k8s_cluster" AND logName:"cloudaudit.googleapis.com"' --project=<project> --freshness=30d --format=json > gke-audit.json
- Alternativ die Ergebnisse aus Logs Explorer als JSON herunterladen oder für lange Zeiträume einen Log-Sink nach Cloud Storage / BigQuery verwenden (BigQuery-Zeilen als JSON oder zeilengetrenntes JSON exportieren).
- Legen Sie die JSON-Dateien hier ab; Einträge anderer Dienste werden ignoriert.
Azure AKS
- Erstellen Sie eine Diagnoseeinstellung für den Cluster mit der Kategorie kube-audit (oder kube-audit-admin, die get/list ausschließt).
- Ziel Storage Account: Laden Sie die PT1H.json-Blobs unter insights-logs-kube-audit/… herunter und legen Sie den Ordner ab.
- Ziel Log Analytics: Fragen Sie AKSAudit ab (oder AzureDiagnostics | where Category startswith "kube-audit") und exportieren Sie die Ergebnisse als JSON, nicht als CSV.
- Auch Event-Hubs-Exporte ({"records": […]}) werden unterstützt.
Stellen Sie sicher, dass die Beweise vorhanden sind
- Protokollieren Sie mindestens Metadata für alles sowie Request oder RequestResponse für RBAC-Objekte, Workloads, pods/exec und serviceaccounts/token: Ohne Request-Bodies lassen sich privilegierte Pods und cluster-admin-Bindings nicht erkennen.
- Protokollieren Sie niemals die Bodies von secrets, configmaps oder tokenreviews (nur Metadata): Das Log würde sonst selbst zu einem Credential-Speicher.
- Bewahren Sie Audit-Logs außerhalb des Clusters für mindestens 90 Tage auf: Angreifer mit cluster-admin können alles innerhalb des Clusters manipulieren.
Einschränkungen
- Das Audit-Log sieht nur den API-Server: Aktivität innerhalb eines Containers oder auf einem Node (eine Reverse Shell, ein manuell gestarteter Miner) ist ohne Runtime-Tools wie Falco unsichtbar.
- Was erkannt wird, hängt von Ihrer Audit-Policy ab: Auf Metadata-Ebene fehlen Request-Bodies (privileged-Flags, Images, roleRef), und mehrere Erkennungen können nicht auslösen.
- Regeln markieren Muster, keine Absicht: Auch legitime Admins führen kubectl exec aus, und Operatoren erstellen DaemonSets. Jedes Finding braucht eine menschliche Überprüfung.
- Es werden nur JSON-Exporte gelesen (CSV-Exporte werden noch nicht unterstützt). Service-Account-Namen Ihrer eigenen Plattformkomponenten müssen unter Umständen den Allow-Lists der Regeln hinzugefügt werden.
FAQ
Werden meine Audit-Logs irgendwohin hochgeladen?
Nein. Der Analyzer ist in Rust geschrieben, zu WebAssembly kompiliert und läuft in einem Web Worker in Ihrem Browser; Dateien werden in Chunks von Ihrer Festplatte gestreamt. Es gibt keinen Upload-Endpunkt.
Wie groß darf ein Export sein?
Dateien werden als Stream gelesen und dekomprimiert, daher ist die Größe vor allem durch die Zeit begrenzt: Rechnen Sie je nach Rechner mit einigen zehn bis wenigen hundert MB pro Minute. Kleine Exporte lassen jedes Event durchsuchbar; ab 50.000 Events werden nur markierte Events behalten, während Zählungen, Entitäten und Findings weiterhin alles abdecken.
Welche Formate werden unterstützt?
Rohe audit.k8s.io/v1-JSON-Lines, EKS-CloudWatch-Exporte (filter-log-events, Logs-Insights-JSON, S3-Export-Dateien), GKE-Cloud-Logging-JSON (gcloud logging read, Logs-Explorer-Downloads, Sinks), AKS-Diagnoseprotokolle (Storage Account, Event Hubs, AKSAudit-/AzureDiagnostics-JSON), gzip und ZIP sowie Falco-JSON-Alerts.
Wie erkenne ich kubectl exec in Audit-Logs?
kubectl exec erzeugt einen Request auf der Subressource pods/exec (Verb create oder get, objectRef.subresource exec); der Befehl steht als command=-Parameter in der requestURI. Dieses Tool listet jede exec-, attach- und port-forward-Aktion auf und erhöht die Schwere, wenn ein Service Account dies tut.
Bedeutet "Kein Hinweis auf Kompromittierung", dass wir sicher sind?
Nein. Es bedeutet nur, dass keine der Regeln in den bereitgestellten Logs angeschlagen hat. Lücken in der Audit-Policy, fehlende Zeiträume und Aktivität innerhalb von Containern können eine Intrusion verbergen. Wenn Sie andere Gründe zur Sorge haben, holen Sie eine fachkundige Überprüfung ein.
Kann ich die Erkennungsregeln einsehen oder wiederverwenden?
Ja. Es handelt sich um eine JSON-Datei im offenen Repository (crates/k8s-audit-wasm/rules) mit Bedingungen, Schwellenwerten, MITRE-ATT&CK-Technik-IDs und Behebungsschritten, sodass sie geprüft und in anderen Tools wiederverwendet werden können.