Veröffentlicht am

Kubernetes Audit Logging konfigurieren: Schritt für Schritt

Teilen:
Authors

Kubernetes Audit Logging: Cluster-Aktivitaeten lueckenlos protokollieren

TL;DR

  • Kubernetes Audit Logs erfassen jede Interaktion mit dem API Server -- wer hat wann was getan, und ob es erfolgreich war
  • Die Audit Policy steuert den Detailgrad: None, Metadata, Request und RequestResponse -- starten Sie mit Metadata fuer die meisten Ressourcen und erhoehen selektiv
  • File-Backend ist einfach, Webhook-Backend ist skalierbarer -- fuer Produktionsumgebungen empfiehlt sich der Webhook an Fluentd/Fluent Bit, der an Loki oder Elasticsearch weiterleitet
  • Eine zu breite Policy erzeugt Terrabytes an Rauschen; eine zu enge Policy uebersieht sicherheitskritische Events -- die richtige Balance finden Sie nur durch iteratives Tuning
  • Audit Logging ist Pflicht fuer DSGVO-Rechenschaftspflicht (Art. 5 Abs. 2) und BSI-Grundschutz

Was Audit Logs erfassen und was nicht

Kubernetes Audit Logs sind keine Anwendungs-Logs. Sie erfassen ausschliesslich Interaktionen mit dem API Server. Jedes kubectl apply, jedes automatische Scaling-Event, jeder Service-Account-Zugriff wird als Audit Event protokolliert.

Ein einzelnes Audit Event enthaelt:

  • Wer: Benutzer oder ServiceAccount (user.username, user.groups)
  • Was: Ressource und Verb (objectRef.resource, verb)
  • Wann: Timestamp (requestReceivedTimestamp)
  • Woher: Source IP (sourceIPs)
  • Ergebnis: Status Code (responseStatus.code)
  • Optional: Request-Body und Response-Body (abhaengig vom Log-Level)

Was Audit Logs NICHT erfassen: Container-Logs (stdout/stderr), Netzwerk-Traffic zwischen Pods, Dateisystem-Aenderungen innerhalb von Containern. Dafuer brauchen Sie Runtime Security Tools wie Falco oder Tetragon.

Audit Policy: Die vier Log-Level im Detail

Die Audit Policy ist eine YAML-Datei, die dem API Server mitteilt, welche Events mit welchem Detailgrad protokolliert werden sollen. Die vier Level:

LevelErfasstTypischer Einsatz
NoneNichtsHealth Checks, System-Discovery, hochfrequente Read-Ops
MetadataWer, Was, Wann, Woher, StatusStandard fuer die meisten Ressourcen
RequestMetadata + Request-BodySchreibende Operationen auf kritische Ressourcen
RequestResponseMetadata + Request + ResponseForensik-Level, nur fuer hochsensible Ressourcen

Wichtig: Die Rules werden von oben nach unten ausgewertet. Die erste passende Rule gewinnt. Ordnen Sie spezifische Rules vor allgemeinen.

Praxistaugliche Audit Policy

Diese Policy ist ein guter Startpunkt. Sie filtert Rauschen, erfasst sicherheitskritische Events detailliert und haelt das Log-Volumen in einem handhabbaren Rahmen.

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  # Health Checks und Discovery ignorieren (extrem hochfrequent)
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
      - group: ""
        resources: ["endpoints", "services", "services/status"]

  - level: None
    userGroups: ["system:nodes"]
    verbs: ["get"]
    resources:
      - group: ""
        resources: ["nodes", "nodes/status"]

  - level: None
    nonResourceURLs:
      - "/healthz*"
      - "/livez*"
      - "/readyz*"
      - "/version"

  # Secrets: Request-Level, um Zugriffsmuster zu erkennen
  # NICHT RequestResponse -- sonst landen Secret-Werte im Log
  - level: Request
    resources:
      - group: ""
        resources: ["secrets"]
    verbs: ["create", "update", "patch", "delete"]

  - level: Metadata
    resources:
      - group: ""
        resources: ["secrets"]
    verbs: ["get", "list", "watch"]

  # RBAC-Aenderungen immer detailliert protokollieren
  - level: Request
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]

  # Workload-Aenderungen (Deployments, StatefulSets, DaemonSets)
  - level: Request
    resources:
      - group: "apps"
        resources: ["deployments", "statefulsets", "daemonsets"]
    verbs: ["create", "update", "patch", "delete"]

  - level: Metadata
    resources:
      - group: "apps"
        resources: ["deployments", "statefulsets", "daemonsets"]
    verbs: ["get", "list", "watch"]

  # Namespace-Aenderungen
  - level: Request
    resources:
      - group: ""
        resources: ["namespaces"]
    verbs: ["create", "delete"]

  # Network Policies -- sicherheitskritisch
  - level: Request
    resources:
      - group: "networking.k8s.io"
        resources: ["networkpolicies"]

  # ServiceAccounts und Tokens
  - level: Request
    resources:
      - group: ""
        resources: ["serviceaccounts", "serviceaccounts/token"]
    verbs: ["create", "update", "patch", "delete"]

  # Default: Metadata fuer alles andere
  - level: Metadata
    omitStages:
      - "RequestReceived"

Beachten Sie: Secrets werden auf Request-Level nur bei Schreibzugriffen protokolliert, nicht auf RequestResponse. Sonst landen die Secret-Werte im Audit Log -- das waere kontraproduktiv.

API Server Konfiguration

Die Audit Policy muss dem kube-apiserver als Datei uebergeben werden. Bei Self-Managed-Clustern (kubeadm) sieht das so aus:

# Audit Policy auf den Control-Plane-Node kopieren
sudo mkdir -p /etc/kubernetes/audit
sudo cp audit-policy.yaml /etc/kubernetes/audit/policy.yaml

# Audit Log-Verzeichnis erstellen
sudo mkdir -p /var/log/kubernetes/audit

In der kube-apiserver-Konfiguration (Static Pod Manifest unter /etc/kubernetes/manifests/kube-apiserver.yaml) muessen folgende Flags gesetzt werden:

spec:
  containers:
    - command:
        - kube-apiserver
        # ... bestehende Flags ...
        ---audit-policy-file=/etc/kubernetes/audit/policy.yaml
        ---audit-log-path=/var/log/kubernetes/audit/audit.log
        ---audit-log-maxage=30
        ---audit-log-maxbackup=10
        ---audit-log-maxsize=200
      volumeMounts:
        - mountPath: /etc/kubernetes/audit
          name: audit-policy
          readOnly: true
        - mountPath: /var/log/kubernetes/audit
          name: audit-log
  volumes:
    - hostPath:
        path: /etc/kubernetes/audit
        type: DirectoryOrCreate
      name: audit-policy
    - hostPath:
        path: /var/log/kubernetes/audit
        type: DirectoryOrCreate
      name: audit-log

Bei Managed Kubernetes (EKS, AKS, GKE) ist Audit Logging ueber die jeweilige Cloud-Console aktivierbar -- die Policy-Konfiguration ist dort allerdings eingeschraenkt.

Logs weiterleiten: Fluent Bit nach Loki

Audit Logs auf dem Node liegen zu lassen ist keine Loesung. Sie brauchen ein zentrales System fuer Suche, Alerting und Langzeitarchivierung. Fluent Bit als DaemonSet ist leichtgewichtiger als Fluentd und reicht fuer die meisten Setups.

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-audit
  namespace: logging
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush        5
        Log_Level    info
        Parsers_File parsers.conf

    [INPUT]
        Name         tail
        Path         /var/log/kubernetes/audit/audit.log
        Parser       json
        Tag          kube.audit
        Refresh_Interval 10
        Mem_Buf_Limit    50MB

    [FILTER]
        Name         modify
        Match        kube.audit
        Add          cluster production-eu

    [OUTPUT]
        Name         loki
        Match        kube.audit
        Host         loki.logging.svc.cluster.local
        Port         3100
        Labels       job=kube-audit, cluster=production-eu
        Line_Format  json

Fuer Elasticsearch ersetzen Sie den OUTPUT-Block:

    [OUTPUT]
        Name         es
        Match        kube.audit
        Host         elasticsearch.logging.svc.cluster.local
        Port         9200
        Index        kube-audit
        Type         _doc
        Suppress_Type_Name On

Alerting auf Audit Events

Audit Logs sind wertlos, wenn niemand sie liest. Definieren Sie Alerting-Rules fuer sicherheitskritische Muster:

Event-MusterBedeutungAlert-Prioritaet
Secret get durch unbekannten ServiceAccountMoeglicher Token-MissbrauchCritical
ClusterRoleBinding mit cluster-admin erstelltPrivilege EscalationCritical
Viele 403 Forbidden von einer Source-IPBrute-Force oder FehlkonfigurationWarning
Deployment in kube-system geaendertUnerwartete System-AenderungHigh
Namespace geloeschtDaten- und Service-VerlustCritical
NetworkPolicy geloeschtNetzwerk-Isolation aufgehobenHigh

In Grafana/Loki koennen Sie diese als LogQL-Queries abbilden und an Alertmanager oder PagerDuty weiterleiten.

Aufbewahrungsfristen und Storage-Planung

Audit Logs koennen erheblich Speicherplatz beanspruchen. Ein Cluster mit 50 Nodes und aktiver Nutzung erzeugt leicht 5-20 GB pro Tag an Audit-Log-Daten (abhaengig von der Policy).

Fuer die Aufbewahrung gelten je nach Kontext unterschiedliche Anforderungen:

AnforderungFristQuelle
DSGVO RechenschaftspflichtDauer der Verarbeitung + NachweisfristArt. 5 Abs. 2 DSGVO
GoBD (buchfuehrungsrelevant)10 JahreGoBD
BSI-Grundschutz (empfohlen)6-12 Monate online, danach ArchivBSI IT-Grundschutz
Internes Security-Team (typisch)90 Tage hot, 1 Jahr warm, 3 Jahre coldBest Practice

Planen Sie ein Tiered-Storage-Konzept: Hot Storage (Elasticsearch/Loki, 30-90 Tage) fuer aktive Suche, Cold Storage (S3-kompatibler Object Store) fuer Langzeitarchivierung.

Haeufige Fehler bei Audit Logging

Alles auf RequestResponse setzen. Das erzeugt enorme Datenmengen und verlangsamt den API Server. Nutzen Sie dieses Level nur fuer wirklich kritische, seltene Operationen.

Secrets im Audit Log. Wenn Sie RequestResponse auf Secrets setzen, landen die dekodierten Werte im Log. Das ist ein Datenschutzproblem und widerspricht dem Zweck von Secrets.

Keine Log-Rotation. Ohne --audit-log-maxsize und --audit-log-maxbackup fuellen sich die Disks der Control-Plane-Nodes. Resultat: etcd wird instabil, der Cluster faellt aus.

Policy nie aktualisiert. Neue CRDs und Operatoren erzeugen neue API-Endpunkte, die von der alten Policy nicht erfasst werden. Reviewen Sie die Policy bei jedem groesseren Cluster-Change.

Audit Logging bei Managed Kubernetes

Bei Managed Services ist die Konfiguration einfacher, aber auch eingeschraenkter:

AnbieterAktivierungCustom PolicyLog-Ziel
EKSControl Plane Logging aktivierenNein (feste Policy)CloudWatch Logs
AKSDiagnostic SettingsTeilweise (Kategorien)Azure Monitor / Log Analytics
GKEAdmin Activity Logs (default an)NeinCloud Logging

Der Nachteil: Sie haben weniger Kontrolle ueber die Policy. Umso wichtiger ist es, die Logs in ein eigenes System zu exportieren (z.B. ueber CloudWatch Log Subscriptions nach Elasticsearch), damit Sie eigene Queries und Alerts definieren koennen.

Zusammenspiel mit anderen Security-Massnahmen

Audit Logging ist ein Baustein, nicht die gesamte Security-Strategie. Es ergaenzt sich mit:

  • RBAC -- Audit Logs zeigen, ob RBAC-Regeln greifen oder umgangen werden
  • Network Policies -- Audit Logs erfassen Aenderungen an Network Policies
  • Runtime Security (Falco) -- erfasst, was innerhalb der Container passiert (Audit Logs sehen nur API-Server-Interaktionen)
  • Secrets Management -- External Secrets Operator reduziert die Notwendigkeit, Secrets ueber die K8s API zu verwalten
  • Security Scanning -- praventive Massnahme vor dem Deployment

Fazit

Audit Logging ist keine optionale Nice-to-have-Funktion. Es ist die Grundlage fuer jede ernsthafte Security- und Compliance-Strategie in Kubernetes. Starten Sie mit einer fokussierten Policy, die Rauschen filtert und kritische Events erfasst. Leiten Sie die Logs an ein zentrales System weiter. Definieren Sie Alerts fuer die Events, die sofortige Aufmerksamkeit erfordern.

Der Aufwand fuer die initiale Einrichtung liegt bei 2-5 Tagen, abhaengig von der bestehenden Infrastruktur. Danach ist es vor allem Pflege: Policy-Reviews bei Cluster-Changes, Storage-Monitoring und gelegentliches Tuning der Alert-Schwellwerte.

Wenn Sie Unterstuetzung bei der Einrichtung von Audit Logging oder einem umfassenden Security-Review Ihres Clusters benoetigen, melden Sie sich unter /kontakt.

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