Zurück zum Blog
29. April 2026

So beheben Sie häufige Fehlkonfigurationen in Kubernetes-Clustern

Sie haben wahrscheinlich den Witz gehört, dass Kubernetes im Wesentlichen ein riesiger Haufen YAML-Dateien ist, die durch Hoffnung und ein paar sehr gestresste SREs zusammengehalten werden. Auch wenn das etwas übertrieben ist, trifft es einen Kern der Wahrheit: Kubernetes ist unglaublich komplex. Es ist ein mächtiger Orchestrator, aber diese Macht geht mit einer steilen Lernkurve einher. Wenn Sie schnell vorankommen – mehrmals täglich Updates bereitstellen, Pods über Regionen hinweg skalieren und Service Meshes verwalten – ist es fast unvermeidlich, dass etwas falsch konfiguriert wird.

Das Problem ist, dass in einer Cloud-nativen Umgebung ein kleiner Tippfehler in einem Manifest oder eine „temporäre“ Berechtigungsanpassung ein riesiges Loch in Ihrer Sicherheit reißen kann. Wir alle kennen das. Sie wollten nur, dass der Pod startet, also haben Sie ihm cluster-admin-Berechtigungen „nur für eine Sekunde“ gegeben, um ein Verbindungsproblem zu debuggen. Dann haben Sie es vergessen. Sechs Monate später läuft dieser Pod immer noch und ist nun eine goldene Eintrittskarte für jeden Angreifer, der es schafft, eine Shell in Ihrem Container zu erhalten.

Häufige Fehlkonfigurationen in Kubernetes-Clustern zu beheben, bedeutet nicht nur, einen Sicherheitsscanner laufen zu lassen und Kästchen abzuhaken. Es geht darum, das „Warum“ hinter den Risiken zu verstehen. Wenn Sie nicht verstehen, wie ein privilegierter Container zu einem vollständigen Node-Breakout führen kann, werden Sie jedes Mal, wenn Sie eine neue Deployment-Datei schreiben, die gleichen Fehler machen.

In diesem Leitfaden werden wir die häufigsten Fehler, die wir in der Praxis sehen, und, was noch wichtiger ist, genau deren Behebung durchgehen. Wir werden alles von Role-Based Access Control (RBAC)-Albträumen bis hin zu den Gefahren des Standard-Namespaces betrachten. Am Ende sollten Sie einen klaren Fahrplan zur Härtung Ihres Clusters haben, ohne Ihre Anwendungen zu beeinträchtigen.

Die Gefahr überprivilegierter Service Accounts (RBAC)

Role-Based Access Control (RBAC) ist das Herzstück der Kubernetes-Sicherheit. Es legt fest, wer was wo tun darf. Allerdings ist RBAC der Punkt, an dem die meisten Leute anfangen, Abkürzungen zu nehmen. Wenn ein Entwickler sagt: „Ich kann meine CI/CD-Pipeline nicht dazu bringen, die App bereitzustellen“, besteht die einfachste Lösung oft darin, dem Service Account cluster-admin-Berechtigungen zu erteilen.

Es funktioniert. Die Pipeline wird grün. Alle sind glücklich. Aber Sie haben gerade eine massive Schwachstelle geschaffen. Wenn Ihr CI/CD-Secret geleakt wird, hat der Angreifer nicht nur Zugriff auf eine App; er hat die Schlüssel zu Ihrem gesamten Königreich.

Die „Cluster-Admin“-Falle

Die cluster-admin-Rolle ist eine integrierte ClusterRole, die uneingeschränkten Zugriff auf jede Ressource im Cluster gewährt. Dies für Service Accounts auf Anwendungsebene zu verwenden, ist eine Todsünde der K8s-Sicherheit.

Die Lösung: Das Prinzip der geringsten Rechte (PoLP) Anstatt breite Rollen zu verwenden, müssen Sie spezifische Rollen definieren, die nur die exakt benötigten Aktionen erlauben.

Wenn ein Pod beispielsweise nur ConfigMaps in seinem eigenen Namespace lesen muss, um zu starten, geben Sie ihm keine ClusterRole. Geben Sie ihm eine Role (die Namespaced ist) mit nur den Verben get und list für configmaps.

Beispiel einer eingeschränkten Rolle:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: app-namespace
  name: config-reader
rules:
- apiGroups: [""] 
  resources: ["configmaps"]
  verbs: ["get", "list"]

Vermeidung des Standard-Service-Accounts

Standardmäßig hat jeder Namespace einen Service Account namens default. Wenn Sie keinen Service Account für einen Pod angeben, weist Kubernetes ihm diesen zu. Historisch gesehen hatte der Standard-Service-Account weitreichende Berechtigungen. Während moderne Versionen besser sind, haben viele ältere Cluster immer noch den default-Account an übermäßig permissive Rollen gebunden.

Die Lösung: Explizite Service-Konten Verlassen Sie sich niemals auf die Standardeinstellungen. Erstellen Sie für jede einzelne Anwendung ein dediziertes Service-Konto.

  1. Erstellen Sie das ServiceAccount.
  2. Erstellen Sie eine Role mit den minimal notwendigen Berechtigungen.
  3. Erstellen Sie ein RoleBinding, um die beiden zu verknüpfen.
  4. Setzen Sie serviceAccountName explizit in Ihrer Pod-Spezifikation.

Wenn Ihre Anwendung überhaupt nicht mit der Kubernetes API kommunizieren muss (was für die meisten Webanwendungen zutrifft), gehen Sie noch einen Schritt weiter. Setzen Sie automountServiceAccountToken: false in Ihrer Pod-Spezifikation. Dies verhindert, dass das API-Token in den Pod gemountet wird, was bedeutet, dass selbst wenn ein Angreifer eindringt, er kein Token für die laterale Bewegung innerhalb des Clusters verwenden kann.

Härtung des Pod Security Context

Wenn ein Container läuft, läuft er nicht nur „im“ Cluster; er läuft als Prozess auf einem Linux-Knoten. Wenn dieser Prozess als der root-Benutzer läuft und eine Schwachstelle in der Container-Laufzeitumgebung oder im Kernel besteht, kann der Angreifer potenziell aus dem Container „ausbrechen“ und Root-Zugriff auf die Host-Maschine erlangen. Dies wird als Container-Breakout bezeichnet.

Das Problem „Privileged: True“

Sie werden oft privileged: true in YAML-Dateien sehen. Dies weist Kubernetes im Wesentlichen an, dem Container fast alle Capabilities der Host-Maschine zu geben. Dies ist für Standardanwendungen selten notwendig. Es wird normalerweise nur für spezialisierte Systemwerkzeuge (wie CNI-Plugins oder Speichertreiber) benötigt.

Die Lösung: Beenden Sie die Verwendung des privilegierten Modus Wenn Sie feststellen, dass Sie privileged: true benötigen, fragen Sie sich warum. Müssen Sie nur eine Netzwerkeinstellung ändern? Müssen Sie ein bestimmtes Gerät mounten?

Anstelle des vollständigen privilegierten Modus verwenden Sie capabilities. Linux-Capabilities ermöglichen es Ihnen, die „Root“-Berechtigungen in kleinere Teile zu zerlegen. Wenn Sie beispielsweise nur Netzwerkschnittstellen ändern müssen, verwenden Sie CAP_NET_ADMIN, anstatt dem Pod vollen Root-Zugriff zu gewähren.

Als Root ausführen

Viele Docker-Images sind standardmäßig so gebaut, dass sie als Root laufen. Wenn Sie diese unverändert bereitstellen, läuft Ihr Prozess mit UID 0. Dies ist ein enormes Risiko.

Die Lösung: Verwenden Sie einen Nicht-Root-Benutzer Sie sollten die Ausführung als Nicht-Root sowohl im Dockerfile als auch im Kubernetes securityContext erzwingen.

Fügen Sie in Ihrer Deployment-YAML-Datei einen securityContext-Abschnitt hinzu:

spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000

runAsNonRoot: true weist Kubernetes an zu prüfen, ob das Image versucht, als Root zu laufen, und den Start fehlschlagen zu lassen, falls dies der Fall ist. Dies zwingt Ihr Team, Images mit einem dedizierten Benutzer zu erstellen (z. B. USER 1000 im Dockerfile).

Nur-Lese-Root-Dateisysteme

Die meisten Anwendungen müssen tatsächlich nicht in ihr eigenes Root-Dateisystem schreiben. Sie schreiben in Logs (die an stdout/stderr gehen sollten) oder in gemountete Volumes. Wenn ein Angreifer Zugriff auf einen Container erhält, lädt er normalerweise zuerst ein Toolkit oder ein Skript auf die lokale Festplatte herunter. Wenn das Dateisystem nur lesbar ist, wird dieser Angriffsvektor blockiert.

Die Lösung: Setzen Sie readOnlyRootFilesystem auf true

securityContext:
  readOnlyRootFilesystem: true

Wenn Ihre Anwendung temporäre Dateien schreiben muss, schalten Sie das Nur-Lese-Dateisystem nicht aus. Mounten Sie stattdessen ein emptyDir-Volume auf den spezifischen Pfad, in den die Anwendung schreiben muss (z. B. /tmp).

Verwalten Ihrer Angriffsfläche: Netzwerkrichtlinien

Standardmäßig verfügt Kubernetes über ein "flaches" Netzwerk. Das bedeutet, dass jeder Pod in jedem Namespace mit jedem anderen Pod in jedem anderen Namespace kommunizieren kann. Obwohl dies für die Konnektivität hervorragend ist, ist es ein Albtraum für die Sicherheit. Wenn Ihr Frontend-Webserver kompromittiert wird, kann der Angreifer Ihr internes Netzwerk frei scannen und Ihre Datenbank, Ihren Cache und Ihre internen Admin-Tools finden.

Der Mangel an Segmentierung

Stellen Sie sich ein Haus vor, in dem es keine Türen zwischen den Räumen gibt – nur einen großen, offenen Bereich. Wenn ein Einbrecher durch das vordere Fenster gelangt, hat er sofortigen Zugang zum Schlafzimmer, zur Küche und zum Safe. Genau so funktioniert ein Standard-K8s-Cluster.

Die Lösung: Eine Default-Deny-Richtlinie implementieren Der sicherste Weg, den Netzwerkverkehr zu verwalten, besteht darin, zunächst alles zu blockieren und dann explizit nur das Notwendige zuzulassen. Dies ist der "Zero Trust"-Ansatz.

Erstellen Sie zunächst eine Richtlinie, die den gesamten Ingress- und Egress-Verkehr für den Namespace blockiert:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Sobald alles blockiert ist, erstellen Sie spezifische "Erlauben"-Regeln. Wenn beispielsweise Ihr frontend-Pod mit Ihrem backend-Pod auf Port 8080 kommunizieren muss, schreiben Sie eine Richtlinie, die den Verkehr vom Frontend-Label zum Backend-Label auf diesem Port explizit zulässt.

Kontrolle des Egress-Verkehrs

Die meisten Leute konzentrieren sich darauf, wer in ihren Cluster gelangen kann, vergessen aber, was herausgeht. Wenn ein Pod kompromittiert wird, wird der Angreifer versuchen, "nach Hause zu telefonieren" zu einem Command-and-Control (C2)-Server, um Anweisungen zu erhalten oder Daten zu exfiltrieren.

Die Lösung: Egress einschränken Sofern Ihr Pod nicht mit dem öffentlichen Internet kommunizieren muss (was für einen Backend-Dienst selten ist), blockieren Sie den gesamten Egress-Verkehr. Wenn er doch Internetzugang benötigt (z. B. um eine Drittanbieter-API wie Stripe oder Twilio aufzurufen), verwenden Sie ein Service Mesh wie Istio oder Linkerd, oder nutzen Sie ein Egress Gateway, um spezifische externe Domains auf eine Whitelist zu setzen.

Die "Point-in-Time"-Falle und kontinuierliches Testen

Eine der größten Fehlkonfigurationen ist keine Codezeile – es ist ein Prozess. Viele Unternehmen führen einmal im Quartal ein "Sicherheitsaudit" durch. Sie beauftragen eine Firma, die Firma findet zehn Fehlkonfigurationen, das Team behebt sie, und alle atmen auf.

Aber Kubernetes-Umgebungen sind dynamisch. Sie könnten morgen eine ConfigMap ändern, ein Helm-Chart aktualisieren oder einen neuen Sidecar-Container hinzufügen. Dieses "saubere" Audit vom letzten Monat ist nun irrelevant. Dies nennen wir "Point-in-Time"-Sicherheit, und in einer Cloud-nativen Welt ist sie gefährlich.

Hier wird eine Verlagerung hin zum Continuous Threat Exposure Management (CTEM) notwendig. Sie können nicht nur nach Schwachstellen suchen; Sie müssen simulieren, wie sich ein Angreifer tatsächlich durch Ihren Cluster bewegt.

Wenn Sie einen Pod mit einer übermäßig permissiven RBAC-Rolle und einer falsch konfigurierten Network Policy haben, könnte ein einfacher Schwachstellenscan diese als zwei separate "mittlere" Risiken kennzeichnen. In Wirklichkeit bilden sie jedoch zusammen einen "kritischen" Pfad: Ein Angreifer nutzt eine Web-Schwachstelle aus, verwendet die RBAC-Rolle, um Secrets aufzulisten, findet ein Datenbankpasswort und nutzt das offene Netzwerk, um Ihre Daten abzugreifen.

Tools wie Penetrify helfen, diese Lücke zu schließen. Anstatt eines statischen Berichts, der Staub ansetzt, bietet Penetrify bedarfsgerechte Sicherheitstests, die mit Ihrer Cloud-Umgebung skalieren. Es hilft Ihnen, diese „Ketten“ von Fehlkonfigurationen – die Art und Weise, wie ein kleiner RBAC-Fehler mit einer Netzwerklücke kombiniert wird – zu identifizieren, bevor ein böswilliger Akteur dies tut. Indem Sie sich einem „Penetration Testing as a Service“ (PTaaS)-Modell zuwenden, hören Sie auf zu raten, ob Ihr Cluster sicher ist, und fangen an, es zu wissen.

Den API-Server und die Control Plane absichern

Der API-Server ist das Gehirn Ihres Clusters. Alles – von kubectl-Befehlen bis zur internen Controller-Logik – läuft über ihn. Wenn der API-Server exponiert oder falsch konfiguriert ist, ist Ihr gesamter Cluster kompromittiert.

Öffentlich zugängliche API-Server

In der Eile, einen Cluster in Betrieb zu nehmen, lassen einige Teams den API-Server offen für das gesamte Internet. Obwohl er durch Authentifizierung geschützt ist, ermöglicht die Offenlegung des Endpunkts Angreifern, Brute-Force-Angriffe zu versuchen, Zero-Day-Schwachstellen im API-Server selbst auszunutzen oder Denial-of-Service-Angriffe durchzuführen.

Die Lösung: Private Endpunkte und autorisierte Netzwerke verwenden Wenn Sie einen verwalteten Dienst wie EKS, GKE oder AKS nutzen, aktivieren Sie die Option „Privater Cluster“. Dies stellt sicher, dass der API-Server nur innerhalb Ihrer VPC oder über einen VPN-/Bastion-Host zugänglich ist. Wenn Sie ihn öffentlich halten müssen, verwenden Sie „Authorized Networks“ (IP-Whitelisting), um den Zugriff auf Ihre Büro-IP oder Ihre CI/CD-Runner-IPs zu beschränken.

Anonyme Authentifizierung

Einige ältere Cluster oder benutzerdefinierte Installationen könnten die anonyme Authentifizierung aktiviert haben. Dies ermöglicht es, nicht authentifizierte Anfragen an den API-Server als speziellen system:anonymous-Benutzer zu behandeln. Abhängig von Ihren RBAC-Einstellungen könnte dieser Benutzer versehentlich Berechtigungen zum Anzeigen von Pods oder Nodes haben.

Die Lösung: Anonyme Authentifizierung deaktivieren Stellen Sie sicher, dass das Flag --anonymous-auth=false auf Ihrem kube-apiserver gesetzt ist. Wenn Sie es aus irgendeinem Grund nicht deaktivieren können, stellen Sie sicher, dass der system:anonymous-Benutzer nicht an Rollen gebunden ist, die Informationen über Ihren Cluster bereitstellen.

Etcd-Sicherheit

Etcd ist die Datenbank, in der Kubernetes seinen gesamten Zustand speichert. Wenn ein Angreifer Zugriff auf etcd erhält, hat er alles: jedes Secret, jede Konfiguration und die Möglichkeit, den Zustand des Clusters zu ändern, ohne den API-Server zu durchlaufen.

Die Lösung: etcd verschlüsseln und isolieren

  1. Verschlüsselung im Ruhezustand: Aktivieren Sie die Verschlüsselung für Secrets in etcd, damit die Secrets nutzlos sind, falls die Festplatte gestohlen oder darauf zugegriffen wird.
  2. Mutual TLS (mTLS): Stellen Sie sicher, dass der API-Server und etcd über Zertifikate kommunizieren. Niemand sollte ohne ein gültiges Client-Zertifikat mit etcd kommunizieren können.
  3. Netzwerkisolation: etcd sollte sich in einem vollständig separaten Netzwerk befinden oder durch strenge Firewall-Regeln geschützt sein, sodass nur der API-Server darauf zugreifen kann.

Secrets verwalten ohne das „Secret“

Der Name Secret in Kubernetes ist ein wenig irreführend. Standardmäßig sind Kubernetes-Secrets nur Base64-kodiert, nicht verschlüsselt. Jeder, der Zugriff auf die API oder das etcd-Backup hat, kann Ihr Datenbankpasswort in etwa zwei Sekunden mit einem einfachen Terminalbefehl dekodieren: echo "base64-string" | base64 --decode.

Secrets in Git speichern (Die ultimative Sünde)

Es passiert häufiger, als man zugibt. Ein Entwickler legt eine secret.yaml-Datei „nur für ein paar Minuten“ in ein Git-Repository, um einem Teamkollegen zu helfen, und vergisst dann, sie zu löschen. Nun lebt dieses Passwort für immer in der Git-Historie.

Die Lösung: Externe Secret-Verwaltung Hören Sie auf, native K8s-Secrets für sensible Daten zu verwenden. Verwenden Sie stattdessen einen dedizierten Secret Manager.

  • HashiCorp Vault: Der Industriestandard. Es bietet dynamische Geheimnisse und eine strenge Zugriffskontrolle.
  • AWS Secrets Manager / Azure Key Vault / GCP Secret Manager: Ideal, wenn Sie bereits an einen Cloud-Anbieter gebunden sind.

Um diese in Kubernetes zu integrieren, verwenden Sie Tools wie External Secrets Operator (ESO) oder Secrets Store CSI Driver. Diese Tools ziehen das Geheimnis aus dem externen Vault und injizieren es als Volume oder temporäres K8s-Geheimnis in den Pod, wodurch sichergestellt wird, dass die eigentliche „Quelle der Wahrheit“ niemals in Ihren YAML-Dateien oder Git liegt.

Geheimnisrotation

Die meisten Teams legen ein Passwort fest und belassen es drei Jahre lang. Wird dieses Passwort geleakt, verfügt der Angreifer über eine permanente Hintertür.

Die Lösung: Automatisierte Rotation Wenn Sie einen externen Manager wie Vault verwenden, können Sie eine automatische Rotation implementieren. Der Geheimnis-Manager aktualisiert das Passwort in der Datenbank und anschließend den Wert in Kubernetes. Da die Anwendung das Geheimnis aus einem Volume oder über eine API liest, übernimmt sie das neue Passwort, ohne dass ein vollständiger Redeploy erforderlich ist.

Ressourcenlimits und das „Noisy Neighbor“-Problem

Obwohl es sich nicht um eine „Sicherheits“-Fehlkonfiguration im traditionellen Sinne handelt, stellt das Versäumnis, Ressourcenlimits festzulegen, ein Stabilitäts- und Verfügbarkeitsrisiko dar. In Kubernetes kann ein Pod, der außer Kontrolle gerät und die gesamte CPU oder den gesamten RAM auf einem Knoten verbraucht, andere Pods – einschließlich kritischer Systemkomponenten – aushungern, was zu einem Knotenabsturz führt. Dies ist im Wesentlichen ein selbst zugefügter Denial of Service (DoS).

Die Gefahr „unbegrenzter“ Pods

Wenn Sie keine resources.limits definieren, kann ein Pod so viele Ressourcen des Knotens nutzen, wie er möchte. Wenn Sie ein Speicherleck in einer Ihrer Anwendungen haben, wird es langsam den gesamten RAM auf dem Knoten verbrauchen, bis der Linux OOM (Out of Memory) Killer beginnt, Prozesse zu beenden. Das Problem? Der OOM Killer könnte zuerst Ihren wichtigsten Pod beenden.

Die Lösung: Requests und Limits festlegen Jeder Container sollte einen request (was er zum Starten benötigt) und ein limit (das Maximum, das er verwenden darf) haben.

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"
  • Requests: Wird vom Scheduler verwendet, um einen Knoten mit ausreichend Platz zu finden.
  • Limits: Wird von der Container-Laufzeitumgebung durchgesetzt, um zu verhindern, dass der Pod den Knoten monopolisiert.

Umgang mit CPU-Drosselung

Seien Sie vorsichtig mit CPU-Limits. Im Gegensatz zum Arbeitsspeicher (wo das Erreichen eines Limits den Pod beendet) „drosselt“ das Erreichen eines CPU-Limits den Pod lediglich. Ihre Anwendung wird langsamer, stürzt aber nicht ab. Wenn Sie eine hohe Latenz in Ihren Anwendungen feststellen, überprüfen Sie Ihre Prometheus-Metriken auf CPU-Drosselung. Möglicherweise müssen Sie Ihre Limits erhöhen oder Ihren Code optimieren.

Image-Sicherheit und Lieferkettenrisiken

Ihr Cluster ist nur so sicher wie die Images, die Sie darin ausführen. Wenn Sie my-app:latest aus einem öffentlichen Registry ziehen, führen Sie im Wesentlichen Code aus, der von einem Fremden auf Ihrer Produktionsinfrastruktur geschrieben wurde.

Verwendung des :latest-Tags

Die Verwendung von :latest ist ein Rezept für eine Katastrophe. Sie haben keine Ahnung, welche Version des Codes tatsächlich ausgeführt wird. Wenn ein Pod neu startet, könnte er eine neue Version des Images ziehen, die eine Breaking Change oder, schlimmer noch, eine bösartige Nutzlast enthält.

Die Lösung: Unveränderliche Tags oder Digests verwenden Verwenden Sie immer ein spezifisches Versionstag (z.B. my-app:v1.2.3) oder, für maximale Sicherheit, den SHA256-Digest des Images. Dies stellt sicher, dass jedes Mal exakt dieselben Bytes bereitgestellt werden.

Ausführen von Images aus nicht vertrauenswürdigen Registries

Öffentliche Registries sind voll von „Typosquatting“-Images – Images, die beliebten ähneln, aber Malware enthalten.

Die Lösung: Private Registry und Image-Scanning

  1. Eine Private Registry verwenden: Öffentliche Images herunterladen, scannen und dann in Ihre eigene Private Registry hochladen (wie ECR, ACR oder Harbor).
  2. Automatisiertes Scanning: Verwenden Sie einen Scanner wie Trivy oder Clair, um bekannte CVEs (Common Vulnerabilities and Exposures) in Ihren Images zu prüfen.
  3. Admission Controller: Verwenden Sie ein Tool wie Kyverno oder OPA (Open Policy Agent), um zu verhindern, dass ein Image bereitgestellt wird, wenn es nicht gescannt wurde oder wenn es „kritische“ Schwachstellen enthält.

Eine umfassende Kubernetes-Hardening-Checkliste

Um dies umsetzbar zu machen, finden Sie hier eine zusammenfassende Checkliste, die Sie während Ihres nächsten Sprints oder Ihrer nächsten Sicherheitsüberprüfung verwenden können.

RBAC & Zugriff

  • Keinen Service-Konten cluster-admin zugewiesen (es sei denn, es ist absolut notwendig).
  • Keine Anwendungen, die das default-Service-Konto verwenden.
  • automountServiceAccountToken: false für Pods gesetzt, die keinen API-Zugriff benötigen.
  • API-Server ist nicht dem öffentlichen Internet zugänglich.
  • Anonyme Authentifizierung auf dem API-Server deaktiviert.

Pod-Sicherheit

  • privileged: true ist für Anwendungs-Pods verboten.
  • runAsNonRoot: true und runAsUser sind für alle Container definiert.
  • readOnlyRootFilesystem: true ist wo möglich aktiviert.
  • CPU- und Arbeitsspeicher-limits und requests sind für jeden Container gesetzt.

Netzwerksicherheit

  • Eine default-deny-all NetworkPolicy ist für jeden Namespace vorhanden.
  • Explizite „Allow“-Regeln werden für notwendigen Service-zu-Service-Traffic verwendet.
  • Egress-Traffic ist auf bekannte, erforderliche Endpunkte beschränkt.

Daten & Secrets

  • Keine Secrets in Git-Repositories gespeichert.
  • Secrets werden über einen externen Vault verwaltet (Vault, AWS SM usw.).
  • Secrets sind in etcd im Ruhezustand verschlüsselt.
  • etcd ist isoliert und erfordert mTLS für die Kommunikation.

Lieferkette

  • Images werden von einer privaten, vertrauenswürdigen Registry heruntergeladen.
  • Keine Images verwenden den :latest-Tag in der Produktion.
  • Alle Images werden vor der Bereitstellung auf CVEs gescannt.
  • Ein Admission Controller blockiert nicht-konforme Images.

Häufige Fehlkonfigurationsszenarien: Vorher und Nachher

Um Ihnen ein klareres Bild davon zu vermitteln, wie diese Lösungen in der Praxis aussehen, sehen wir uns einige „Vorher- und Nachher“-Szenarien an.

Szenario 1: Die „faule“ Bereitstellung

Vorher: Ein Entwickler stellt eine einfache Node.js-API bereit. Er verwendet das Standard-Service-Konto, läuft als Root, hat keine Ressourcenbeschränkungen und keine Netzwerkrichtlinien.

  • Risiko: Eine Schwachstelle in einem Node-Paket ermöglicht es einem Angreifer, eine Shell zu erhalten. Da er Root ist und ein Standard-Token besitzt, kann er das interne Netzwerk sondieren, die Datenbank finden und potenziell Privilegien auf den Knoten eskalieren.

Nachher:

  • Verwenden Sie ein benutzerdefiniertes ServiceAccount ohne API-Berechtigungen.
  • Setzen Sie runAsNonRoot: true.
  • Definieren Sie cpu- und memory-Limits.
  • Wenden Sie eine NetworkPolicy an, die nur Datenverkehr vom Ingress Controller zulässt.
  • Ergebnis: Selbst wenn der Angreifer eine Shell erhält, ist er ein Benutzer mit geringen Berechtigungen, kann nicht mit anderen Pods kommunizieren und den Knoten nicht durch das Verbrauchen des gesamten RAM zum Absturz bringen.

Szenario 2: Das "Secret"-Leck

Vorher: Das Team speichert sein Datenbankpasswort in einem Kubernetes Secret, das aus einer lokalen YAML-Datei erstellt wurde. Die YAML-Datei wurde versehentlich in einen Feature-Branch committet.

  • Risiko: Jeder mit Lesezugriff auf die Git-Historie hat nun das Produktionsdatenbankpasswort.

Nachher:

  • Verschieben Sie das Passwort in den AWS Secrets Manager.
  • Installieren Sie den External Secrets Operator.
  • Das K8s-Secret ist nun ein "Schatten" des AWS-Secrets und wird niemals in Git gespeichert.
  • Ergebnis: Das Secret ist zentralisiert, wird automatisch rotiert und berührt niemals unverschlüsselt die lokale Festplatte eines Entwicklers.

Häufig gestellte Fragen (FAQ)

1. Führt das Setzen von Ressourcenlimits nicht zum Absturz meiner Pods?

Ja, wenn Sie das Memory-Limit zu niedrig ansetzen, wird Ihr Pod OOMKilled. Das ist tatsächlich gut – es ist besser, wenn ein Pod abstürzt und neu startet, als wenn ein Pod Ihren gesamten physischen Knoten zum Absturz bringt. Der Trick besteht darin, die tatsächliche Nutzung Ihrer Anwendung mit Tools wie Prometheus und Grafana zu überwachen und Ihre Limits dann leicht über dem Spitzenverbrauch festzulegen.

2. Ist es wirklich notwendig, ein Service Mesh für die Netzwerksicherheit zu verwenden?

Für kleine Cluster könnte ein Service Mesh (wie Istio) übertrieben sein. Standard-Kubernetes-NetworkPolicies reichen in der Regel aus, um 80 % des Weges zu bewältigen. Wenn Sie jedoch erweiterte Funktionen wie gegenseitiges TLS (mTLS) zwischen allen Diensten oder komplexes Traffic Splitting benötigen, ist ein Service Mesh der richtige Schritt.

3. Wie finde ich alle meine aktuellen Fehlkonfigurationen, ohne jede YAML-Datei zu überprüfen?

Dies manuell zu tun, ist unmöglich, sobald Sie mehr als ein paar Anwendungen haben. Sie sollten automatisierte Tools verwenden. Tools wie kube-bench (das gegen CIS-Benchmarks prüft) und kube-hunter eignen sich hervorragend, um Schwachstellen zu finden. Für eine kontinuierlichere "Angreifersicht" auf Ihren Cluster kann eine Plattform wie Penetrify Ihre Angriffsfläche automatisch abbilden und die Pfade finden, die ein Angreifer tatsächlich nehmen würde.

4. Funktioniert runAsNonRoot, wenn das Image als Root erstellt wurde?

Wenn Sie runAsNonRoot: true setzen und die Metadaten des Images angeben, dass es als Root (UID 0) ausgeführt wird, verweigert Kubernetes den Start des Pods. Sie müssen zum Dockerfile zurückkehren und einen Benutzer hinzufügen (z. B. RUN useradd -u 1000 appuser && USER appuser).

5. Kann ich diese Sicherheitseinstellungen auf einen bestehenden Cluster ohne Ausfallzeiten anwenden?

Ja, aber gehen Sie vorsichtig vor. Wenden Sie nicht sofort eine default-deny-all-Netzwerkrichtlinie auf Ihren gesamten Produktions-Namespace an, sonst legen Sie Ihre gesamte Website lahm. Wenden Sie Richtlinien Dienst für Dienst an. Testen Sie Ihre securityContext-Änderungen ebenfalls in einer Staging-Umgebung, um sicherzustellen, dass Ihre Anwendung keine spezifische Root-Berechtigung zum Schreiben in einen Ordner benötigt.

Von reaktiver zu proaktiver Sicherheit wechseln

Fehlkonfigurationen zu beheben ist ein ständiger Kampf. Wenn Sie mehr Dienste, mehr Entwickler und komplexere Integrationen hinzufügen, wächst die "Sicherheitsfläche" Ihres Clusters. Wenn Sie sich auf eine manuelle Checkliste oder ein einmal jährliches Audit verlassen, spielen Sie im Wesentlichen ein Whack-a-Mole-Spiel, bei dem der Maulwurf einen Raketenwerfer hat.

Das Ziel sollte es sein, von einem reaktiven Zustand – in dem Sie Dinge beheben, nachdem sie gemeldet wurden – zu einem proaktiven Zustand überzugehen. Dies bedeutet, Sicherheit in Ihre CI/CD-Pipeline (DevSecOps) zu integrieren und kontinuierliche Tests einzusetzen.

Automatisierung ist der einzige Weg, um mit der Geschwindigkeit von Kubernetes Schritt zu halten. Wenn Sie Ihre Manifeste automatisch auf privileged: true scannen können, bevor sie überhaupt den Cluster erreichen, haben Sie die halbe Miete gewonnen. Wenn Sie ein Tool wie Penetrify verwenden, um kontinuierlich Angriffe auf Ihre Umgebung zu simulieren, müssen Sie nicht länger raten, ob Ihre Netzwerkrichtlinien funktionieren – Sie haben den Beweis.

Denken Sie daran: Sicherheit ist kein Ziel, sondern ein Prozess der Risikoreduzierung. Sie werden niemals einen "100% sicheren" Cluster haben, aber indem Sie diese häufigen Fehlkonfigurationen beheben, machen Sie es einem Angreifer so teuer und schwierig, dass er wahrscheinlich zu einem leichteren Ziel übergeht.

Bereit, das Rätselraten um die Sicherheit Ihres Clusters zu beenden? Warten Sie nicht auf eine Sicherheitsverletzung, um herauszufinden, dass Ihr RBAC zu offen ist oder Ihre Netzwerkrichtlinien Lücken aufweisen. Besuchen Sie Penetrify, um zu erfahren, wie automatisierte, bedarfsgerechte Sicherheitstests Ihnen helfen können, Schwachstellen in Echtzeit zu finden und zu beheben und so Ihre Cloud-native Infrastruktur wirklich sicher zu halten.

Zurück zum Blog