Простейшая возможная безопасная песочница (необходимы ограниченные ресурсы)

15

Я работаю над проектом, который реализует распределенное моделирование: произвольный код выполняется на нескольких узлах, а затем результаты собираются и объединяются.

Каждый узел является экземпляром виртуальной машины Ubuntu Linux и запускает главный процесс, который заботится о пересылке кода, который должен быть выполнен, ряду рабочих процессов (по 1 для каждого ядра).

Этот вопрос о том, как убедиться, что каждый работник работает в изолированной среде, не прибегая к использованию экземпляра виртуальной машины для каждого из них. Точные требования к работникам:

  • fs : нет разрешения на запись, разрешение только на чтение ограничено одним каталогом (и подпапками)
  • net : разрешены только локальные коммуникации (IPC, TCP, что угодно ...)
  • mem : ограничение использования памяти (без подкачки памяти). kill, если превышен предел памяти.
  • процессор : разрешено только 1 ядро, убить если ограничение по времени

Не должно быть никаких других ограничений: рабочий должен иметь возможность загружать динамические библиотеки (из папки только для чтения), порождать новые потоки или процессы, вызывать системную функцию, ecc ecc, но ограничения должны наследоваться порожденными / загруженными объектами и следует применять суммированным образом (например, у нас не может быть рабочего, порождающего два потока, каждый из которых использует 800 МБ, поскольку ограничение памяти для такого рабочего составляет 1 ГБ).

Само собой разумеется, что у работника не должно быть возможности повысить свои права.

Я потратил немало времени на рассмотрение доступных альтернатив (SELinux, AppArmor, cgroups, ulimit, пространства имен Linux, LXC, Docker, ...) для самого простого решения, которое удовлетворяет моим требованиям, но мой опыт работы в этой области ограничен.

Текущее понимание: LXC и Docker немного сложны для моего случая использования и не полностью безопасны 1 . AppArmor предпочтительнее SELinux из-за более простой настройки, используйте его для ограничений fs и net; cgroups предпочтительнее ulimit (который работает на одном процессе), использует его для ограничений mem и cpu.

Это самый простой способ достичь моей цели? Могу ли я использовать AppArmor или cgroups исключительно? Есть ли в моей модели очевидная дыра в безопасности? Руководящий принцип должен быть «работнику разрешено самоуничтожиться, но не более того» .

StephQ
источник
2
Если вашей целью является ограничение ресурсов [ing] , вы можете сделать это намного лучше, чем гость Ubuntu (или, в действительности, любой производный от Debian) . В любом случае, вы , вероятно , хотите , пользовательский режим Linux и / или (с последних ядер) имен пользователя
mikeserv
2
LXC звучит как то, что вам нужно. Почему вы думаете, что это тяжелая сторона и небезопасно? (Конечно, в нем есть ошибки, но есть и все, что вы могли бы использовать.)
Жиль: «Так, перестаньте быть злыми»
Связанная презентация (предположительно с 2011 года) и раздел «Безопасность» в документации по Ubuntu LXC, в котором говорится о «утечках пространства имен», не очень обнадеживают. Похоже, что LXC, основанный главным образом на пространствах имен и cgroups, может быть лучшим вариантом сейчас в любом случае. Я также нашел Linux-Sandboxing , интересное чтение
StephQ
Это может потребовать небольшого переоснащения, но рассматривали ли вы запуск на BSD-тюрьмах?
Райдер
Хотя LXC может быть «тяжелым» в том смысле, что он похож на кучу виртуальных машин, сделать их действительно просто. Некоторые из этих решений, хотя и «более легкие», могут потребовать большого количества настроек. С LXC вам может не понадобиться настраивать такие вещи, как запись, поскольку одно приложение будет иметь весь контейнер.
MikeP

Ответы:

1

Да, вы можете использовать cgroups и SELinux / AppArmor исключительно для мониторинга и управления произвольным кодом, который вы будете выполнять.

С cgroups вы можете сделать следующее:

  1. Ограничить использование ядра ЦП до 1 ЦП с cpusetподсистемой
  2. Установите пределы использования памяти с memoryподсистемой, отслеживая даже вилки. См. Https://github.com/gsauthof/cgmemtime для примера.
  3. Доступ к сети Предотвратить все , что не на loс net_prioподсистемой.

А с помощью SELinux / AppArmor вы можете ограничить доступ процесса на чтение / запись.

Примечание: я незнаком с AppArmor, но это система обязательного контроля доступа (MAC), а это означает, что охранять запись и чтение - это его работа.

Использование этих систем является вопросом написания правильных конфигураций. Конечно, все это гораздо легче сказать, чем сделать. Итак, вот несколько справочных ссылок для начала:

Удачи!

Деннис Чен
источник
1

Я бы отказался от SELinux для AppArmor, только если бы я использовал Ubuntu . (действительно довольно сложно)

LXC сам по себе небезопасен. Если вам нужна безопасность, вы должны использовать их через libvirt (на основе SELinux MLS ).

Ваша проблема бесконечна, поэтому не пытайтесь найти какое-либо решение с полки и без бесконечного времени, помните, что даже kernel.org был помилован, и совсем недавно ФБР объявило, что кто-то использует их системы в течение многих лет без обнаружения до сих пор.

Я пойду с LXC / libvirt для довольно хорошей безопасности или попробую «новые» контейнеры Intel Clear , которые используют очень легкую виртуальную машину для вашего контейнера с явным использованием DAX / KSM (я не тестировал их, но они выглядят очень действительно многообещающе).

Если вы беспокоитесь об использовании ядра, grsecurity - это ваше решение, но вам придется интегрировать его с вашим контейнерным решением (наверняка, головная боль).

Так что задача непростая, LXC / libvirt действительно аккуратны, но, возможно, чистые контейнеры - это путь.

Docker? Я не использовал / не использовал докер для более чем локального тестирования, когда не было доступного блуждающего ящика, им нужно было больше работы и лучшее сообщество.

Конечно, системные контейнеры тоже хороши, но я предполагаю, что они вам не нравятся / не нужны, потому что вы даже не упомянули их, и они не являются независимым от поставщика решением.

Если вы хотите что-то «более простое» и более любительское, вы можете попробовать firejail , я использовал его для некоторых «приложений» на рабочем столе, и он делает свою работу (создать шаблон для вашего пользовательского приложения довольно просто, используйте «private») монтируется поверх ваших директорий и ограничивает сеть только для локального использования, порожденные процессы наследуют для родителя и продолжают ...).

Приветствия и веселиться, не сходя с ума. ;)

more2000
источник
0

seccomp-bpf - еще одна опция, которая хорошо работает для OpenSSH, vsftpd и Chromium, она имеет только exit (), sigreturn (), read (), она также использует write (), хотя она позволяет фильтровать системные вызовы с использованием настраиваемых правил Berkeley Packet Filter. Он также может быть использован в сочетании с cgroups для памяти, процессора и т.д ...

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

Кит Смит
источник
0

Возможно, вы захотите взглянуть на сеточные вычислительные системы. В частности, BOINC ( http://boinc.berkeley.edu ) проверяет почти все ваши поля.

Я считаю, что это работает на ваших параметрах как таковых:

fs: может читать / писать в своем собственном каталоге, больше нигде

net: может быть настроен так, чтобы разрешить только сетевой доступ к вашему серверу BOINC, но не по умолчанию из коробки IIRC

mem: да, раздельные ограничения памяти для незанятых и незанятых машин

процессор: да, можно даже сказать "не работать, если компьютер не работает"

user159726
источник