Linux Container - sicher bauen und betreiben

Natürlich kommt man für das Deployment von Applikationen noch um Container herum - aber man möchte das immer weniger. Unternehmen verinnerlichen mehr und mehr die Vorteile von Linux-Containern für das Bauen und Deployment ihrer Applikationen und Services. Die Technologie ist beliebt und wird nicht zuletzt durch moderne Container-Plattformen und -Scheduler wie Kubernetes oder Nomad befeuert.

Ein hohes Maß an IT-Sicherheit ist dabei unumgänglich, schließlich muss der gesamte Stack möglichst (betriebs-)sicher sein. Das betrifft neben dem Produktivbetrieb auch die Prozesse rund um die Auslieferung. Gerade die Container-Landschaft ist nicht frei von Sicherheitsproblematiken und entsprechenden Risiken.

Wir beleuchten das Thema in diesem Post näher und steigen in die verschiedenen Aspekte von Security Hardening bei Linux-Container ein.

Risiko, Risiko, …

Wer Blogs und Foren zum Thema Docker oder Container verfolgt, stößt immer wieder auf Security-Themen, d.h. sicherheitstechnische Dinge, die für den Betrieb von Linux-Containern relevant sind. Zum Einen geht es dabei ein Möglichkeiten, die Sicherheitsmechanismen auszuhebeln, um beispielsweise mehr Rechte zu erlangen oder aus dem Container in Richtung Host auszubrechen. Zum Anderen werden Härtungs- und Abwehrmaßnahmen behandelt, also wie man seine Container ab besten sicher macht. Das alles wird leider sehr schnell sehr technisch und beinhaltet z.B. auf Mechanismen und Begriffe des Linux-Kernels wie cgroups, selinux, BPF usw. Natürlich alles spannend und relevant, aber für den Einstieg doch arg detailliert.

Ich versuche daher, mich dem Thema von der Nutzerseite her anzunähern. Welche Arten von Risiken gibt es und auf welcher Ebene sind sie angesiedelt? Ich möchte 3 Aspekte auswählen: Schwachstellen und Risiken (“CVEs”) in Bibliotheken und Softwarepaketen, Risiken bei der Automatisierung und betriebliche Sicherheitsrisiken zur Laufzeit.

CVEs im Container Images

Das ist vermutlich eines der meistgenannten Risiken. Fast jede containerisierte Applikation verwendet ein Basisimage (z.B. Fedora oder Alpine oder Ubuntu). Darin sind die Basispakete der Distribution installiert, und es gibt eine größere Anzahl an Common Vulnerabilities and Exposures, kurz CVEs. Diese Sicherheitsschwachstellen können ganze Applikationen betreffen oder nur Werkzeuge, oder auch nur einzelne Bibliotheken. Wenn so eine Bibliothek aber eine sehr zentrale Rolle einnimmt, haben viele Stellen ein Problem - Heartbleed lässt grüßen.

CVEs besitzen einen Schweregrad, der einen Hinweis auf das Risiko geben kann. Und natürlich heißt das Vorhandensein einer Schwachstelle in einem Programm oder einen Bibliothek nicht automatisch, dass die eigene Applikation betroffen ist - vielleicht verwendet man das ganze ja gar nicht. Oder? Aber vielleicht ist die Schwachstelle Teil eines komplexeren Angriffsvektors, also ist eine Detailbetrachtung meist ebenso komplex.

Risiken der Automatisierung

Continuous Integration und Delivery “bauen” im wörtlichen Sinne seit Jahren auf Container. Gerade für CI-Pipelines ist es sinnvoll, die Buildumgebung als Container bereit zu stellen, innerhalb derer Artefakte gebaut werden. Und wenn am Ende der Pipeline ein Container-Image entsteht, muss das ganze auch noch an den richtigen Ort bewegt werden. In der Regel werden Images von Buildsystemen in Registries hinterlegt, und Plattformen im Betrieb (wie von Test- und Produktionssystemen) bedienen sich daraus.

Das alles geschieht nicht mehr manuell, sondern vollautomatisch. Und manchmal gibt's auch noch “Pipelines as Code”, d.h. diese (automatischen) Prozesse werden auch automatisch aufgesetzt und durch Code beschrieben. So kommen Unternehmen dem Ziel nahe, kleine Änderungen am Code möglichst schnell und mit wenig Aufwand live stellen zu können. Bei all der gewonnenen Geschwindigkeit bleibt aber die Frage, ob die Applikation aus Sicherheitssicht genug getestet wird und ob man verhindern kann, dass Artefakte mit bekannt gewordenen CVEs überhaupt in einem Produktivsystem landen.

Sicherheitsrisiken zur Laufzeit

Falls bis hierhin alles “secure” abgelaufen ist, bleibt noch die Frage, ob man seine Container im Produktivsystem sicher betreibt. Obwohl Linux-Container eine Menge von sicherheitsunterstützenden Dingen des Linux-Kernels überhaupt erst einfach zugänglich gemacht haben ist es immer noch möglich, Container ziemlich unsicher zu betreiben. Der vermutlich bekannteste Ausspruch hierzu lautet “Don't run containers as root”, d.h. die Prozesse im Container sollten nicht als root-user laufen. Neben diesen noch vergleichsweise einfach umzusetzenden Tipp gesellen sich noch sehr viele andere Empfehlungen, also ist es hilfreich, sich mit Security Best Practices für die Laufzeit zu befassen.

Aber wie kann man einem Container zur Laufzeit “auf die Finger” schauen? Wenn ein Unternehmen ein SIEM (Security Information and Event Management) betreibt, um möglichst in Echtzeit Alarme von Servern und Anwendungen zu erhalten, sollte das auch für Container möglich sein.

Aleris Container Hardening Landscape

Aleris Container Hardening Landscape

In Projekten versuchen wir bei aleri, unseren Kunden nicht nur bei einzelnen technische Sicherheitsaspekten zu helfen, sondern auch Unterstützung über den gesamten Prozess der Softwareerstellung und -auslieferung zu geben. IT-Sicherheit ist nichts, was man nachträglich einfach dazu installiert - sie muss früh in die Entwicklung “hineingedacht” werden.

Durch die Umsetzung von agilen Organisationsformen haben sich Teams und Abteilungen auch in dieser Richtung gewandelt, weg von langwierigen Freigabeprozessen in Richtung von DevSecOps-Ansätzen, d. h. der integrierten Zusammenarbeit von Entwicklern, betriebs-affinen Menschen und Security-Spezialisten.

Wir betrachten drei Prozesse:

  • Build: Wie erstellen wir möglichst sichere Container Images?
  • Delivery: Wie lassen sich Images sicher transportieren und auf dem Weg prüfen?
  • At Runtime: Wie werden Container möglichst sicher zur Laufzeit betrieben und kontrolliert?

Build

Beim Build-Prozess geht es darum, ein möglichst sicheres Container-Image auszuliefern. Dazu gehört z.B. neben der Auswahl eines passenden Basisimages auch die Reduktion der Abhängigkeiten - was man nicht braucht, kann trotzdem eine Schwachstelle beisteuern. Hier liegen zahlreiche Security-Best-Practises vor, um Images mit sicheren Defaults auszustatten und somit die Angriffsfläche zu reduzieren.

Delivery

Teil des Delivery-Prozesses ist die Verarbeitung von Container-Images auf dem Weg zum Zielsystem. Container-Registries können unter Anderem automatisch Images nach Schwachstellen untersuchen und “Alarm schlagen”. Für manche Unternehmen ist es ausreichend, in einer frühen Phase - z.B. auf Testsystemen – CVEs zu erkennen und anzugehen. Bei sicherheitskritischen Bereichen möchten Unternehmen gar nicht erst, dass schwerwiegende Schwachstellen ihren Weg in das Produktivsystem finden - ganz klar ein Prozessthema.

At Runtime

Linux Server Hardening ist ein bekanntes Thema und sollte auch nicht vernachlässigt werden. Ziel ist, eine möglichst sichere Basis zum Betrieb von Container zu haben. Ähnliche Härtungsmaßnahmen ergeben sich auch für Container, und verschiedene Security Best Practises liegen hierzu vor. Durch Linux-Kernel-Proben haben Sicherheitswerkzeuge die Möglichkeit, der Applikation bei der Arbeit zuzuschauen und ggf. regelbasiert bei ungewöhnlichem Verhalten Alarme auszulösen.

Fazit

Die sicherheitstechnische Härtung von Servern und virtuellen Maschinen ist eine bekannte Tätigkeit. Wenn die Applikation im Container kommt, sollte dieser gehärtet werden - nichts Neues eigentlich, “same old”. Interessant ist nun, dass sich Werkzeuge und Methoden weiterentwickelt haben und dass die Prozess-Schritte von unterschiedlichen Akteuren am besten integriert vorgenommen werden. Die Arbeit an einem sicheren Anwendungsstack beginnt schon im Entwicklungsteam, je mehr Entwickler, Betriebs- und Security-Spezialisten zusammenarbeiten, desto besser. In Folgeposts werde ich die einzelnen Prozesse genauer betrachten und konkrete Werkzeuge für die Lösung zeigen.