Kapitel 1. Container-Sicherheitsbedrohungen
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
In den letzten Jahren ist die Nutzung von Containern explodiert. Die Konzepte rund um Container gab es schon einige Jahre vor Docker, aber die meisten Beobachter sind sich einig, dass es die benutzerfreundlichen Kommandozeilen-Tools von Docker waren, die Container seit ihrer Einführung im Jahr 2013 in der Entwicklergemeinschaft populär gemacht haben.
Container bieten viele Vorteile : Wie im ursprünglichen Slogan von Docker beschrieben, ermöglichen sie es dir, "einmal zu bauen und überall auszuführen". Dazu bündeln sie eine Anwendung und alle ihre Abhängigkeiten und isolieren die Anwendung vom Rest des Rechners, auf dem sie läuft. Die containerisierte Anwendung hat alles, was sie braucht, und lässt sich leicht als Container-Image verpacken, das auf meinem und deinem Laptop oder auf einem Server in einem Rechenzentrum gleichermaßen läuft.
Ein Nebeneffekt dieser Isolierung ist, dass du mehrere verschiedene Container nebeneinander laufen lassen kannst, ohne dass sie sich gegenseitig stören. Vor der Einführung von Containern konnte es leicht zu einem Abhängigkeitsproblem kommen, wenn zwei Anwendungen unterschiedliche Versionen derselben Pakete benötigten. Die einfachste Lösung für dieses Problem war es, die Anwendungen auf getrennten Rechnern laufen zu lassen. Mit Containern werden die Abhängigkeiten voneinander isoliert, so dass es ganz einfach ist, mehrere Anwendungen auf demselben Server laufen zu lassen. Die Leute haben schnell erkannt, dass sie die Vorteile der Containerisierung nutzen können, um mehrere Anwendungen auf demselben Host zu betreiben (egal ob es sich um eine virtuelle Maschine oder einen Bare-Metal-Server handelt), ohne sich um Abhängigkeiten kümmern zu müssen.
Der nächste logische Schritt bestand darin, containerisierte Anwendungen auf einen Cluster von Servern zu verteilen. Orchestratoren wie Kubernetes automatisieren diesen Prozess, so dass du eine Anwendung nicht mehr manuell auf einem bestimmten Rechner installieren musst; du sagst dem Orchestrator, welche Container du ausführen willst, und er findet für jeden einen geeigneten Ort.
Aus der Sicherheitsperspektive sind viele Dinge in einer containerisierten Umgebung die gleichen wie in einem traditionellen Einsatz. Es gibt Angreifer, die Daten stehlen, das Systemverhalten verändern oder die Rechenressourcen anderer nutzen wollen, um ihre eigenen Kryptowährungen zu schürfen. Das ändert sich nicht, wenn du auf Container umsteigst. Allerdings verändern Container die Art und Weise, wie Anwendungen ausgeführt werden, erheblich, und das birgt eine Reihe anderer Risiken.
Risiken, Bedrohungen und Abhilfemaßnahmen
Ein Risiko ist ein potenzielles Problem und die Auswirkungen dieses Problems, falls es eintreten sollte.
Eine Bedrohung ist ein Weg, wie dieses Risiko eintreten kann.
Eine Abschwächung ist eine Gegenmaßnahme gegen eine Bedrohung - etwas, das du tun kannst, um die Bedrohung zu verhindern oder zumindest die Wahrscheinlichkeit ihres Erfolgs zu verringern.
Es besteht zum Beispiel die Gefahr, dass jemand deine Autoschlüssel aus deinem Haus stiehlt und mit deinem Auto wegfährt. Es gibt verschiedene Möglichkeiten, die Schlüssel zu stehlen: ein Fenster einschlagen, um sie zu holen, eine Angelrute in den Briefkasten stecken, an deine Tür klopfen und dich ablenken, während ein Komplize schnell hineinschlüpft, um die Schlüssel zu holen. Ein Mittel gegen all diese Bedrohungen ist es, deine Autoschlüssel außer Sichtweite zu halten.
Die Risiken variieren stark von einer Organisation zur anderen. Für eine Bank, die Geld für ihre Kunden verwahrt, besteht das größte Risiko sicherlich darin, dass das Geld gestohlen wird. Eine E-Commerce-Organisation wird sich um die Risiken betrügerischer Transaktionen sorgen. Eine Person, die einen persönlichen Blog betreibt, könnte befürchten, dass jemand einbricht, um sich als sie auszugeben und unangemessene Kommentare zu posten. Da sich die Datenschutzbestimmungen von Land zu Land unterscheiden, ist das Risiko, dass persönliche Daten von Kunden weitergegeben werden, von Land zu Land verschieden - in vielen Ländern ist das Risiko "nur" rufschädigend, während in Europa die Allgemeine Datenschutzverordnung (GDPR) Geldstrafen von bis zu 4 % des Gesamtumsatzes eines Unternehmens vorsieht.
Da die Risiken sehr unterschiedlich sind, variiert auch die relative Bedeutung der verschiedenen Bedrohungen und damit auch die geeigneten Maßnahmen zur Risikominderung. Ein Rahmenwerk für das Risikomanagement ist ein Verfahren, mit dem man systematisch über Risiken nachdenkt, die möglichen Bedrohungen auflistet, ihre Bedeutung in eine Rangfolge bringt und einen Ansatz zur Risikominderung festlegt.
Bei der Bedrohungsmodellierung geht es darum, die potenziellen Bedrohungen für ein System zu identifizieren und aufzuzählen. Durch eine systematische Betrachtung der Systemkomponenten und der möglichen Angriffsarten kann ein Bedrohungsmodell dir dabei helfen, herauszufinden, wo dein System am anfälligsten für Angriffe ist.
Es gibt kein umfassendes Bedrohungsmodell, da es von deinen Risiken, deiner speziellen Umgebung, deiner Organisation und den Anwendungen abhängt, die du einsetzt, aber es ist möglich, einige potenzielle Bedrohungen aufzulisten, die für die meisten, wenn nicht sogar für alle Container-Einsätze gelten.
Container-Bedrohungsmodell
Eine Möglichkeit, über das Bedrohungsmodell nachzudenken, ist die Betrachtung der beteiligten Akteure. Dazu könnten gehören:
-
Externe Angreifer, die versuchen, von außen auf eine Einrichtung zuzugreifen
-
Interne Angreifer, die sich Zugang zu einem Teil des Einsatzes verschafft haben
-
Böswillige interne Akteure wie Entwickler und Administratoren, die über ein gewisses Maß an Berechtigung für den Zugriff auf die Bereitstellung verfügen
-
Unbeabsichtigte interne Akteure, die versehentlich Probleme verursachen können
-
Anwendungsprozesse, die zwar keine fühlenden Wesen sind, die dein System kompromittieren wollen, aber möglicherweise programmatischen Zugriff auf das System haben
Jeder Akteur hat bestimmte Berechtigungen, die du beachten musst:
-
Welchen Zugang haben sie durch ihre Anmeldedaten? Haben sie zum Beispiel Zugriff auf Benutzerkonten auf den Host-Rechnern, auf denen dein Einsatz läuft?
-
Welche Berechtigungen haben sie auf dem System? In Kubernetes kann sich dies auf die rollenbasierten Einstellungen für die Zugriffskontrolle für jeden Benutzer sowie für anonyme Benutzer beziehen.
-
Welchen Netzwerkzugang haben sie? Welche Teile des Systems sind zum Beispiel in einer Virtual Private Cloud (VPC) enthalten?
Es gibt verschiedene Möglichkeiten, einen Container-Einsatz anzugreifen. Eine Möglichkeit, sie zu erfassen, ist, sich die potenziellen Angriffsvektoren in jeder Phase des Lebenszyklus eines Containers vorzustellen. Diese sind in Abbildung 1-1 zusammengefasst.
- Anfälliger Anwendungscode
-
Der Lebenszyklus beginnt mit dem Anwendungscode, den ein Entwickler schreibt. Dieser Code und die Abhängigkeiten von Drittanbietern, auf die er sich stützt, können Fehler enthalten, die als Schwachstellen bekannt sind, und es gibt Tausende von veröffentlichten Schwachstellen, die ein Angreifer ausnutzen kann, wenn sie in einer Anwendung vorhanden sind. Die beste Methode, um zu verhindern, dass Container mit bekannten Schwachstellen ausgeführt werden, ist das Scannen von Images, wie du in Kapitel 7 sehen wirst. Das ist keine einmalige Aktion, denn es werden ständig neue Schwachstellen in bestehendem Code entdeckt. Beim Scannen muss auch festgestellt werden, wenn Container mit veralteten Paketen laufen, die mit Sicherheits-Patches aktualisiert werden müssen. Einige Scanner können auch Malware erkennen, die in ein Image eingebaut wurde.
- Schlecht konfigurierte Container-Images
-
Sobald der Code geschrieben ist, wird er in ein Container-Image eingebaut. Wenn du konfigurierst, wie ein Container-Image erstellt werden soll, gibt es viele Möglichkeiten, Schwachstellen einzubauen, die später für Angriffe auf den laufenden Container genutzt werden können. Dazu gehört, den Container so zu konfigurieren, dass er als Root-Benutzer läuft, was ihm mehr Rechte auf dem Host gibt, als er eigentlich braucht. Mehr dazu erfährst du in Kapitel 6.
- Maschinenangriffe bauen
-
Wenn ein Angreifer die Art und Weise, wie ein Container-Image erstellt wird, verändern oder beeinflussen kann, könnte er bösartigen Code einschleusen, der anschließend in der Produktionsumgebung ausgeführt wird. Darüber hinaus könnte ein Eindringen in die Build-Umgebung ein Sprungbrett sein, um in die Produktionsumgebung einzudringen. Dies wird auch in Kapitel 6 behandelt.
- Angriffe auf die Lieferkette
-
Sobald das Container-Image erstellt ist, wird es in einer Registry gespeichert und an dem Punkt, an dem es ausgeführt werden soll, aus der Registry abgerufen oder "gezogen". Woher weißt du, dass das Image, das du abrufst, genau dasselbe ist wie das, das du zuvor gepusht hast? Könnte es verfälscht worden sein? Ein Akteur, der ein Image ersetzen oder zwischen Build und Deployment verändern kann, hat die Möglichkeit, beliebigen Code auf deinem Deployment auszuführen. Das ist ein weiteres Thema, das ich in Kapitel 6 behandeln werde.
- Schlecht konfigurierte Container
-
Wie wir in Kapitel 9 besprechen werden, ist es möglich, Container mit Einstellungen zu betreiben, die ihnen unnötige und vielleicht ungeplante Privilegien geben. Wenn du YAML-Konfigurationsdateien aus dem Internet herunterlädst, führe sie bitte nicht aus, ohne sorgfältig zu prüfen, dass sie keine unsicheren Einstellungen enthalten!
- Anfällige Gastgeber
-
Container laufen auf Host-Rechnern und du musst sicherstellen, dass auf diesen Hosts kein anfälliger Code läuft (zum Beispiel alte Versionen von Orchestrierungskomponenten mit bekannten Schwachstellen). Es ist ratsam, die Menge der auf jedem Host installierten Software zu minimieren, um die Angriffsfläche zu verringern. Außerdem müssen die Hosts nach bewährten Methoden korrekt konfiguriert werden. Dies wird in Kapitel 4 behandelt.
- Aufgedeckte Geheimnisse
-
Anwendungscode benötigt oft Anmeldeinformationen, Token oder Passwörter, um mit anderen Komponenten in einem System zu kommunizieren. Bei einem Einsatz in Containern musst du diese geheimen Werte an den containerisierten Code weitergeben können. Wie du in Kapitel 12 sehen wirst, gibt es dafür verschiedene Ansätze mit unterschiedlichen Sicherheitsniveaus.
- Unsichere Vernetzung
-
Container müssen in der Regel mit anderen Containern oder mit der Außenwelt kommunizieren. In Kapitel 10 wird erläutert, wie die Vernetzung in Containern funktioniert, und in Kapitel 11 geht es darum, sichere Verbindungen zwischen den Komponenten einzurichten.
- Container-Escape-Schwachstellen
-
Die weit verbreiteten Container-Runtimes wie
containerd
undCRI-O
sind mittlerweile ziemlich abgehärtet, aber es liegt immer noch im Bereich des Möglichen, dass noch Fehler gefunden werden, durch die bösartiger Code, der in einem Container läuft, auf den Host gelangen kann. Ein solches Problem, das manchmal auch als Runcescape bezeichnet wird, wurde erst 2019 bekannt. In Kapitel 4 erfährst du mehr über die Isolierung, die den Anwendungscode innerhalb eines Containers einschränken soll. Für manche Anwendungen könnten die Folgen eines Ausbruchs so schädlich sein, dass es sich lohnt, über stärkere Isolationsmechanismen nachzudenken, wie sie in Kapitel 8 beschrieben werden.
Es gibt auch einige Angriffsvektoren, die nicht in diesem Buch behandelt werden.
-
Der Quellcode wird in der Regel in Repositories gespeichert, die möglicherweise angegriffen werden könnten, um die Anwendung zu vergiften. Du musst sicherstellen, dass der Zugriff der Benutzer auf das Repository angemessen kontrolliert wird.
-
Hosts sind vernetzt zusammen, oft mit einer VPC für die Sicherheit, und normalerweise mit dem Internet verbunden. Genau wie bei einer herkömmlichen Bereitstellung musst du die Host-Maschinen (oder virtuellen Maschinen) vor dem Zugriff von Bedrohungsakteuren schützen. Sichere Netzwerkkonfigurationen, Firewalls und Identitäts- und Zugriffsmanagement sind bei einer Cloud-Native-Implementierung genauso wichtig wie bei einer herkömmlichen Implementierung.
-
Container laufen in der Regel unter einem Orchestrator - in der Regel Kubernetes, aber es gibt auch andere Optionen wie Docker Swarm oder Hashicorp Nomad. Wenn der Orchestrator unsicher konfiguriert ist oder der administrative Zugriff nicht wirksam kontrolliert wird, bietet dies Angreifern zusätzliche Angriffsmöglichkeiten auf den Einsatz.
Hinweis
Wenn du mehr über Bedrohungsmodelle für Kubernetes-Einsätze wissen willst, solltest du das von der CNCF in Auftrag gegebene Kubernetes Threat Model lesen.
Darüber hinaus hat die Financial User Group der CNCF einen Kubernetes-Angriffsbaum veröffentlicht, der mit der STRIDE-Methode erstellt wurde.
Grenzen der Sicherheit
Eine Sicherheitsgrenze (manchmal auch Vertrauensgrenze genannt) verläuft zwischen den Teilen des Systems, so dass du unterschiedliche Berechtigungen brauchst, um dich zwischen diesen Teilen zu bewegen. In einem Linux-System kann der Systemadministrator die Sicherheitsgrenze, die festlegt, auf welche Dateien ein Benutzer zugreifen darf, ändern, indem er die Gruppen ändert, in denen der Benutzer Mitglied ist. Wenn du dich mit Linux-Dateiberechtigungen nicht auskennst, findest du in Kapitel 2 eine Auffrischung.
Ein Container ist eine Sicherheitsgrenze. Der Anwendungscode sollte innerhalb des Containers laufen und nicht auf Code oder Daten außerhalb des Containers zugreifen können, es sei denn, er hat die ausdrückliche Erlaubnis dazu (z. B. über ein in den Container eingebundenes Volume).
Je mehr Sicherheitsgrenzen zwischen einem Angreifer und seinem Ziel (z. B. deinen Kundendaten) liegen, desto schwieriger ist es für ihn, dieses Ziel zu erreichen.
Die im "Container-Bedrohungsmodell" beschriebenen Angriffsvektoren können miteinander verknüpft werden, um mehrere Sicherheitsgrenzen zu durchbrechen. Zum Beispiel:
-
Ein Angreifer kann aufgrund einer Schwachstelle in einer Anwendungsabhängigkeit in der Lage sein, Code aus der Ferne in einem Container auszuführen.
-
Angenommen, der angegriffene Container hat keinen direkten Zugriff auf wertvolle Daten. Der Angreifer muss einen Weg finden, den Container zu verlassen, entweder in einen anderen Container oder auf den Host. Eine Container-Escape-Schwachstelle wäre ein Weg aus dem Container; eine unsichere Konfiguration des Containers könnte ein weiterer sein. Wenn der Angreifer einen dieser Wege findet, kann er nun auf den Host zugreifen.
-
Der nächste Schritt wäre, nach Möglichkeiten zu suchen, Root-Rechte auf dem Host zu erlangen. Dieser Schritt könnte trivial sein, wenn dein Anwendungscode als root im Container läuft, wie du in Kapitel 4 sehen wirst.
-
Mit Root-Rechten auf dem Host-Rechner kann der Angreifer auf alles zugreifen, was der Host oder einer der Container, die auf diesem Host laufen, erreichen kann.
Das Hinzufügen und Verstärken der Sicherheitsgrenzen in deinem Einsatz wird Angreifern das Leben schwer machen.
Ein wichtiger Aspekt des Bedrohungsmodells ist die Berücksichtigung der Möglichkeit von Angriffen aus der Umgebung, in der deine Anwendungen ausgeführt werden. In der Cloud teilst du möglicherweise einige Ressourcen mit anderen Nutzern und deren Anwendungen. Die gemeinsame Nutzung von Rechnerressourcen wird als Multitenancy bezeichnet und hat einen erheblichen Einfluss auf das Bedrohungsmodell.
Multitenancy
In einer mandantenfähigen Umgebung führen verschiedene Nutzer, die sogenannten Tenants, ihre Arbeitslasten auf gemeinsamer Hardware aus. (Du kennst den Begriff "Mandantenfähigkeit" vielleicht auch im Zusammenhang mit Softwareanwendungen, wo er sich auf mehrere Benutzer bezieht, die sich dieselbe Softwareinstanz teilen, aber in dieser Diskussion wird nur die Hardware gemeinsam genutzt). Je nachdem, wem die verschiedenen Workloads gehören und wie sehr die verschiedenen Tenants einander vertrauen, brauchst du möglicherweise stärkere Grenzen zwischen ihnen, um zu verhindern, dass sie sich gegenseitig stören.
Das Konzept der Mandantenfähigkeit gibt es schon seit den Mainframe-Zeiten in den 1960er Jahren, als Kunden CPU-Zeit, Arbeitsspeicher und Speicherung auf einem gemeinsam genutzten Rechner mieteten. Das unterscheidet sich nicht so sehr von den heutigen öffentlichen Clouds wie Amazon AWS, Microsoft Azure und Google Cloud Platform, in denen Kunden CPU-Zeit, Arbeitsspeicher und Speicherung sowie andere Funktionen und verwaltete Dienste mieten. Seit Amazon AWS EC2 im Jahr 2006 eingeführt hat, können wir virtuelle Maschineninstanzen mieten, die auf Servern in Rechenzentren auf der ganzen Welt laufen. Auf einem physischen Rechner können viele virtuelle Maschinen (VMs) laufen, und als Cloud-Kunde, der eine Reihe von VMs betreibt, hast du keine Ahnung, wer die VMs betreibt, die neben dir stehen.
Gemeinsame Maschinen
Es gibt Situationen, in denen ein einzelner Linux-Rechner (oder eine virtuelle Maschine) von vielen Benutzern gemeinsam genutzt wird. Das ist z. B. an Universitäten sehr häufig der Fall und ein gutes Beispiel für echte Mandantenfähigkeit, bei der die Benutzer einander nicht vertrauen und, offen gesagt, auch die Systemadministratoren den Benutzern nicht trauen. In dieser Umgebung werden Linux-Zugriffskontrollen eingesetzt, um den Benutzerzugriff streng zu begrenzen. Jeder Benutzer hat seine eigene Anmelde-ID, und die Zugriffskontrollen von Linux werden eingesetzt, um den Zugriff zu beschränken und z. B. sicherzustellen, dass die Benutzer nur Dateien in ihren eigenen Verzeichnissen ändern können. Kannst du dir das Chaos vorstellen, wenn Studenten die Dateien ihrer Kommilitonen lesen oder - noch schlimmer - ändern könnten?
Wie du in Kapitel 4 sehen wirst, teilen sich alle Container, die auf demselben Host laufen, denselben Kernel. Wenn auf dem Rechner der Docker-Daemon läuft, hat jeder Benutzer, der docker
Befehle erteilen kann, praktisch Root-Zugriff, sodass ein Systemadministrator diesen nicht an nicht vertrauenswürdige Benutzer vergeben sollte.
In Unternehmen und insbesondere in nativen Cloud-Umgebungen wirst du diese Art von gemeinsam genutzten Rechnern eher selten sehen. Stattdessen nutzen die Nutzer/innen (oder Teams von Nutzer/innen, die sich gegenseitig vertrauen) in der Regel ihre eigenen Ressourcen, die ihnen in Form von virtuellen Maschinen zugewiesen werden.
Virtualisierung
Im Allgemeinen gelten virtuelle Maschinen als ziemlich stark voneinander isoliert, was bedeutet, dass es unwahrscheinlich ist, dass deine Nachbarn die Aktivitäten in deinen VMs beobachten oder stören können. In Kapitel 5 erfährst du mehr darüber, wie diese Isolation erreicht wird. Nach der gängigen Definition gilt Virtualisierung überhaupt nicht als Mandantenfähigkeit: Mandantenfähigkeit liegt vor, wenn sich verschiedene Personengruppen eine einzige Instanz derselben Software teilen, und bei der Virtualisierung haben die Nutzer/innen keinen Zugriff auf den Hypervisor, der ihre virtuellen Maschinen verwaltet, sie teilen sich also keine Software.
Das heißt nicht, dass die Isolierung zwischen den virtuellen Maschinen perfekt ist, und in der Vergangenheit haben sich Nutzer über "laute Nachbarn" beschwert, bei denen die Tatsache, dass man eine physische Maschine mit anderen Nutzern teilt, zu unerwarteten Leistungsschwankungen führen kann. Netflix war ein früher Nutzer der Public Cloud und hat in einem Blogbeitrag aus dem Jahr 2010 im Abschnitt "Co-tenancy is hard" eingeräumt, dass es Systeme gebaut hat, die eine Teilaufgabe absichtlich aufgeben, wenn sie sich als zu langsam erweist. In jüngerer Zeit haben andere behauptet, dass das Problem der lärmenden Nachbarn kein echtes Problem ist.
Es gab auch Fälle von Software-Schwachstellen, die die Grenze zwischen virtuellen Maschinen gefährden konnten.
Für einige Anwendungen und Organisationen (vor allem in Behörden, Finanzinstituten oder im Gesundheitswesen) sind die Folgen einer Sicherheitsverletzung so gravierend, dass eine vollständige physische Trennung gerechtfertigt ist. Du kannst eine private Cloud betreiben, die in deinem eigenen Rechenzentrum läuft oder von einem Service-Provider in deinem Namen verwaltet wird, um eine vollständige Isolierung deiner Workloads zu gewährleisten. Private Clouds sind manchmal mit zusätzlichen Sicherheitsmerkmalen ausgestattet, z. B. mit zusätzlichen Hintergrundkontrollen für das Personal, das Zugang zum Rechenzentrum hat.
Viele Cloud-Provider bieten VM-Optionen an, bei denen du garantiert der einzige Kunde auf einem physischen Rechner bist. Es ist auch möglich, von Cloud-Providern betriebene Bare-Metal-Maschinen zu mieten. In beiden Fällen vermeidest du das Problem der lärmenden Nachbarn und hast außerdem den Vorteil einer stärkeren Sicherheitsisolierung zwischen physischen Maschinen.
Egal, ob du physische oder virtuelle Maschinen in der Cloud mietest oder deine eigenen Server verwendest, wenn du Container einsetzt, musst du möglicherweise die Sicherheitsgrenzen zwischen mehreren Benutzergruppen berücksichtigen.
Container-Multimandantenschaft
Wie du in Kapitel 4 sehen wirst, ist die Isolation zwischen Containern nicht so stark wie die zwischen VMs. Auch wenn es von deinem Risikoprofil abhängt, ist es unwahrscheinlich, dass du Container auf demselben Rechner wie eine Partei verwenden willst, der du nicht vertraust.
Selbst wenn alle Container, die auf deinen Rechnern laufen, von dir oder von Personen betrieben werden, denen du absolut vertraust, solltest du dich gegen die Fehlbarkeit von Menschen absichern, indem du dafür sorgst, dass sich deine Container nicht gegenseitig beeinflussen können.
In Kubernetes kannst du Namensräume verwenden, um einen Cluster von Maschinen für die Nutzung durch verschiedene Personen, Teams oder Anwendungen zu unterteilen.
Hinweis
Das Wort "Namensraum" ist ein überladener Begriff. In Kubernetes ist ein Namensraum eine übergeordnete Abstraktion, die Cluster-Ressourcen unterteilt, auf die verschiedene Kubernetes-Zugriffskontrollen angewendet werden können. In Linux ist ein Namensraum ein Low-Level-Mechanismus zur Isolierung von Maschinenressourcen, die einem Prozess bekannt sind. Du wirst diese Art von Namensräumen in Kapitel 4 im Detail kennenlernen.
Verwende die rollenbasierte Zugriffskontrolle (RBAC), um die Personen und Komponenten einzuschränken, die auf diese verschiedenen Namensräume von Kubernetes zugreifen können. Die Details dazu liegen außerhalb des Rahmens dieses Buches, aber ich möchte erwähnen, dass Kubernetes RBAC nur die Aktionen kontrolliert, die du über die Kubernetes-API durchführen kannst. Anwendungscontainer in Kubernetes Pods, die zufällig auf demselben Host laufen, sind nur durch die in diesem Buch beschriebene Container-Isolierung voreinander geschützt, auch wenn sie sich in unterschiedlichen Namensräumen befinden. Wenn ein Angreifer einem Container auf den Host entkommen kann, macht die Kubernetes-Namensraumgrenze keinen Unterschied für die Fähigkeit, andere Container zu beeinflussen.
Container-Instanzen
Cloud-Dienste wie Amazon AWS, Microsoft Azure oder Google Cloud Platform bieten viele verwaltete Dienste an, über die der Nutzer Software, Speicherung und andere Komponenten mieten kann, ohne sie selbst installieren oder verwalten zu müssen. Ein klassisches Beispiel ist Amazons Relational Database Service (RDS); mit RDS kannst du ganz einfach Datenbanken bereitstellen, die bekannte Software wie PostgreSQL verwenden, und die Sicherung deiner Daten ist so einfach wie das Ankreuzen eines Kästchens (und das Bezahlen einer Rechnung, natürlich).
Managed Services haben sich auch auf die Welt der Container ausgeweitet. Azure Container Instances und AWS Fargate sind Dienste, mit denen du Container ausführen kannst, ohne dich um die zugrunde liegende Maschine (oder virtuelle Maschine) kümmern zu müssen, auf der sie laufen.
Dies kann dir einen erheblichen Verwaltungsaufwand ersparen und ermöglicht es dir, den Einsatz nach Belieben zu skalieren. Zumindest theoretisch könnten deine Container-Instanzen jedoch auf derselben virtuellen Maschine untergebracht sein wie die anderer Kunden. Erkundige dich im Zweifelsfall bei deinem Cloud-Provider.
Du kennst jetzt eine ganze Reihe potenzieller Bedrohungen für deinen Einsatz. Bevor wir uns dem Rest des Buches widmen, möchte ich dir einige grundlegende Sicherheitsprinzipien vorstellen, die dir bei der Entscheidung helfen sollen, welche Sicherheitstools und -prozesse du für deinen Einsatz einführen musst.
Sicherheitsprinzipien
Dies sind allgemeine Richtlinien, die allgemein als kluger Ansatz angesehen werden, unabhängig von den Details dessen, was du zu sichern versuchst.
Least Privilege
Das Prinzip der geringsten Privilegien besagt, dass du den Zugriff auf das absolute Minimum beschränken solltest, das eine Person oder eine Komponente benötigt, um ihre Aufgabe zu erfüllen. Wenn du zum Beispiel einen Microservice hast, der die Produktsuche in einer E-Commerce-Anwendung durchführt, sollte dieser Microservice nach dem Prinzip der geringsten Rechte nur über Anmeldeinformationen verfügen, die ihm einen Lesezugriff auf die Produktdatenbank ermöglichen. Er muss weder auf Benutzer- noch auf Zahlungsinformationen zugreifen und auch keine Produktinformationen schreiben.
Defense in Depth
Wie du in diesem Buch sehen wirst, gibt es viele verschiedene Möglichkeiten, wie du die Sicherheit deines Einsatzes und der darin laufenden Anwendungen verbessern kannst. Das Prinzip der "Defense in Depth" besagt, dass du mehrere Schutzschichten anwenden solltest. Wenn ein Angreifer in der Lage ist, eine Verteidigungsschicht zu durchbrechen, sollte eine andere Schicht ihn daran hindern, deiner Einrichtung zu schaden oder deine Daten zu exfiltrieren.
Verringerung der Angriffsfläche
Im Allgemeinen gilt: Je komplexer ein System ist, desto wahrscheinlicher ist es, dass es einen Weg gibt, es anzugreifen. Die Beseitigung der Komplexität kann das System schwerer angreifbar machen. Dazu gehören:
-
Reduzierung der Zugangspunkte, indem die Schnittstellen möglichst klein und einfach gehalten werden
-
Begrenzung der Nutzer und Komponenten, die auf einen Dienst zugreifen können
-
Minimierung der Menge an Code
Begrenzung des Explosionsradius
Das Konzept der Aufteilung von Sicherheitskontrollen in kleinere Teilkomponenten oder "Zellen" bedeutet, dass die Auswirkungen im schlimmsten Fall begrenzt sind. Container eignen sich gut für dieses Prinzip, denn durch die Aufteilung einer Architektur in viele Instanzen eines Microservice kann der Container selbst als Sicherheitsgrenze dienen.
Aufgabentrennung
Mit dem Prinzip der geringsten Privilegien und der Begrenzung des Sprengrads ist die Idee der Aufgabentrennung verbunden, bei der verschiedene Komponenten oder Personen so weit wie möglich nur für die kleinste Teilmenge des Gesamtsystems zuständig sind, die sie benötigen. Dieser Ansatz begrenzt den Schaden, den ein einzelner privilegierter Benutzer anrichten kann, indem er sicherstellt, dass bestimmte Vorgänge mehr als die Befugnisse eines einzelnen Benutzers erfordern.
Anwendung von Sicherheitsprinzipien mit Containern
Wie du in späteren Abschnitten dieses Buches sehen wirst, kann die Granularität von Containern uns bei der Anwendung all dieser Sicherheitsprinzipien helfen.
- Das geringste Privileg
-
Du kannst verschiedenen Containern unterschiedliche Berechtigungen geben, die sich jeweils auf die kleinste Gruppe von Berechtigungen beschränken, die sie zur Erfüllung ihrer Funktion benötigen.
- Defense in depth
-
Container bieten eine weitere Grenze, an der Sicherheitsvorkehrungen durchgesetzt werden können.
- Verringerung der Angriffsfläche
-
Die Aufteilung eines Monolithen in einfache Microservices kann saubere Schnittstellen zwischen ihnen schaffen, die bei sorgfältigem Design die Komplexität reduzieren und damit die Angriffsfläche begrenzen können. Es gibt das Gegenargument, dass das Hinzufügen einer komplexen Orchestrierungsschicht zur Koordination von Containern eine weitere Angriffsfläche bietet.
- Begrenzung des Explosionsradius
-
Wenn eine containerisierte Anwendung kompromittiert wird, können Sicherheitskontrollen dazu beitragen, den Angriff innerhalb des Containers einzuschränken und zu verhindern, dass er sich auf den Rest des Systems auswirkt.
- Aufgabentrennung
-
Berechtigungen und Zugangsdaten können nur an die Container weitergegeben werden, die sie benötigen, so dass die Kompromittierung eines Satzes von Geheimnissen nicht unbedingt bedeutet, dass alle Geheimnisse verloren sind.
Diese Vorteile klingen gut, sind aber eher theoretischer Natur. In der Praxis können sie leicht durch eine schlechte Systemkonfiguration, schlechte Container-Image-Hygiene oder unsichere Praktiken zunichte gemacht werden. Am Ende dieses Buches solltest du gut gewappnet sein, um die Sicherheitsfallen zu vermeiden, die bei einem containerisierten Einsatz auftreten können, und die Vorteile zu nutzen.
Zusammenfassung
Du hast nun einen Überblick über die Arten von Angriffen, die einen Container-basierten Einsatz beeinträchtigen können, und eine Einführung in die Sicherheitsgrundsätze, die du zur Abwehr dieser Angriffe anwenden kannst. Im weiteren Verlauf des Buches wirst du dich mit den Mechanismen befassen, die Containern zugrunde liegen, damit du verstehst, wie Sicherheitstools und bewährte Methoden zusammenwirken, um diese Sicherheitsprinzipien umzusetzen.
Get Container Sicherheit now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.