Container-Sicherheit in AKS: Vom Image zur Laufzeit (Teil 2 – Deploy & Runtime)

Dieser Artikel setzt den Überblick über die Containersicherheit in Azure Kubernetes Service (AKS) fort.

Im vorigen Teil haben wir uns auf die früheren Phasen des Lebenszyklus konzentriert, einschließlich Image-Sicherheit, Scannen und Registrierungskontrollen.

Lesen Sie Teil 1: Container-Sicherheit in AKS: Vom Image zur Laufzeit (Build & Registry)

Dieser Teil konzentriert sich auf die Bereitstellung und die Laufzeit, wo Konfiguration und Verhalten die effektive Sicherheitslage bestimmen.

Kubernetes-Sicherheitskontext

Der Sicherheitskontext ist der Kubernetes-Mechanismus zur Kontrolle dessen, was ein Container auf Betriebssystemebene tatsächlich tun darf. Er ist einer der wirkungsvollsten und am häufigsten übersprungenen Härtungsschritte.

Die Schlüsselfelder

  • runAsNonRoot: true – Kubernetes weigert sich, den Container zu starten, wenn das Image so konfiguriert ist, dass es als Root läuft. Eine Absicherung, wenn die Dockerfile-Disziplin nachlässt.
  • runAsUser – gibt die genaue UID an, unter der der Prozess läuft. Paaren Sie sie mit einer konsistenten Nicht-Root-UID in Ihrem Dockerfile.
  • readOnlyRootFilesystem: true – Das Root-Dateisystem des Containers wird schreibgeschützt eingehängt. Dies ist sehr effektiv, um Exploits einzudämmen: Die meisten Techniken zur Nachnutzung sind auf das Schreiben auf die Festplatte angewiesen. Ein schreibgeschütztes Dateisystem beseitigt das meiste davon.
  • allowPrivilegeEscalation: false – verhindert, dass der Prozess mehr Privilegien erlangt, als er zu Beginn hatte. Blockiert einen verbreiteten Pfad zur Privilegieneskalation.
  • capabilities – Linux-Fähigkeiten sind fein abgestufte Teile dessen, was Root tun kann. Container erhalten einen Standardsatz, den die meisten Anwendungen nicht benötigen. Lassen Sie sie alle weg und fügen Sie nur das hinzu, was benötigt wird.

Ein Basis-Sicherheitskontext für die meisten Workloads:

securityContext:
  runAsNonRoot: true
  runAsUser: 1001
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop:
      - ALL

Handhabung von readOnlyRootFilesystem in der Praxis

readOnlyRootFilesystem: true ist die Einstellung, die die Teams unvorbereitet trifft. Anwendungen, die temporäre Dateien schreiben müssen – Protokolle, Upload-Staging, Socket-Dateien – beginnen auf nicht offensichtliche Weise zu versagen. Die Lösung besteht nicht darin, die Einstellung zu deaktivieren, sondern bestimmte beschreibbare Verzeichnisse als emptyDir Volumes zu mounten:

volumeMounts:
  - name: tmp-dir
    mountPath: /tmp
volumes:
  - name: tmp-dir
    emptyDir:
      sizeLimit: 500Mi

emptyDir ist flüchtig (wird bei einem Pod-Neustart gelöscht) und gibt der Anwendung einen begrenzten beschreibbaren Bereich, ohne das gesamte Dateisystem zu öffnen. Setzen Sie immer eine sizeLimit – ein Anwendungsfehler, der /tmp ohne Limit füllt, kann den Node beeinträchtigen.

Pod-Sicherheitsstandards

Kubernetes 1.25+ bietet Pod Security Standards (PSS) als integrierten Ersatz für die veraltete PodSecurityPolicy. PSS definiert drei Profile – Privileged, Baseline und Restricted – die auf Namespace-Ebene über Labels durchgesetzt werden. Das Profil “Restricted” erzwingt die meisten der oben genannten Sicherheitskontexteinstellungen. Die Aktivierung dieses Profils für einen Namespace ist eine einzige Label-Änderung, die die Untergrenze für alles, was dort eingesetzt wird, anhebt.

Netzwerk-Politiken

Standardmäßig kann jeder Pod in einem Kubernetes-Cluster mit jedem anderen Pod kommunizieren. Über Namespaces hinweg. Ohne Einschränkung. Dies ist das Netzwerkäquivalent dazu, jeden Dienst in ein flaches LAN ohne Firewall-Regeln zu setzen.

Netzwerkrichtlinien sind die Kubernetes-eigene Art zu definieren, was erlaubt ist und was nicht. Sie werden durch das CNI-Plugin durchgesetzt – in AKS sind Azure CNI oder Calico die übliche Wahl.

Das mentale Modell

Betrachten Sie Netzwerkrichtlinien als Firewall-Regeln für den Datenverkehr zwischen Pods. Sie sind additiv – ein Pod, auf den keine Richtlinie angewendet wird, hat keine Einschränkungen. Ein Pod mit einer Richtlinie kann nur das tun, was die Richtlinien erlauben.

Ein praktischer Ausgangspunkt ist eine Standardverweigerungsrichtlinie für jeden Namespace und dann explizite Erlaubnisregeln für den Datenverkehr, der fließen soll:

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

Dadurch werden alle Ein- und Ausgänge für jeden Pod im Namensraum blockiert. Sie fügen dann spezifische Richtlinien hinzu, um nur die Pfade zu öffnen, die Sie benötigen – Frontend zu Backend, Backend zu Datenbank, Backend zu externen APIs.

Warum das wichtig ist

Der Wert von Netzwerkrichtlinien liegt in der Eingrenzung. Wenn ein Dienst kompromittiert wird, ermöglicht ein flaches Netzwerk dem Angreifer, jeden anderen Dienst im Cluster zu untersuchen und anzusprechen. Mit Netzwerkrichtlinien kann ein kompromittierter Pod nur das erreichen, was Sie ausdrücklich erlaubt haben. Der Explosionsradius ist begrenzt.

Laufzeitsicherheit

Image-Scans und Sicherheitskontexte sind präventive Kontrollen. Die Laufzeitsicherheit ist detektivisch: Sie beobachtet, was in den laufenden Containern tatsächlich passiert und warnt (oder blockiert), wenn etwas falsch aussieht.

Das Bedrohungsmodell

Selbst mit einem sauberen Image und korrekten Sicherheitskontexten kann ein Angreifer immer noch eine Schwachstelle in der Anwendung selbst ausnutzen. Zu diesem Zeitpunkt befindet sich der Angreifer in einem laufenden Container. Sicherheitstools für die Laufzeit überwachen Systemaufrufe, Netzwerkverbindungen und das Prozessverhalten, um Anomalien zu erkennen – ein Webserverprozess, der eine Shell startet, ein Container, der ausgehende Verbindungen zu unerwarteten IPs herstellt, ein Prozess, der Dateien liest, für die er keinen Grund hat.

Falco

Falco (CNCF-abgeschlossenes Projekt) ist das de-facto Open-Source-Laufzeit-Sicherheitstool für Kubernetes. Es klinkt sich über eBPF in den Linux-Kernel ein, liest Systemaufruf-Ereignisse in Echtzeit und wertet sie anhand eines Regelsatzes aus. Die Standardregeln fangen die offensichtlichen Dinge ab: im Container gespawnte Shell, sensibler Dateizugriff, Versuche der Privilegienerweiterung, ausgehende Verbindungen zu nicht auf der Whitelist stehenden Zielen.

Falco wird mit einem soliden Standard-Regelsatz geliefert, und die Regeln sind in YAML lesbar. Alarme werden standardmäßig an stdout gesendet und können an SIEM, Slack oder eine beliebige Alarmierungspipeline weitergeleitet werden.

Microsoft Defender für Container

Wenn Sie bereits im Azure-Ökosystem sind, lohnt sich die Aktivierung von Defender for Containers. Er deckt Image-Scans in ACR, Audit-Log-Analysen der Kubernetes-Kontrollebene und Laufzeit-Bedrohungserkennung für AKS-Knoten ab. Die Signalqualität ist im Allgemeinen gut, um gängige Angriffsmuster zu erkennen, und es lässt sich mit Microsoft Sentinel integrieren, wenn Sie ein zentralisiertes SIEM betreiben.

Die praktische Empfehlung: Defender for Containers als Basislösung mit geringem Betriebsaufwand, Falco für Teams, die benutzerdefinierte Regeln und eine genauere Kontrolle über die Erkennungslogik benötigen.

Geheimnisse Management

Dies ist eine kurze Frage, denn die Antwort ist klar: keine Geheimnisse in Umgebungsvariablen setzen.

Warum ENV-Vars ein Anti-Muster sind

Umgebungsvariablen sind praktisch. Sie sind in kubectl describe pod sichtbar, für jeden Prozess im Container zugänglich, werden von vielen Frameworks protokolliert und erscheinen oft in Crash-Dumps und Diagnoseausgaben. Ein Geheimnis in einer ENV-Variable ist ein Geheimnis, das bereits seine vorgesehene Begrenzung überschritten hat.

Kubernetes Secrets sind in ihrer Standardform nur unwesentlich besser – sie sind base64-kodiert (nicht verschlüsselt) und in etcd gespeichert. Ohne etcd-Verschlüsselung im Ruhezustand und strenges RBAC für die Secrets-API sind sie im Wesentlichen Klartext mit zusätzlichen Schritten.

Azure Key Vault + CSI-Treiber

Der richtige Ansatz in AKS besteht darin, Geheimnisse in Azure Key Vault zu speichern und sie mit dem Secrets Store CSI Driver in Pods einzubinden. Der Treiber holt das Geheimnis beim Starten des Pods ab, hängt es als Datei ein oder synchronisiert es mit einem Kubernetes Secret und kümmert sich um die Rotation. Der Pod liest eine Datei – er muss nie wissen, woher das Geheimnis stammt. Die verwaltete Identität steuert den Zugriff auf Key Vault, sodass für das Manifest und die Pipeline keine Anmeldedaten erforderlich sind.

Dies bedeutet auch, dass eine geheime Rotation in vielen Fällen ohne erneute Bereitstellung erfolgen kann. Der CSI-Treiber kann den montierten Wert nach einem Zeitplan aktualisieren.

Versiegelte Geheimnisse

Für Teams, die Geheimnisse in verschlüsselter Form an Git übergeben wollen (ein legitimes GitOps-Muster), verschlüsselt Sealed Secrets (von Bitnami, jetzt Teil der CNCF-Sandbox) ein Kubernetes-Geheimnis mit einem clusterspezifischen öffentlichen Schlüssel. Das verschlüsselte Objekt ist für die Übertragung sicher. Nur der Zielcluster kann es entschlüsseln. Es funktioniert gut mit ArgoCD oder Flux.

Schließen: Defense in Depth

Kein einzelnes Kontrollmittel macht Ihren Cluster sicher. Der Sinn dieses gesamten Stapels – Image-Hygiene, Scannen, Sicherheitskontexte, Netzwerkrichtlinien, Erkennung zur Laufzeit, ordnungsgemäße Verwaltung von Geheimnissen – besteht darin, dass jede Schicht die Lücken der anderen ausgleicht.

Ein Angreifer, der durch die Bildüberprüfung schlüpft, trifft auf einen nicht-root-geschützten Container.
Wenn ein Angreifer die Anwendung ausnutzt, trifft er auf eine Netzwerkrichtlinie, die seitliche Bewegungen verhindert.
Wenn er diese Barriere umgeht, erkennt Falco die Aktivität. Das ist Verteidigung in der Tiefe: nicht eine Mauer, sondern viele Schichten, bei denen das Durchbrechen einer immer noch mehr übrig lässt.

Der praktische Ansatzpunkt für die meisten Teams besteht darin, nicht alles auf einmal zu implementieren, sondern zu ermitteln, welche Schicht derzeit völlig fehlt, und diese Lücke zuerst zu schließen. In der Praxis sind Sicherheitskontexte und eine standardmäßig verweigerte Netzwerkrichtlinie die beiden Kontrollen, die am häufigsten fehlen und den größten unmittelbaren Nutzen bringen. Beginnen Sie dort und bauen Sie die übrigen Schichten schrittweise auf.

Wenn Sie zusätzliche DevOps-Unterstützung benötigen, kann Ihnen unser Team bei der Implementierung, dem laufenden Betrieb und dem Infrastrukturmanagement helfen. Erfahren Sie mehr auf unserer Website(Professional Services) oder kontaktieren Sie uns.

More News from Apptimized

Container-Sicherheit in AKS: Vom Image zur Laufzeit (Teil 1 - Build & Registry)

Dieser Artikel befasst sich mit der Containersicherheit in Azure Kubernetes…

Adobe Acrobat Zero-Day: aktive Ausnutzung über PDF-Dateien

Adobe hat ein Notfall-Sicherheitsupdate für Adobe Acrobat Reader veröffentlicht, nachdem…

Warum der Patch-Management-Workflow oft reaktiv wird

Warum fühlt sich Patch-Management oft unter Kontrolle an – bis…