BLOG

Grundlagen der Containersicherheit: Orchestrierung

  Jordan Zebor

  Lori MacVittie

Veröffentlicht am 24. Juli 2019

Wenn Sie gerade erst in diese Serie einsteigen, möchten Sie vielleicht am Anfang beginnen: 
Grundlagen der Containersicherheit: Einführung
Grundlagen der Containersicherheit: Pipeline

Laut Tripwires „State of Container Security 2019“ betreibt derzeit fast jedes dritte (32 %) Unternehmen mehr als 100 Container in der Produktion. Ein kleinerer Prozentsatz (13 %) betreibt mehr als 500. Und 6 % der wirklich eifrigen Anwender verwalten derzeit mehr als 1.000. Es gibt nur wenige Organisationen, die Container in großem Maßstab betreiben , ohne über ein unterstützendes Orchestrierungssystem zu verfügen.

Die Orchestrierungsebene der Containersicherheit konzentriert sich auf die Umgebung, die für den täglichen Betrieb der Container verantwortlich ist. Wenn Sie Container verwenden, nutzen Sie den heute verfügbaren Daten zufolge mit ziemlicher Sicherheit Kubernetes als Orchestrator.

Es ist wichtig zu beachten, dass es auch andere Orchestratoren gibt, die meisten davon nutzen jedoch auch Komponenten und Konzepte, die von Kubernetes abgeleitet sind. Daher konzentrieren wir uns auf die Sicherheit von Kubernetes und seinen Komponenten.

Die Kubernetes-Umgebung

Kubernetes besteht aus mehreren beweglichen Teilen. Dies erschwert die Sicherung nicht nur aufgrund der Anzahl der beteiligten Komponenten, sondern auch aufgrund der Art und Weise, wie diese Komponenten interagieren. Einige kommunizieren über API. Andere über das Host-Dateisystem. Dies alles sind potenzielle Einstiegspunkte in die Orchestrierungsumgebung, die berücksichtigt werden müssen. 

grundlegende Kubernetes-Umgebung

Grundlegende Kubernetes-Umgebung

Ein kurzer Überblick über die Kernkomponenten, die Aufmerksamkeit erfordern:

  • API-Server und Kubelet
  • Pods
  • Usw.

Das heißt, holen Sie sich eine Tasse Kaffee, das hier wird etwas länger dauern.

1. Authentifizierung ist nicht optional

Aufmerksamen Lesern wird auffallen, dass ihnen das bekannt vorkommt. Sie haben vielleicht schon davon gehört, dass es als Sicherheitsregel Zwei bezeichnet wird, auch bekannt als Schließ die Tür ab. Es ist ein allgemeines Thema, das wir immer wieder wiederholen werden, weil es oft ignoriert wird. Eine starke Authentifizierung ist ein Muss. Wir beobachten, dass die Zahl der Sicherheitsvorfälle aufgrund mangelhafter Sicherheitspraktiken im Zusammenhang mit Containern weiterhin steigt. Und eine der häufigsten Ursachen ist eine fehlgeschlagene Authentifizierung, normalerweise bei der Bereitstellung in der öffentlichen Cloud.

Fordern Sie starke Anmeldeinformationen und wechseln Sie häufig. Der Zugriff auf den API-Server (über ungesicherte Konsolen) kann zu einer „Game Over“-Situation führen, da darüber die gesamte Orchestrierungsumgebung gesteuert werden kann. Das bedeutet, Pods bereitzustellen, Konfigurationen zu ändern und Container zu stoppen/starten. In einer Kubernetes-Umgebung ist der API-Server die „eine API, sie alle zu beherrschen“, die Sie vor böswilligen Akteuren schützen möchten.

So sichern Sie den API-Server und Kubelet

Es ist wichtig zu beachten, dass diese Empfehlungen auf dem aktuellen Kubernetes-Autorisierungsmodell basieren. Ziehen Sie immer die neueste Dokumentation für die von Ihnen verwendete Version zu Rate.

  • Aktivieren Sie mTLS überall
    - Weisen Sie jedem Dienst eine CA zu – k8s, etcd, Applications
    - Zertifikate rotieren und auf die Berechtigungen privater Schlüssel auf der Festplatte achten
  • Nur an sichere Adressen binden
    - Vorsicht vor den API-Konfigurationen „insecure-bind-address“ und „insecure-port“
    - Wenden Sie dies auf _alle_ Dienste an (SSH, Vault usw.)
  • Deaktivieren Sie „Anonyme Authentifizierung“
    - Klingt „Anonyme Authentifizierung“ nach einer guten Idee?
    - Ab 1.5 standardmäßig deaktiviert, manuell aktiviert mit „--anonymous-auth=True“
  • Autorisierung aktivieren
    - Verwenden Sie nicht „--authorization-mode=AlwaysAllow“
    - Der API-Server sollte „--authorization-mode=RBAC,Node“ haben
    - Kubelet sollte „--authorization-mode=Webhook“ haben
    - Beschränken Sie Kubelet so, dass es nur auf die Ressourcen seines eigenen Knotens zugreifen kann.

Es ist wichtig zu beachten, dass diese Empfehlungen auf dem aktuellen Kubernetes-Autorisierungsmodell basieren. Konsultieren Sie immer die neueste Dokumentation für die von Ihnen verwendete Version. 

2. Pods und Privilegien 

Pods sind eine Sammlung von Containern. Sie sind die kleinste Kubernetes-Komponente und abhängig vom Container Network Interface (CNI)-Plugin können alle Pods standardmäßig einander erreichen. Es gibt CNI-Plugins, die „Netzwerkrichtlinien“ verwenden können, um Einschränkungen dieses Standardverhaltens zu implementieren. Dies ist wichtig zu beachten, da Pods auf verschiedenen Kubernetes-Knoten (die einem physischen Server entsprechen) geplant werden können. Pods enthalten häufig auch Geheimnisse, bei denen es sich um private Schlüssel, Authentifizierungstoken und andere vertrauliche Informationen handeln kann. Aus diesem Grund werden sie „Geheimnisse“ genannt.

Das bedeutet, dass es mehrere Bedenken hinsichtlich der Pods und der Sicherheit gibt. Bei F5 gehen wir immer von einem kompromittierten Pod aus, wenn wir mit der Bedrohungsmodellierung beginnen. Das liegt daran, dass die Application Workloads in Pods bereitgestellt werden. Da die Workloads von Application am ehesten einem nicht vertrauenswürdigen Zugriff ausgesetzt sind, stellen sie auch die wahrscheinlichste Angriffsstelle dar. Aus dieser Annahme ergeben sich vier grundlegende Fragen, die bei der Planung der Eindämmung potenzieller Bedrohungen gestellt werden müssen. 

  1. Was könnte ein Angreifer mit anderen Pods sehen oder tun, wenn er Zugriff auf einen Pod hat?
  2. Kann ein Angreifer auf andere Dienste im Cluster zugreifen?
  3. Welche Geheimnisse werden automatisch gemountet?
  4. Welche Berechtigungen wurden dem Pod-Dienstkonto erteilt?

Die Antworten auf diese Fragen offenbaren Risiken, die ausgenutzt werden könnten, wenn ein Angreifer Zugriff auf einen Pod innerhalb des Clusters erhält. Um die Gefahren einer Pod-Kompromittierung einzudämmen, ist ein vielschichtiger Ansatz erforderlich, der Konfigurationsoptionen, Berechtigungskontrolle und Einschränkungen auf Systemebene umfasst. Denken Sie daran, dass mehrere Pods auf demselben (physischen oder virtuellen) Knoten bereitgestellt werden können und somit den Zugriff auf das Betriebssystem (normalerweise ein Linux-Betriebssystem) gemeinsam nutzen.

So mildern Sie Pod-Bedrohungen
Kubernetes enthält eine Pod-Sicherheitsrichtlinienressource, die sensible Aspekte eines Pods steuert. Es ermöglicht den Betreibern, die Bedingungen zu definieren, unter denen ein Pod arbeiten muss, um in das System gelassen zu werden, und erzwingt eine Basislinie für den Sicherheitskontext des Pods. Gehen Sie niemals davon aus, dass Standardeinstellungen sicher sind. Implementieren Sie sichere Baselines und überprüfen Sie die Erwartungen, um sich vor Pod-Bedrohungen zu schützen.

Spezifische Optionen für eine Pod-Sicherheitsrichtlinie sollten Folgendes berücksichtigen:

  • Vermeiden Sie privilegierte Container
    • Suchen Sie nach der Einstellung „—allow-privileged“ auf der Kube-API und/oder dem Kubelet
    • Suchen Sie in der Pod-Spezifikation nach „privileged: true“.
    • Reduzieren Sie das Sicherheitsrisiko mit „--allow-privileged=false“
  • Der Standard-Containerbenutzer bei Docker ist root
    • Vermeiden Sie das Ausführen jeglicher Workloads als Root
    • Die Pod-Sicherheitsrichtlinie kann „runAsUser“, „runAsGroup“ und „runAsNonRoot: true“ verwenden.
    • Ähnliche Optionen können in einem Dockerfile definiert werden
  • Rechteausweitung innerhalb eines Containers nicht zulassen
    • „allowPrivilegeEscalation: false“
  • Verwenden Sie SELinux / AppArmor
    • SELinux nutzt Multi Category Security, um Container voneinander zu isolieren
    • Aktiviert lassen und die Ablehnungen durcharbeiten
    • Das Deaktivieren oder Wechseln in den permissiven Modus verringert die Sicherheit erheblich
  • Symlink-/Entrypoint-Angriffe verhindern
    • Angreifer können die Entrypoint-Binärdatei überschreiben oder fehlerhafte symbolische Links erstellen.
    • Vermeiden Sie dies, indem Sie „readOnlyRootFilesystem: true“ festlegen.
  • Vermeiden Sie Host*-Konfigurationsoptionen
    • Angreifer mit Zugriff auf die Host-Ressourcen können ihre Angriffe eher auf den Host und/oder benachbarte Container ausweiten.
    • Vermeiden Sie Optionen wie hostPID, hostIPC, hostNetwork, hostPorts
  • Nur lesbare HostPath-Mounts
    • Wenn Sie Lese-/Schreibzugriffe auf dem Host konfigurieren müssen, gehen Sie bei der Bereitstellung vorsichtig vor und machen Sie dies auf keinen Fall zur Standardpraxis.
    • Verwenden Sie „readOnly“ auf allen erlaubten HostPaths, um Angriffe zu vermeiden
  • Seccomp-Profile
    • Reduzieren Sie die Angriffsfläche, indem Sie die zulässigen Systemaufrufe begrenzen
    • Der Docker-Standard wird einiges reduzieren, aber es ist ein generisches Profil
    • Application Profile bieten den größten Sicherheitsvorteil

3. Usw.

Etcd ist der Speicher für Konfigurationen und Geheimnisse. Ein Kompromiss kann hier die Extraktion vertraulicher Daten oder die Einschleusung schädlicher Daten ermöglichen. Beides ist nicht gut. Um Bedrohungen für etcd einzudämmen, muss der Zugriff kontrolliert werden. Dies lässt sich am besten durch die Durchsetzung von mTLS erreichen. Geheimnisse werden von Kubernetes in etcd als Base64-codiert gespeichert. Erwägen Sie die Verwendung einer Alpha-Funktion, „Verschlüsselungsanbieter“ , für stärkere Optionen beim Speichern vertraulicher Geheimnisse oder ziehen Sie die Verwendung von HashiCorp Vault in Betracht.

Lesen Sie den nächsten Blog der Reihe: 
Grundlagen der Containersicherheit: Arbeitsbelastung