Schwachstellenanalyse für Container und Cloud, Teil 1 Ebenen der Container-Sicherheit

Autor / Redakteur: Dipl. -Ing. Thomas Drilling / Stephan Augsten

Das Absichern von Container-Umgebungen ist eine nicht zu unterschätzende Angelegenheit. Dabei legen Betreiber von Container-Plattformen ihren Fokus eher darauf, die Container-Integrität und die Container Herkunft zu überwachen und zu kontrollieren.

Enthält die ursprüngliche Version eines Containers eine Schwachstelle, findet sich diese auch in den identischen Abbildern wieder.
Enthält die ursprüngliche Version eines Containers eine Schwachstelle, findet sich diese auch in den identischen Abbildern wieder.
(Bild: heju - Pixabay.com / CC0 )

Docker hat sich zum Synonym für Container-Technologie entwickelt, denn mit Docker wurde Container-Technik massentauglich. Engine, Management-Tools und Container-Marktplatz (Docker Hub) haben einen nicht unerheblichen Anteil daran.

Sicherheitstechnisch weisen (Docker-)Container allerdings neben systemimmanenten Aspekten ein weiteres Problem auf, der die Herkunft der Technik betrifft. Container werden über Images bereitgestellt und diese Abbilder basieren auf anderen Images.

Weist der Code eines (Basis-)Images Schwachstellen auf, dann übertragen sich die Schwachstellen unweigerlich auf sämtliche Container, die denselben Image-Code nutzen. Solange niemand diesen Code patcht und optimiert, helfen auch zusätzliche Sicherheitstools nicht.

Bedeutung von Container-Sicherheit

Es ist ja kein Geheimnis, dass sich z. B. der Docker-Hub über die Jahre zu einer Spielwiese für Entwickler und Virtualisierungs-Geeks entwickelt hat. Hier können sie sich nach Lust und Laune an der wieder entdeckten Linux/Unix-Technologie (Docker basiert bekanntlich auf LXC, das wiederum Konzepte aus Solaris Zones oder BSD Jails aufgreift) austoben.

Nachdem zunächst Entwickler die leichtgewichtigen Container für sich entdeckt hatten, rufen Container heute zunehmend auch IT-Verantwortlichen aus dem klassischen Virtualisierungsumfeld auf den Plan, weil Container im Kontext von DevOps sowie Continuous Integration and Delivery (CI/CD) auch für Unternehmen interessant werden.

Im Unternehmen müssen Container aber sowohl gesetzlichen Vorgaben, als auch interne Compliance- und Sicherheitsstandards genauso erfüllen, wie anderen Technologien auch. Der Schutz von Containern und dessen Überwachung ist daher für alle Unternehmen, die Container produktiv einsetzen, ein zentrales Problem, da handelsübliche Sicherheitstools in der Regel keine Container scannen.

Checkliste Container-Security

Container-Sicherheit startet bei fundamentalen Themen wie dem Härten der Systeme, wobei man den gesamten Container-Stack hierzu sinnvollerweise in Schichten betrachtet:

  • 1. Container Host
  • 2. Container Runtime
  • 3. Container Registry
  • 4. Container Images
  • 5. Container Orchestrator
  • 6. Persistent Storage

Absichern des Container-Hosts

Der wichtigste Layer ist der Host, der sämtliche Container „hostet“ (Docker-Host). Glücklicherweise bildet dieser aber den am einfachsten zu schützende Layer im Security-Stack. Hierbei wird es sich in den meisten Fällen um eine handelsübliche Linux-Distribution handeln. Wie man ein Linux-System härtet dürfte daher hinlänglich bekannt sein.

  • Angriffsvektoren minimieren: hierzu speckt man das zu verwendende Linux-System Dienst-technisch sowie dessen Kernel z. B. durch das Entfernen/Deaktivieren von Kernel-Modulen soweit ab, dass der resultierende Footprint nur dazu dient, Container zu hosten und zu überwachen.
  • Strikte Zugriffskontrolle: Besteht die einzige Rolle des Container-Hosts aber im Hosten von Containern, braucht man auf dem System nicht viele Benutzer-Konten. In den meisten Fällen genügt ein root-User, bei dem es einfach ist, nur Remote-Logins von spezifischen Remote-Hosts zu erlauben. Hinzu kommen ggf. noch eine Reihe von Dummy-User-Konten, die nur auf ausgewählte Services zugreifen dürfen. Tools wie App Armor oder SELinux helfen zudem beim Umsetzen einer strikten Access Control.

Absichern der Container Runtime

Aus den geschilderten Gründen lassen sich Container während der Laufzeit noch viel schwieriger schützen bzw. härten. Traditionelle Sicherheitswerkzeuge sind nämlich nicht dafür gebaut, laufende Container zu überwachen. Dazu empfiehlt sich folgende Vorgehensweise:

  • Definieren von Status-Baselines für die Container-Umgebung, wie z. B. „Normal” und „Sicher”. Durchführen von Echtzeit-Scans laufender Container und Vergleichen der Ergebnisse mit den definierten Baselines, um Anomalien auszuspüren, die eine Angriffssignatur darstellen könnten.
  • Nutzer sollten sich eher auf das „Absichern” der Applikation konzentrieren, als sich auf Netzwerk-Security-Tools zu verlassen. Firewalls und andere Arten von Perimeter-Netzwerken/DMZs funktionieren nämlich in einer Container-basierten Umgebung nicht.
  • Steht dann z. B. ein Update einer Applikation oder eines Dienstes an ist es besser, laufende Container zu stoppen und durch komplett neue zu ersetzen. In Container-Umgebungen gilt es als sicherer, die Container-Infrastruktur unverändert zu lassen, als zu versuchen, Live-Updates auf laufende Container anzuwenden. Dies führt auf lange Sicht gesehen zu Konfigurationsabweichungen und erschwert das Umsetzen von Security-Policies.
  • Laufende Container sind immer nur so sicher, wie der Applikations-Code, d. h. sämtliche traditionellen Regeln zum Schreiben sicheren Codes gelten und greifen auch hier

Absichern der Container Registry

Eines der Features, durch das sich Container-Umgebungen von traditionellen Umgebungen unterscheiden, ist die Container Registry. Registries sind praktisch, weil sie eine zentrale Bezugsquelle zum Herunterladen von Images zur Verfügung stellen.

Das ist nun keine wirklich neue Idee, denkt man etwa an die Online-Depots der diverses Linux-Distributionen, App Stores oder an Marktplätze für virtuelle Maschinen (OVA/OVF, z. B. VMware Solution Exchange) oder VM-Templates (AWS AMI Marketplace). Jedoch unterscheidet sich die Container Registry in einem wichtigen Punkt. In Container-Umgebungen stellen Registries tatsächlich die einzige Möglichkeit dar, an „containerisierte“ Applikationen zu kommen, während man Applikationen in traditionellen Umgebungen auch ganz ohne Paket-Repository installieren kann.

Daher sollte der Server, der die Registry hostet, ebenso wie der Container-Host möglichst geringe Angriffsfläche bieten. Außerdem dürfen ausschließlich sichere Zugriffsrichtlinien zum Einsatz kommen. Hierbei kann ein Image-Scanner helfen, der Verwundbarkeiten in Container-Images findet.

Absichern von Container Images

Die wichtigsten Schritte zum Absichern von Container-Images überlappen sich zu einem großen Teil mit denen zum Absichern der Registry. Allerdings erfordert das Absichern von Images noch einige zusätzliche Überlegungen:

  • Images sollten stets nur ein absolutes Minimum an Code beinhalten, gerade so viel, wie zwingend erforderlich ist, um den Service oder die Applikation auszuführen, für den das Image gedacht ist. Alle nicht zwingend benötigten Services sollten aus dem Image entfernt werden. So ist es z. B. nur in den seltensten Fällen erforderlich, im Image einen SSH-Server auszuführen, weil man sich jederzeit auf andere, sicherere Weise mit dem Container verbinden kann.
  • Der Zweck jedes Images besteht ja ausschließlich darin, als Vorlage für das Erstellen von Service- oder Applikations-Containern zu dienen. Daher sollten Images unter keinen Umständen für anderen Zwecke „missbraucht“ werden, wie etwa das Hosten von Quellcode. Dies wäre nämlich tatsächlich recht praktisch, aber es gibt bessere und sicherere Wege wie etwa ein Code-Repository.

Absichern des Orchestrators

Der Orchestrator ist das Gehirn der Container-Umgebung. Ein wichtiger Punkt, den man dabei im Hinterkopf behalten sollte: weder bei Kubernetes noch bei Docker Swarm handelt es sich um Sicherheits-Tools. Sie kümmern sich um das Provisionieren von Containern, sind aber nicht für Intrusion- oder Vulnerability-Detection konzipiert.

Nutzer dürfen daher von Kubernetes oder Docker Swarm nicht erwarten, dass deren Vorhandensein allein genügt, die Container-Umgebung sicher zu machen. Im Gegenteil ist es sogar erforderlich, Vorsichtsmaßnahmen zu treffen um sicherzustellen, dass der Orchestrator nicht zum Einfallstor mutiert.

Daher ist es ratsam, den Orchestrator nur aus einer offiziellen und vertrauten Quelle zu installieren. Ferner muss der Orchestrator für HA, bzw. automatisches Failover konzipiert, bzw. konfiguriert sein. In Abhängigkeit davon, welchen Orchestrator man konkret einsetzt, sind ggf. weitere, spezielle Maßnahmen zu treffen.

Wer sich mit dem Thema auseinandersetzen muss, findet beispielsweise einige Sicherheitsvorschläge in der Kubernetes-Community. Swarm-Nutzer erhalten entsprechende Security-Best-Practices im Docker Reference Guide. Einen ebenfalls sehr detaillierten Leitfaden zum Absichern des Orchestrators hat auch Twistlock selbst veröffentlicht.

Absichern des persistenten Storage

Der Persistent-Storage-Layer einer Container-Umgebung kann in vielfältigen Formen existieren – je nachdem, für welche Container-Plattform man sich entschieden hat, etwa Docker Data Volumes oder Flocker. Die Details zum Absichern der Container-Umgebung hängen also auch von den Details der Storage-Architektur ab.

Dazu folgende Überlegungen: meist benötigen Container gar keinen Schreib-Zugriff auf ein Container-Directory im Shared Storage. Gut ist es auch, wenn das verwendete Dateisystem Roll-Backs unterstützt.

Wie bei anderen Komponenten des Container-Stacks sind effiziente Access Controls der Schlüssel dazu. So müssen nur Container, die Zugriff auf Shared Storage benötigen, entsprechende Berechtigungen dazu haben. Außerdem ist sicherzustellen, dass keine User oder Apps auf dem Storage Server Zugriff auf das Storage-System haben, außer wenn dies zwingend erforderlich ist.

(ID:44886166)