Der Kubernetes-API-Server ist der einzige Weg, über den irgendetwas im Cluster verändert wird. Jeder kubectl-Befehl, jeder Controller, jedes CI/CD-Pipeline-Deployment läuft als Request gegen diese API. Audit-Logging protokolliert genau diese Requests: wer hat wann welchen Befehl gegen welche Ressource ausgeführt, mit welchem Ergebnis. Für einen Nachweis nach einem Vorfall oder in einer Prüfung ist das der Unterschied zwischen „wir vermuten“ und „wir können es zeigen“.
Konfiguriert wird das über eine Audit-Policy, eine YAML-Datei, die festlegt, welche Requests in welcher Tiefe protokolliert werden. Ohne diese Datei passiert nichts: Der API-Server protokolliert ohne gesetztes --audit-policy-file keine Audit-Events.
Die vier Audit-Stufen
Die Policy arbeitet mit vier Stufen:
None: Events, die auf diese Regel passen, werden gar nicht protokolliert.Metadata: Metadaten wie anfragender User, Zeitstempel, Ressource und Verb werden protokolliert, Request- und Response-Body nicht.Request: Metadaten und Request-Body werden protokolliert, der Response-Body nicht. Gilt nicht für Non-Resource-Requests.RequestResponse: Metadaten, Request-Body und Response-Body werden protokolliert. Gilt ebenfalls nicht für Non-Resource-Requests.
Regeln werden der Reihe nach geprüft, die erste passende Regel setzt die Stufe für das Event. Eine Policy ohne Regeln gilt als ungültig, mindestens eine Regel ist Pflicht.
Eine Audit-Policy, die du wirklich einsetzen kannst
Für die Praxis willst du nicht alles auf RequestResponse setzen, das erzeugt enorme Logmengen. Sinnvoller ist eine gestufte Policy: sensible Ressourcen wie Secrets und RBAC-Objekte auf RequestResponse, der Rest auf Metadata, reines Hintergrundrauschen von Systemkomponenten auf None. Die folgende Policy ist eine selbst entworfene Beispielkonfiguration zur Veranschaulichung, kein 1:1 aus der Kubernetes-Doku zitiertes Referenzbeispiel.
apiVersion: audit.k8s.io/v1kind: PolicyomitStages: - "RequestReceived"rules: - level: RequestResponse resources: - group: "" resources: ["secrets"] - group: "rbac.authorization.k8s.io" resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"] - level: RequestResponse verbs: ["create", "delete"] resources: - group: "" resources: ["pods"] - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] - level: None users: ["system:kube-proxy"] verbs: ["watch"] resources: - group: "" resources: ["endpoints", "services"] - level: Metadata
Die Datei übergibst du dem API-Server mit --audit-policy-file, zusammen mit --audit-log-path für das Ziel der Logdatei.
omitStages: Rauschen begrenzen, ohne Nachweise zu verlieren
Jeder Request durchläuft mehrere Stadien: RequestReceived, bei langlaufenden Requests wie watch zusätzlich ResponseStarted, dann ResponseComplete oder im Fehlerfall Panic. Mit omitStages: ["RequestReceived"] auf Policy-Ebene unterdrückst du das früheste, am wenigsten aussagekräftige Stadium global, ohne dass dir ResponseComplete (das Ergebnis der Aktion) verloren geht.
Backend-Optionen: Log oder Webhook
Kubernetes kennt zwei Backends. Das Log-Backend schreibt die Events als JSON Lines in eine Datei (--audit-log-path), mit Rotation über --audit-log-maxage, --audit-log-maxbackup und --audit-log-maxsize. Das Webhook-Backend sendet Events an eine externe HTTP-API, konfiguriert über --audit-webhook-config-file. Standardmäßig arbeitet der Webhook im Modus batch: Events werden gepuffert und asynchron verschickt, steuerbar über --audit-webhook-batch-max-size (Standard 400 Events) und --audit-webhook-batch-max-wait (Standard 30 Sekunden). Für Fälle, in denen kein Event verloren gehen darf, gibt es die Modi blocking und blocking-strict.
Lokaler Test mit kind
Wer das ausprobieren will, kann es in einem lokalen kind-Cluster tun, ohne eine Produktionsumgebung anzufassen: Policy-Datei und Log-Verzeichnis per extraMounts einbinden, --audit-policy-file und --audit-log-path über kubeadmConfigPatches an den API-Server reichen. Das ist ein lokaler Test zum Kennenlernen der Policy-Syntax, kein Produktionserlebnis.
Managed Kubernetes: Wo diese Konfiguration endet
Diese Konfiguration setzt Zugriff auf die Flags des API-Servers voraus. Bei verwalteten Angeboten wie EKS, GKE oder AKS hast du den nicht, der Control-Plane-Prozess liegt beim Cloud-Anbieter. Audit-Logging läuft dort über die jeweils eigene Plattform-Integration, bei EKS etwa über Control Plane Logging, nicht über eine selbst geschriebene --audit-policy-file. Die Stufen und das Konzept bleiben gleich, der Konfigurationsweg nicht.
Abgrenzung zu anderen Bausteinen
Falco erkennt verdächtiges Verhalten zur Laufzeit im Cluster, Audit-Logging dagegen den Zugriff auf den API-Server selbst. RBAC legt fest, wer welche Rechte hat, Audit-Logging zeigt, was mit diesen Rechten tatsächlich gemacht wurde. Pod Security Admission verhindert bestimmte Pod-Konfigurationen schon beim Erstellen, Audit-Logging protokolliert nachträglich jeden API-Zugriff, unabhängig davon, ob er erfolgreich war oder abgelehnt wurde.
Fragen zur Audit-Policy für deinen Cluster kannst du an mm@mhm-dl.de schicken.
Über das Anmeldeformular für den Newsletter trägst du deine E-Mail-Adresse ein, kreuzt die Einwilligung an und bestätigst die Anmeldung danach per Mail. Mit der Anmeldung willigst du ein, dass der Newsletter unter anderem folgende Themen behandelt: Schulungen zu Docker, Kubernetes, CI/CD, Git-Workflows und DevSecOps-Werkzeugen sowie die Anforderungen aus NIS2, CRA und DORA und deren technische Umsetzung.
Kommentar verfassen