Einfachstmögliches sicheres Sandboxing (begrenzte Ressourcen erforderlich)

15

Ich arbeite an einem Projekt, das verteilte Simulationen implementiert: Beliebiger Code wird auf mehreren Knoten ausgeführt und die Ergebnisse werden später gesammelt und aggregiert.

Jeder Knoten ist eine Instanz einer virtuellen Ubuntu Linux-Maschine und führt einen Master-Prozess aus, der den auszuführenden Code an eine Reihe von Worker-Prozessen weiterleitet (1 für jeden Kern).

Bei dieser Frage geht es darum, wie sichergestellt werden kann, dass jeder Mitarbeiter in einer Sandkastenumgebung arbeitet, ohne dass für jeden von ihnen eine Instanz einer virtuellen Maschine verwendet wird. Die genauen Anforderungen an die Arbeiter sind:

  • fs : keine Schreibberechtigung, nur Leseberechtigung für ein einziges Verzeichnis (und Unterordner)
  • net : nur lokale Kommunikation erlaubt (IPC, TCP, was auch immer ...)
  • mem : Begrenzung der Speichernutzung (kein Auslagerungsspeicher) kill, wenn das mem-Limit überschritten wird
  • cpu : nur 1 core erlaubt, kill wenn über zeitlimit

Es sollten keine weiteren Einschränkungen auferlegt werden: Der Worker sollte in der Lage sein, dynamische Bibliotheken (aus dem schreibgeschützten Ordner) zu laden, neue Threads oder Prozesse zu erzeugen, die Systemfunktion aufzurufen, ecc ecc, aber die Grenzen müssen von den erzeugten / geladenen Entitäten und übernommen werden sollte in Summe angewendet werden (zum Beispiel kann ein Worker nicht zwei Threads erzeugen, die jeweils 800 MB belegen. Dies ist das Speicherlimit für einen solchen Worker von 1 GB).

Es versteht sich von selbst, dass es für den Arbeitnehmer keine Möglichkeit geben sollte, seine Rechte geltend zu machen.

Ich habe viel Zeit darauf verwendet, die verfügbaren Alternativen (SELinux, AppArmor, cgroups, ulimit, Linux-Namespaces, LXC, Docker, ...) zu überprüfen, um die einfachste Lösung zu finden, die meinen Anforderungen entspricht, aber meine Erfahrung auf dem Gebiet ist begrenzt.

Derzeitiges Verständnis: LXC und Docker sind für meinen Anwendungsfall etwas schwierig und nicht ganz sicher 1 . AppArmor ist wegen der einfacheren Konfiguration SELinux vorzuziehen. Verwenden Sie es für fs und Netzbeschränkungen. cgroups, die ulimit vorzuziehen sind (das mit einem einzelnen Prozess arbeitet), haben es für mem- und cpu-Einschränkungen verwendet.

Ist dies der einfachste Weg, um mein Ziel zu erreichen? Kann ich AppArmor oder cgroups ausschließlich verwenden? Gibt es eine offensichtliche Sicherheitslücke in meinem Modell? Die Richtlinie sollte lauten: "Arbeiter dürfen sich selbst stürzen, aber sonst nichts" .

StephQ
quelle
2
Wenn es Ihr Ziel ist, die Ressourcen zu begrenzen , könnten Sie viel besser abschneiden als ein Ubuntu-Gast (oder wirklich ein beliebiges Debian-Derivat) . In jedem Fall möchten Sie wahrscheinlich Linux im Benutzermodus und / oder (mit neueren Kerneln) den Benutzernamensraum
mikeserv
2
LXC klingt genau so, wie Sie es brauchen. Warum denkst du, ist es schwer und unsicher? (Sicher, es hatte Bugs, aber es hat alles, was Sie verwenden könnten.)
Gilles 'SO - hören Sie auf, böse zu sein'
Die verlinkte Präsentation (zugegebenermaßen ab 2011) und der Abschnitt Sicherheit in der Ubuntu LXC-Dokumentation , in dem es um 'Namespaces Leaks' geht, sind nicht sehr beruhigend. Scheint so, als ob LXC, das hauptsächlich auf Namespaces und Cgroups basiert, momentan sowieso die beste Option sein könnte. Ich fand auch Linux-Sandboxing , interessante Lektüre
StephQ
Es könnte ein wenig Umrüsten erforderlich sein, aber haben Sie darüber nachgedacht, auf BSD-Jails zu laufen?
Ryder
Während LXC insofern "schwer" ist, als es wie ein Haufen VMs ist, ist es wirklich einfach, sie herzustellen. Einige dieser Lösungen sind zwar "leichter", erfordern jedoch möglicherweise eine umfangreiche Konfiguration. Mit LXC müssen Sie möglicherweise keine Einstellungen zum Schreiben vornehmen, da die eine App den gesamten Container enthält.
MikeP

Antworten:

1

Ja, können Sie cgroups und SELinux / AppArmor verwenden ausschließlich zu überwachen und die Steuerung beliebiger Code, den Sie ausführen wird.

Mit cgroups können Sie Folgendes tun:

  1. Begrenzen Sie die CPU-Kernnutzung mit dem cpusetSubsystem auf 1 CPU
  2. Stellen Sie die Speicherverbrauchsgrenzen mit dem memorySubsystem ein und verfolgen Sie sogar die Gabeln. Ein Beispiel finden Sie unter https://github.com/gsauthof/cgmemtime .
  3. Verhindern Sie den Netzwerkzugriff auf alle Objekte, die lomit dem net_prioSubsystem nicht aktiviert sind.

Mit SELinux / AppArmor können Sie den Lese- / Schreibzugriff des Prozesses einschränken.

Hinweis: Ich bin mit AppArmor nicht vertraut, aber es handelt sich um ein obligatorisches Zugriffskontrollsystem (MAC). Das heißt, das Schreiben und Lesen zu schützen ist seine Aufgabe.

Für die Verwendung dieser Systeme müssen die richtigen Konfigurationen geschrieben werden. Natürlich ist das alles viel einfacher gesagt als getan. Hier sind ein paar Referenzlinks, um Ihnen den Einstieg zu erleichtern:

Viel Glück!

Dennis Chen
quelle
1

Ich würde SELinux für AppArmor nur dann verwerfen, wenn ich Ubuntu verwenden würde . (wirklich ziemlich schwierig)

LXC ist an sich nicht sicher Wenn Sie Sicherheit benötigen, müssen Sie diese über libvirt (basierend auf SELinux MLS ) verwenden.

Ihr Problem ist unendlich. Versuchen Sie also nicht, eine Lösung von der Stange zu finden, und denken Sie daran, dass sogar kernel.org pwoned wurde. Vor kurzem hat das FBI erklärt, dass jemand seine Systeme seit Jahren verwendet, ohne bis jetzt entdeckt zu werden.

Ich werde mit LXC / libvirt für ziemlich gute Sicherheit arbeiten oder ich werde die "neuen" Intel Clear Container ausprobieren , die eine sehr leichte VM für Ihren Container mit klarer Verwendung von DAX / KSM verwenden (ich habe sie nicht getestet, aber sie sehen sehr gut aus) vielversprechend).

Wenn Sie sich Sorgen über die Ausnutzung des Kernels machen, ist grsecurity Ihre Lösung, aber Sie müssen es in Ihre Container-Lösung integrieren (Kopfschmerzen sind sicher).

Es ist also keine leichte Aufgabe, LXC / libvirt sind wirklich ordentlich, aber vielleicht sind klare Container der richtige Weg.

Docker? Ich habe / würde Docker nicht für mehr als lokale Tests verwenden, wenn keine Vagabundkiste verfügbar war. Sie brauchen viel mehr Arbeit und eine viel bessere Community.

Natürlich sind systemd-Container auch nett, aber ich gehe davon aus, dass Sie sie nicht mögen / wollen, weil Sie sie nicht einmal erwähnt haben und sie keine herstellerunabhängige Lösung sind.

Wenn Sie etwas " Einfacheres " und Amateurfreundlicheres möchten , können Sie sich FireJail anschauen . Ich habe es für einige Desktop-Apps verwendet und es erledigt den Job. (Es ist ziemlich einfach, die Vorlage für Ihre benutzerdefinierte App zu erstellen. Verwenden Sie "Privat".) Mounts auf Ihre Verzeichnisse und beschränken das Netzwerk nur für die lokale Verwendung, gespawnte Prozesse erben für Eltern und geht weiter ...).

Prost und viel Spaß ohne verrückt zu werden. ;)

mehr2000
quelle
0

seccomp-bpf ist eine weitere Option, die für OpenSSH, vsftpd und Chromium gut funktioniert. Sie verfügt nur über exit (), sigreturn (), read () und write (), obwohl sie das Filtern von Systemaufrufen mithilfe konfigurierbarer Berkeley Packet Filter-Regeln ermöglicht. Es kann auch in Verbindung mit cgroups für Speicher, CPU usw. verwendet werden.

https://wiki.mozilla.org/Security/Sandbox/Seccomp

Keith Smith
quelle
0

Möglicherweise möchten Sie sich mit Grid-Computing-Systemen befassen. Insbesondere überprüft BOINC ( http://boinc.berkeley.edu ) fast alle Ihre Boxen.

Ich glaube, es wirkt sich auf Ihre Parameter als solche aus:

fs: kann nirgendwo anders in ein eigenes Verzeichnis lesen / schreiben

net: Kann so konfiguriert werden, dass nur der Netzwerkzugriff auf Ihren BOINC-Server zugelassen wird, ist jedoch nicht standardmäßig in IIRC enthalten

mem: ja, getrennte Speichergrenzen für inaktive und nicht inaktive Maschinen

CPU: Ja, kann sogar sagen "Nicht ausführen, wenn der Computer nicht im Leerlauf ist"

user159726
quelle