Zum Hauptinhalt springen

Update, der Logger

· 5 Minuten Lesezeit
Entenute
NDM maintainer | Dev for Web, docs and CLI

Einer der zentralen Bestandteile von NDM ist es, zu beobachten, was ein analysiertes npm-Paket während seiner Ausführung tatsächlich macht. Wir möchten Informationen über gestartete Prozesse, Dateisystemzugriffe, Netzwerkverbindungen und potenziell sensible Daten sammeln.

Klingt eigentlich ziemlich einfach, oder?

Tatsächlich hat sich das Ganze als deutlich komplizierter herausgestellt als ursprünglich gedacht. Wir haben bereits mehrere Ansätze ausprobiert und sind mittlerweile bei einer Lösung angekommen, die sich ziemlich stark von unserem ursprünglichen Plan unterscheidet.

Unser ursprünglicher Plan​

Unser erster Ansatz war die Verwendung von Tetragon, einem auf eBPF basierenden Tool zur Überwachung und Absicherung von Systemaktivitäten zur Laufzeit.

Tetragon in unserer Docker-Umgebung zum Laufen zu bringen, war zunächst kein Problem. Der Container startete erfolgreich und auch unsere Policies wurden ohne Konfigurationsfehler akzeptiert.

Die eigentlichen Probleme begannen erst, als wir die Ereigniserfassung testen wollten.

Unsere Policies lieferten nicht die erwarteten Events. Besonders die Einschränkung auf Prozesse innerhalb unserer Sandbox bereitete Schwierigkeiten. Die zunächst verwendeten Mechanismen zur Containerauswahl funktionierten in unserer Docker-basierten Umgebung nicht wie erwartet, da wir kein Kubernetes einsetzen. (Tetraogn ist für Kubernetes genaut)

Das bedeutete: Tetragon lief zwar, aber wir konnten nicht zuverlässig die Informationen sammeln, die wir für NDM benötigten.

Anstatt noch mehr Zeit in einen Ansatz zu investieren, der nicht wie gewünscht funktionierte, entschieden wir uns deshalb für unsere zweite Option.

Plan „B“​

Natürlich hatten wir einen Plan B.

Wir entfernten den Tetragon-Container aus unserer Docker-Compose-Konfiguration und begannen mit Tests von Falco.

Diesmal sah die Sache schon deutlich besser aus. Wir konnten die Containerauswahl konfigurieren und unsere eigenen Regeln lieferten endlich die gewünschten Events.

Wir konnten verschiedene Arten von Aktivitäten erfolgreich erkennen:

  • Prozessaktivitäten: Erkennung von gestarteten Prozessen innerhalb der Sandbox.
  • Dateisystemaktivitäten: Beobachtung von Dateizugriffen, dem Erstellen und Verändern von Dateien.
  • Netzwerkaktivitäten: Erkennung ausgehender Netzwerkverbindungen.

Auch beim CPU-Verbrauch schnitt Falco in unseren Tests besser ab als unser vorheriger Tetragon-Aufbau.

Zum ersten Mal hatten wir einen funktionierenden Proof of Concept, der einen Großteil der benötigten Informationen erfassen konnte.

Allerdings gab es noch ein großes Problem: unsere Sandbox-Runtime.

gVisor​

NDM führt potenziell unsichere Pakete nicht einfach in gewöhnlichen Docker-Containern aus. Stattdessen verwenden wir gVisor als zusätzliche Isolationsschicht.

Aber was genau ist gVisor eigentlich?​

Im Gegensatz zu herkömmlichen Containern, die hauptsächlich auf Linux-Kernel-Mechanismen wie Namespaces und cgroups setzen, bringt gVisor einen zusätzlichen Kernel im Userspace mit. Dieser wird Sentry genannt.

Das bedeutet, dass Systemaufrufe von Anwendungen innerhalb der Sandbox von gVisor abgefangen und verarbeitet werden, anstatt direkt an den Host-Kernel weitergegeben zu werden.

Aus Sicherheitssicht ist das natürlich ein großer Vorteil. Für klassische Monitoring-Tools entsteht dadurch allerdings ein Problem.

Falco beobachtet Systemaktivitäten normalerweise über Events, die vom Host-Kernel erzeugt werden. Bei gVisor werden viele Vorgänge innerhalb der Sandbox jedoch von Sentry verarbeitet. Diese sind für Falco deshalb nicht auf dieselbe Weise sichtbar wie bei gewöhnlichen Containern.

Dadurch konnte Falco nicht den vollständigen Einblick in die Aktivitäten eines Pakets liefern, den wir für NDM benötigen.

Problem

Unsere Monitoring-Lösung muss beobachten können, was innerhalb der Sandbox passiert, und nicht nur, was auf dem Host-System geschieht. Die alleinige Überwachung des Host-Kernels reicht für unseren Aufbau nicht aus.

Wir hätten unsere Sandbox-Architektur natürlich überdenken können. Das hätte allerdings bedeutet, einen wichtigen Bestandteil des Sicherheitskonzepts von NDM infrage zu stellen.

Stattdessen suchten wir nach einer Lösung, die direkt mit gVisor zusammenarbeitet.

Eine neue Hoffnung​

Hier kommt SecCheck ins Spiel.

SecCheck ist ein direkt in gVisor integrierter Monitoring-Mechanismus. Damit kann gVisor sicherheitsrelevante Ereignisse aus der Sandbox über einen eigenen Event-Stream bereitstellen.

Und genau das haben wir gesucht!

Anstatt die Aktivitäten innerhalb der Sandbox von außen über den Host-Kernel beobachten zu müssen, können wir die Monitoring-Funktionen nutzen, die gVisor bereits selbst mitbringt.

Das bedeutet außerdem, dass wir weder unsere bestehende Sandbox-Architektur aufgeben noch eine zusätzliche Monitoring-Schicht einführen müssen, die möglicherweise gar nicht alle relevanten Vorgänge sehen kann.

Warum SecCheck vielversprechend ist
  • Direkte gVisor-Integration: Die Events stammen direkt von der Komponente, die für die Isolation der Sandbox verantwortlich ist.
  • Bessere Sichtbarkeit: Wir können Informationen über Aktivitäten erfassen, die bei einer herkömmlichen Überwachung auf Host-Ebene möglicherweise nicht sichtbar wären.
  • Passt zu unserer Architektur: Der Event-Stream kann von einem separaten Dienst empfangen und in unser bestehendes Django-Backend integriert werden.

Mit der Implementierung der Kommunikation zwischen gVisor und unserem Backend haben wir bereits begonnen. Erste Tests haben bestätigt, dass gVisor unseren konfigurierten SecCheck-Socket erreicht.

Bis wir alle relevanten Events zuverlässig erfassen, verarbeiten und speichern können, liegt allerdings noch etwas Arbeit vor uns. Insbesondere müssen wir mehrere gleichzeitig laufende Sandboxes unterstützen und sicherstellen, dass die Events immer der richtigen Analyse zugeordnet werden.

Ganz am Ziel sind wir also noch nicht, aber diesmal scheint die Richtung zu stimmen.

Weitere Details zur technischen Umsetzung werden in unserer Dokumentation folgen, sobald alles wie vorgesehen funktioniert.