Security für Docker-Umgebungen

Sicherer Containerhafen

30. Oktober 2018, 7:00 Uhr | Michael Vogeler

Virtualisierung mittels Containern ist heute aus der Entwicklung nicht mehr wegzudenken. Denn die Technik bringt zahlreiche Vorteile in Bezug auf Agilität und schnelle Produkteinführung. Unternehmen müssen sich jedoch neuen Security-Problemen stellen. Für die besonderen Sicherheitsanforderungen, die sich durch Tausende Container innerhalb einer Applikation ergeben, reichen traditionelle Security-Tools nicht mehr aus. Wer eine Reihe von Best Practices befolgt, ist mit Containern jedoch auf der sicheren Seite.

Containervirtualisierung ist in den letzten Jahren unter Entwicklern zur führenden Technik für Micro-Services geworden. Laut der Umfrage "2018 State of the Cloud Survey" von RightScale planen 83 Prozent der befragten Unternehmen den Einsatz von Containern oder nutzen diese bereits. Der Containereinsatz birgt aber auch neue Herausforderungen. Im Rahmen einer Studie der Cloud Native Computing Foundation (CNCF) haben 43 Prozent der befragten Unternehmen angegeben, dass die Containersicherheit eine der größten Hürden für den Einsatz von Containern darstellt.

Tatsächlich reichen traditionelle Sicherheitswerkzeuge, die der Überwachung monolithischer Applikationen dienen, für die Sicherung dieser Plattformen nicht mehr aus. Auf Micro-Service-Architekturen basierende Applikationen können Hunderte Micro-Services enthalten, die sich über Tausende von Containern verteilen. Dies erhöht die Angriffsfläche signifikant. Behandelt man jeden Container als Einheit eines Services, verringert deren schiere Anzahl die Transparenz und Auditierfähigkeit von Applikationen deutlich. Während die Kommunikation der Komponenten einer monolithischen Anwendung innerhalb der Applikation stattfindet, kommunizieren Micro-Service-basierte Applikationen intern sowie über externe Interfaces (REST-APIs). Entwickler müssen dadurch ein größeres Spektrum an Sicherheitsanforderungen der Micro-Service-Applikation berücksichtigen.

Basis-Images nutzen und sichern

Zunächst ist es wichtig, Container nur aus vertrauenswürdigen Quellen zu installieren. Für Unternehmen ist es dabei empfehlenswert, eine eigene interne, abgesicherte Docker-Registry zu hosten, welche vertrauenswürdige Docker-Basis-Images vorhält, die den Entwicklern als Grundlage für ihre Micro-Services oder Applikationen dienen. Beliebte Open-Source-Docker-Registries sind Gitlab, Nexus und Jfrogs Artifactory. Die drei größten Cloud-Anbieter AWS, Google und Microsoft offerieren ebenfalls eigene geeignete Produkte. Viele der genannten Open-Source-Registries bieten die Möglichkeit, interne Security-Scans durchzuführen. Gitlab zum Beispiel nutzt hier den CoreOS-Security-Scanner Clair. In einer solchen Registry sollte das IT-Team auch ein Lifecycle-Management der Images etablieren. Container, die schon vor Monaten gebaut und durch eine Schwachstelle angreifbar sind, gehören gekennzeichnet und aus der Registry gelöscht.

Das IT-Team kann die zur Entwicklung benötigten Basis-Images vom Docker-Hub herunterladen. Ein beliebtes Basis-Image ist Alpine, das mit einer Größe von 2 MByte in den Versionen 3.7 und 3.8 keine bekannten Schwachstellen enthält. Bei Betriebssystemen wie Debian oder CentOS ist es nötig, die entsprechenden Images vor der Bereitstellung für die Entwicklung zu aktualisieren. Das aktuelle Image library/centos:7.5.1804 beinhaltet zurzeit knapp 19 verwundbare Komponenten und wäre dadurch für die Entwicklung einer Applikation ungeeignet.

LL11S03a
Schematische Darstellung einer Jenkins-Pipeline. Bild: PlusServer

Viele der auf dem Docker-Hub vorgehaltenen Basis-Images erhalten leider nur unregelmäßig Updates. Der Security-Spezialist Anchore hat festgestellt, dass der Abstand zwischen den Updates der Images in den letzten Monaten immer größer geworden ist. Deswegen empfiehlt es sich, durch ein eigenes Docker-File die Images während der Entwicklung selbst zu aktualisieren. Ein Docker-File ist eine Textdatei, die quasi eine Schritt-für-Schritt-Anleitung für den Aufbau eines Docker-Images enthält. Ein Beispiel anhand von centos:latest:

FROM centos:latestRUN yum update -y && yum install -y epel-release && yum clean all

Bei der Verwendung von Basis-Images sollte man darauf verzichten, unnötige Pakete in den Container zu installieren. Eine in einen Container installierte Shell kann Tür und Tor für Angriffe öffnen. So ist jüngst der Fall eines kompromittierten Docker-Images bekannt geworden, das nach der Ausführung eine Reverse Shell als Hintertür geöffnet hat. Dieses Image war via Docker-Hub erhältlich und fand somit häufig Verwendung.

Absicherung von Containern

Container sollten "immutable" (unveränderbar) sein. Das bedeutet, dass man persistente Daten außerhalb des Containers sichert. Dies ermöglicht es, jeden Container jederzeit wegzuwerfen und neu aufzusetzen. Im nächsten Schritt gilt es, die CI/CD-Pipeline (Continuous Integration/Continuous Delivery) in Jenkins oder anderen Plattformen wie Gitlab mit einem Step für Container Security Scanning zu erweitern. Es ist unbedingt sicherzustellen, dass ein mit einer Applikation (zum Beispiel Nginx, Apache) angereichertes Basis-Image (Alpine) durch die installierten Komponenten nicht angreifbar wird.

Daher ist ein Image-Scan mit marktüblichen Container-Security-Scannern wie Clair, Anchore oder Jfrog XRay am Ende eines CI/CD-Build-Jobs zu empfehlen, bevor man das neu generierte Applikations-Image in die Container-Registry pusht. Diese Scanner ziehen täglich frische CVE-Security-Feeds (Common Vulnerabilities and Exposure) von Herstellern wie beispielsweise CentOS. Diese Feeds kommen dann beim Security-Scan zum Einsatz, um Schwachstellen oder Schadcode in den Komponenten der Container-Images zu identifizieren. Zudem ist es möglich, die im Image enthaltenen Paketkomponenten sowie die Container-Dateisystemstruktur anzuzeigen. So lassen sich unbekannte Images "auslesen", um Malware zu erkennen. Insgesamt ist es empfehlenswert, automatische Sicherheitstests in den Build- oder CI-Prozess zu integrieren.

Label erhöhen Transparenz

Als weitere wichtige Best Practice gilt das Labeln von Containern, um später wichtige Informationen abrufen zu können. Ein Beispiel dafür sieht wie folgt aus:

docker build –no-cache \–label ‚com.nexinto.vendor=Example GmbH‘ \ –label ‚com.exapmle.create_date= 2018-02-28 11:50:17‘ \–label com.example.build_number=7 \–label com.example.build_URL=https:// jenkins.example.com/job/docker_image_ application-alpine/7/ \ –label com.example.build_host=jenkins.example.com \–label com.example.job=docker_image_ application-alpine \–label com.example.git_url=git@ git.example.com:docker/application-alpine.git \–label com.example.git_commit=a68ef41ead 819aaa0066c944bead45698cf7bb1d -t build/ application-alpine:latest

Mittels "docker inspect $IMAGENAME" ist es nach dem Build-Prozess möglich, jederzeit das Erstellungsdatum, Build-Host, Jenkins-Job, Build-Nummer etc. des Containers auszulesen. Dies erhöht die Transparenz und lässt das IT-Betriebsteam und die Entwickler leicht erkennen, welchen Versions- oder Entwicklungsstand die Platform hat. Das Label "create_date" macht ebenfalls das Alter der Container ersichtlich.

LL11S03b
CIS Docker Benchmark liefert eine gute Basis, um Systeme zu härten. Bild: PlusServer

Als weitere Komponente im CI/CD-Prozess rückt nun die Container-Orchestrierungsplattform in den Fokus. Letztes Jahr hat Kubernetes hier maßgeblich die Oberhand gewonnen. Die in einem Kubernetes-Cluster befindlichen Server sollten sich bei Betriebssystem-Patches auf dem neusten Stand befinden. Es ist zwingend notwendig, diese Server abzusichern. Dafür steht das Open-Source-Werkzeug CIS Docker Benchmark zur Verfügung. Es offeriert eine Liste an Prüfungen und bietet damit eine gute Baseline, um Systeme zu härten. Häufig empfiehlt CIS Docker Benchmark folgende Einstellungen:

  • User Authentication,
  • spezifizierte Berechtigungen für Binary-File-Zugriffe und
  • Aktivierung des Loggings von Audit-Daten.

Um Datendiebstahl zu verhindern, sollte man den Containerzugriff auf das darunter liegende Host-Betriebssystem einschränken. Eine gängige Praxis ist es, die Container-Engine im Kernel und die Container selbst im User-Modus laufen zu lassen. Zusätzlich bietet Linux verschiedene Sicherheitsebenen, um Container zu limitieren. Dazu gehört die Möglichkeit, Kernel-Sicherheitsfunktionen und Module wie Namespaces, Seccomp, CGroups und SELinux zu nutzen.

Im Kubernetes-Cluster stehen weitere Security-Features zur Verfügung. Gängige Praxis ist es hier, eine rollenbasierte Zugriffskontrolle (Role-Based Access Control, RBAC) sowie Pod-Security- und Netzwerk-Richtlinien zu nutzen. Ein sehr hilfreiches Werkzeug, um fast 95 Prozent der möglichen Fehlkonfigurationen im Kubernetes-Cluster zu vermeiden, ist Kube-Bench. Es dient der Prüfung von Master Node oder Worker Node und der zugehörigen Control-Panel-Komponenten. Dabei läuft CIS Kubernetes Benchmark im Hintergrund. CIS Kubernetes Benchmark gibt ähnlich CIS Docker Benchmark eine nützliche Liste an Hinweisen aus, um den Kubernetes-Cluster abzusichern.

Containervirtualisierung bietet eine Reihe von Angriffsflächen über die Komponenten Container, Images, Registries, Orchestrierungsplattformen und Host-Betriebssysteme. Diese Vielzahl an Schwachstellen gab Anlass zu hitzigen Debatten, ob dieser neue Ansatz der Softwareentwicklung mehr Probleme verursacht, als er löst. Gerade im Geschäftseinsatz sollten Container daher hohen Sicherheitsanforderungen entsprechen. Wer die genannten Best Practices befolgt und sich nicht allein auf althergebrachte Sicherheitswerkzeuge verlässt, kann mit Containern jedoch nicht nur effizient, sondern auch sicher arbeiten.

Michael Vogeler ist Systemadministrator Application Services bei PlusServer, www.plusserver.com.


Lesen Sie mehr zum Thema


Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu FrontRange Solutions Deutsch- land GmbH

Weitere Artikel zu Acerdon GmbH

Matchmaker+