Kubernetes-Hardening und Container-Sicherheit: die Praxis-Checkliste
Die meisten Kubernetes-Vorfälle sind keine Zero-Days, sondern Standardeinstellungen, die nie jemand geändert hat. Das ist die Hardening-Checkliste, die wir auf Kundenclustern tatsächlich abarbeiten.
Von Innovation T Team
Die meisten Kubernetes-Kompromittierungen beginnen nicht mit einem Zero-Day. Sie beginnen mit einem Container, der als Root läuft, einem Service Account mit cluster-admin oder einem Dashboard, das jemand 2023 ins Internet gestellt und dann vergessen hat. Hardening ist kein Produkt, das Sie einkaufen, und schon gar kein Tool mit hübschem Dashboard. Es ist eine Reihe von Standardeinstellungen, die Sie schlicht nicht akzeptieren. Was folgt, ist die Checkliste, die wir abarbeiten, wenn wir einen Cluster übernehmen.
Das Bedrohungsmodell in einem Absatz
Ein Angreifer, der in einem Container landet, will drei Dinge: Rechte innerhalb des Containers ausweiten, auf den Node ausbrechen oder sich lateral durch das Clusternetz und die Kubernetes-API bewegen. Jede Maßnahme in diesem Artikel existiert, um einen dieser drei Pfade zu unterbrechen. Wenn Sie bei einer Maßnahme nicht sagen können, welchen Pfad sie blockiert, brauchen Sie sie vermutlich noch nicht. Diese Sichtweise hält die Härtungsarbeit ehrlich und verhindert, dass Teams in CIS-Benchmark-Positionen oder BSI-Grundschutz-Bausteinen ertrinken, die am realen Risiko nichts ändern. Compliance-Papier schützt keinen Cluster, durchgesetzte Defaults schon.
Beim Image anfangen, nicht beim Cluster
Die günstigsten Schwachstellen sind die, die Sie gar nicht erst ausliefern. Image-Hygiene ist der Punkt, an dem sich Hardening zuerst auszahlt.
Die Angriffsfläche verkleinern
Ein Standard-Image wie node:20 bringt Hunderte Betriebssystempakete mit, eine Shell, einen Paketmanager und am Tag des Scans typischerweise Hunderte bekannter CVEs. Jedes Binary im Image ist nach einer Kompromittierung ein Werkzeug für den Angreifer. Ihre Optionen, grob nach Aufwand sortiert:
- Slim-Varianten (
-slim,-alpine): schnelle Gewinne, aber die musl libc von Alpine bricht native Abhängigkeiten und DNS-Verhalten gelegentlich auf subtile Weise. Erst testen, dann festlegen. - Distroless (Googles
gcr.io/distroless-Images): keine Shell, kein Paketmanager. Debugging läuft über Ephemeral Containers (kubectl debug), und diesen Workflow-Wechsel muss Ihr Team vor einem Vorfall geübt haben, nicht währenddessen. - Images auf Chainguard- oder Wolfi-Basis: täglich neu gebaut, typischerweise nahe null bekannte CVEs, SBOMs inklusive. Der Preis ist die Abhängigkeit vom Build-Rhythmus eines Anbieters und bei manchen Images Lizenzkosten. Rechnen Sie nüchtern nach, ob sich das für Ihr Portfolio lohnt.
Multi-Stage bauen, ohne Root betreiben
Die Build-Toolchain hat im Runtime-Image nichts verloren. Compiler, npm, git und curl sind exakt das, was eine Reverse Shell braucht.
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/api
FROM gcr.io/distroless/static:nonroot
COPY --from=build /app /app
USER 65532:65532
ENTRYPOINT ["/app"]
Das finale Image enthält ein Binary, keine Shell und einen Nicht-Root-Benutzer. Ein Angreifer, der den Anwendungsprozess kompromittiert, landet in einem Raum ohne Werkzeuge.
Scannen, signieren, pinnen
Scannen ohne Policy ist Sicherheitstheater. Verdrahten Sie es mit einem echten Gate in die Pipeline:
- Trivy oder Grype in der CI, mit Build-Abbruch bei behebbaren Critical- und High-CVEs. Dokumentierte, zeitlich befristete Ausnahmen sind erlaubt, stille Ignores nicht.
- Cosign zum Signieren der Images beim Build, kombiniert mit einer Admission Policy im Cluster, die unsignierte Images ablehnt. Das schließt die Lücke "jemand hat ein Image vom Laptop gepusht".
- Digest-Pinning für Basis-Images (
FROM node@sha256:...), damit Builds reproduzierbar sind und ein vergifteter Tag nicht durchrutschen kann. - SBOM-Erzeugung mit Syft, als Artefakt abgelegt. Beim nächsten Ereignis vom Kaliber Log4j beantworten Sie die Frage "sind wir betroffen" in Minuten statt Tagen. Das ist nebenbei genau die Auskunftsfähigkeit, die Prüfer und Kunden im DACH-Raum zunehmend vertraglich einfordern.
Das ist ebenso ein Pipeline-Thema wie ein Sicherheitsthema. Die CI-Seite haben wir ausführlich in unserem Leitfaden zum Aufbau einer DevSecOps-Pipeline behandelt.
Die Pod-Spezifikation absichern
Kubernetes-Defaults sind auf "es läuft" optimiert, nicht auf "es ist sicher". Der securityContext des Pods ist der Ort, an dem Sie das korrigieren, und er kostet zur Laufzeit praktisch nichts.
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
Was jede Zeile Ihnen konkret bringt:
runAsNonRootplus feste UID: Ausbruchstechniken, die Root im Container voraussetzen, laufen größtenteils ins Leere.allowPrivilegeEscalation: false: verhindert, dass setuid-Binaries Rechte ausweiten, und eliminiert damit eine ganze Klasse lokaler Privilege-Escalation.readOnlyRootFilesystem: true: Schadsoftware kann keine Payloads auf die Platte schreiben. Für Anwendungen, die Scratch-Speicher brauchen, mounten Sie einemptyDirunter/tmp.seccompProfile: RuntimeDefault: filtert rund 60 der exotischeren Syscalls. Nahezu jeder Kernel-basierte Container-Ausbruch der letzten Jahre benötigte einen Syscall, den dieses Profil blockiert.- Capabilities mit
drop: ["ALL"]: fügen Sie nur zurück, was Sie begründen können, und werden Sie misstrauisch bei allem, wasNET_ADMINoderSYS_ADMINverlangt. Ein Pod mitSYS_ADMINoderprivileged: trueist in der Praxis Root auf dem Node.
Erzwingen Sie all das über Pod Security Admission auf Namespace-Ebene. Versehen Sie jeden Anwendungs-Namespace mit dem Label pod-security.kubernetes.io/enforce: restricted und behandeln Sie Ausnahmen als Tickets mit Verantwortlichen und Ablaufdatum. Nach unserer Erfahrung fördert die Migration eine Handvoll Altlasten zutage, die tatsächlich Privilegien brauchen (CNI-Agenten, Log-Kollektoren, Storage-Treiber). Isolieren Sie diese in dedizierten Namespaces, statt die Policy überall aufzuweichen.
Den Schadensradius begrenzen
Gehen Sie davon aus, dass irgendwann ein Pod kompromittiert wird. Die entscheidende Frage ist, was der Angreifer danach erreichen kann.
RBAC: Least Privilege, ohne Diskussion
Der häufigste Befund in unseren Cluster-Reviews: Service Accounts mit Berechtigungen, die niemand mehr erklären kann. Die Regeln sind simpel und unspektakulär:
- Binden Sie niemals
cluster-adminan einen Workload. Niemals. CI-Deployer eingeschlossen. - Ein Service Account pro Workload, beschränkt auf seinen Namespace, mit den Verben, die er tatsächlich nutzt.
- Setzen Sie
automountServiceAccountToken: falseals Standard. Die meisten Anwendungs-Pods rufen die Kubernetes-API nie auf, und trotzdem liegt in jedem von ihnen ein gültiges API-Credential an einem allgemein bekannten Pfad. Dieses Token ist das Erste, was ein Angreifer ausliest. - Auditieren Sie regelmäßig mit
kubectl auth can-i --list --as=system:serviceaccount:ns:nameoder Werkzeugen wierbac-tool. Wildcards in Verben oder Ressourcen sind Befunde, keine Bequemlichkeit.
Network Policies: erst alles verbieten, dann gezielt erlauben
Ab Werk kann jeder Pod mit jedem anderen Pod über alle Namespaces hinweg kommunizieren. Dieses flache Netz ist der Grund, warum aus einem kompromittierten Frontend ein Datenbank-Vorfall wird. Beginnen Sie jeden Namespace mit einem Default Deny:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
Erlauben Sie danach gezielte Flüsse: Frontend zur API auf 8080, API zu Postgres auf 5432, alles zu DNS. Egress-Policies sind mindestens so wichtig wie Ingress, denn sie machen aus "Angreifer im Pod" einen "Angreifer im Pod, der weder seinen C2-Server noch den Cloud-Metadata-Endpunkt erreicht". Das Blockieren von 169.254.169.254 für alle Workloads, die ihn nicht nachweislich brauchen, hat reale Pfade zum Diebstahl von Cloud-Credentials gestoppt. Das ist Zero Trust auf Pod-Ebene, und die Argumentation deckt sich mit dem, was wir in Zero-Trust-Architektur erklärt dargelegt haben.
Der Haken: Network Policies sind unbarmherzig im Debugging, wenn ein Deployment scheitert, weil jemand die DNS-Egress-Regel vergessen hat. Liefern Sie eine getestete Policy-Bibliothek mit Ihren Plattform-Templates aus, statt jedes Team seine eigene schreiben zu lassen.
Secrets: Base64 ist keine Verschlüsselung
Kubernetes Secrets sind base64-kodiert, nicht verschlüsselt, und jeder mit Lesezugriff auf Secrets in einem Namespace hat den Klartext. Wenn dort Zugangsdaten zu Systemen mit personenbezogenen Daten liegen, ist das nicht nur ein technisches Problem, sondern schnell auch eines nach Art. 32 DSGVO, Stichwort Stand der Technik. Die Mindestanforderungen:
- Aktivieren Sie Encryption at Rest für etcd mit einem KMS-Provider (bei Managed-Clustern: verifizieren, nicht annehmen).
- Bevorzugen Sie gemountete Secret-Volumes gegenüber Umgebungsvariablen. Env-Variablen landen in Crash Dumps, in
kubectl describeund in Kindprozessen. - Für alles Ernsthafte: Bezug aus einem externen Secret-Manager (Vault, AWS Secrets Manager, GCP Secret Manager) via External Secrets Operator oder CSI-Treiber, damit eine Rotation nicht das Redeployment der halben Plattform erfordert.
- Härten Sie RBAC auf der Secret-Ressource selbst. Clusterweites
get secretsist Domain-Admin in Verkleidung.
Control Plane und Nodes härten
Bei Managed Kubernetes (EKS, GKE, AKS) betreibt der Anbieter etcd und die API-Server-Binaries, aber die Konfiguration, auf die es ankommt, bleibt Ihre Verantwortung. Eine Region in Frankfurt oder Zürich löst die Frage der Datenresidenz, ersetzt aber keine einzige der folgenden Maßnahmen:
- Privater API-Endpunkt, mindestens aber strikte CIDR-Allowlists. Öffentlich erreichbare API-Server werden binnen Minuten nach der Erstellung gescannt.
- Audit-Logging aktiviert und ausgeleitet an einen durchsuchbaren Ort. Ohne Audit-Logs rekonstruieren Sie Angreiferaktionen nach einem Vorfall aus dem Gedächtnis. Für die 72-Stunden-Meldung an die Aufsichtsbehörde nach DSGVO und die Berichtspflichten unter NIS2 ist das keine tragfähige Grundlage.
- Node-Betriebssystem: minimale, containeroptimierte Images verwenden (Bottlerocket, COS, Flatcar), Node-Pools in einem automatisierten Upgrade-Takt halten und SSH auf Nodes niemals zur Routine werden lassen.
- Versionsstand: Kubernetes-Minor-Versionen fallen nach etwa einem Jahr aus dem Support. Cluster, die mehr als zwei Minors zurückliegen, sammeln ungepatchte CVEs und eine beängstigende Upgrade-Klippe an. Lieber klein und häufig aktualisieren.
Zur Laufzeit detektieren, denn Prävention versagt irgendwann
Alles bisher Genannte senkt die Wahrscheinlichkeit. Runtime-Detection kümmert sich um das Restrisiko. Werkzeuge wie Falco oder Tetragon beobachten Syscalls per eBPF und melden Verhalten, das in einem gehärteten Workload schlicht nicht vorkommen darf: eine Shell, die in einem Distroless-Container startet, eine unerwartete ausgehende Verbindung, ein Prozess, der das Service-Account-Token liest, Schreibzugriffe auf /etc/passwd.
Die Signalqualität ist hier ungewöhnlich gut, gerade weil das Hardening das Rauschen entfernt hat. Wenn Ihr Image keine Shell enthält, ist "Shell ausgeführt" kein Anomalie-Score, sondern ein Vorfall. Leiten Sie diese Alarme in einen Reaktionsprozess mit Verantwortlichen und Runbooks. Wenn dieser Muskel bei Ihnen noch nicht existiert, beginnen Sie mit unserem Incident-Response-Playbook.
Fehlerbilder, die uns immer wieder begegnen
- Hardening wird auf neue Services angewendet, während der Legacy-Namespace
privileged: truebehält, "vorübergehend", seit zwei Jahren. - Ein Scanner in der CI mit Failure-Threshold auf null, der Berichte erzeugt, die niemand liest.
- Network Policies werden ohne DNS-Egress-Regel ausgerollt, legen die Produktion lahm und werden dann komplett zurückgerollt statt korrigiert.
- Admission Policies verharren dauerhaft im Audit-Modus, weil niemand die Umstellung auf Enforcement terminiert hat.
- Secrets wurden "nach Vault migriert", aber die alten Kubernetes Secrets nie gelöscht: weiterhin lesbar, weiterhin gültig.
Das Muster hinter allen fünf Punkten: Hardening wird als Projekt mit Enddatum behandelt statt als Satz durchgesetzter Defaults. Policy-Engines (Kyverno oder native ValidatingAdmissionPolicy mit CEL) existieren genau dafür, den sicheren Weg zum einzigen Weg zu machen.
Die Praxis-Checkliste
Arbeiten Sie die Liste von oben nach unten ab. Jeder Punkt ist ein Ja oder Nein, und "größtenteils" zählt als Nein.
- Alle Runtime-Images sind minimal (Distroless, Chainguard oder Slim) und werden Multi-Stage gebaut.
- Die CI bricht Builds bei behebbaren Critical- und High-CVEs ab, Ausnahmen nur zeitlich befristet.
- Images sind mit Cosign signiert und der Cluster lehnt unsignierte Images ab.
- Basis-Images sind per Digest gepinnt und pro Build wird eine SBOM erzeugt.
- Jeder Workload läuft ohne Root, mit
allowPrivilegeEscalation: false, entfernten Capabilities,RuntimeDefault-seccomp und Read-only-Root-Dateisystem. - Pod Security Admission erzwingt
restrictedin allen Anwendungs-Namespaces. - Kein Workload-Service-Account besitzt cluster-admin; Token-Automount ist standardmäßig deaktiviert.
- Jeder Namespace hat Default-Deny-Network-Policies für Ingress und Egress, inklusive Blockade des Metadata-Endpunkts.
- etcd-Verschlüsselung at Rest nutzt ein KMS; Secrets liegen in einem externen Manager mit Rotation.
- Der API-Server ist privat oder CIDR-beschränkt, und Audit-Logs landen in durchsuchbarem Speicher.
- Nodes laufen auf einem containeroptimierten OS mit automatisiertem Patching, und der Cluster liegt höchstens zwei Minor-Versionen zurück.
- Runtime-Detection (Falco oder Tetragon) ist im Einsatz, mit Alarmen, die in einen verantworteten Reaktionsprozess laufen.
- Admission Policies erzwingen all das, damit Abweichungen nicht stillschweigend entstehen können.
Ab zwölf Punkten liegen Sie vor der großen Mehrheit der Cluster, die wir prüfen. Unter acht Punkten sollten Sie das Thema als Priorität für dieses Quartal behandeln, denn Angreifer automatisieren die Suche nach genau diesen Lücken.
Wie Innovation T unterstützen kann
Innovation T konzipiert, baut und härtet containerisierte Plattformen für Unternehmen in Europa, den Golfstaaten und Nordafrika. Wir führen Cluster-Security-Assessments exakt entlang dieser Checkliste durch und erledigen anschließend die unglamouröse Arbeit: Workloads auf Restricted Pod Security migrieren, die Policy-Bibliothek schreiben, Image-Signierung in die CI verdrahten, und Ihrem Team durchgesetzte Defaults hinterlassen statt eines PDF-Berichts.
Wenn Ihr Cluster schneller gewachsen ist als seine Leitplanken, werfen Sie einen Blick auf unsere Cloud- und Security-Leistungen oder sprechen Sie mit unseren Engineers. Wir sagen Ihnen ehrlich, welche dieser dreizehn Punkte für Ihre Umgebung wirklich zählen und welche warten können.
Bereit, mit Innovation T zu bauen?
Ob Sicherheit, Wachstum oder Engineering, unser Team hilft Ihnen, es gut umzusetzen.