Я работаю над проектом, который реализует распределенное моделирование: произвольный код выполняется на нескольких узлах, а затем результаты собираются и объединяются.
Каждый узел является экземпляром виртуальной машины 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 исключительно? Есть ли в моей модели очевидная дыра в безопасности? Руководящий принцип должен быть «работнику разрешено самоуничтожиться, но не более того» .
Ответы:
Да, вы можете использовать cgroups и SELinux / AppArmor исключительно для мониторинга и управления произвольным кодом, который вы будете выполнять.
С cgroups вы можете сделать следующее:
cpuset
подсистемойmemory
подсистемой, отслеживая даже вилки. См. Https://github.com/gsauthof/cgmemtime для примера.lo
сnet_prio
подсистемой.А с помощью SELinux / AppArmor вы можете ограничить доступ процесса на чтение / запись.
Примечание: я незнаком с AppArmor, но это система обязательного контроля доступа (MAC), а это означает, что охранять запись и чтение - это его работа.
Использование этих систем является вопросом написания правильных конфигураций. Конечно, все это гораздо легче сказать, чем сделать. Итак, вот несколько справочных ссылок для начала:
Удачи!
источник
Я бы отказался от SELinux для AppArmor, только если бы я использовал Ubuntu . (действительно довольно сложно)
LXC сам по себе небезопасен. Если вам нужна безопасность, вы должны использовать их через libvirt (на основе SELinux MLS ).
Ваша проблема бесконечна, поэтому не пытайтесь найти какое-либо решение с полки и без бесконечного времени, помните, что даже kernel.org был помилован, и совсем недавно ФБР объявило, что кто-то использует их системы в течение многих лет без обнаружения до сих пор.
Я пойду с LXC / libvirt для довольно хорошей безопасности или попробую «новые» контейнеры Intel Clear , которые используют очень легкую виртуальную машину для вашего контейнера с явным использованием DAX / KSM (я не тестировал их, но они выглядят очень действительно многообещающе).
Если вы беспокоитесь об использовании ядра, grsecurity - это ваше решение, но вам придется интегрировать его с вашим контейнерным решением (наверняка, головная боль).
Так что задача непростая, LXC / libvirt действительно аккуратны, но, возможно, чистые контейнеры - это путь.
Docker? Я не использовал / не использовал докер для более чем локального тестирования, когда не было доступного блуждающего ящика, им нужно было больше работы и лучшее сообщество.
Конечно, системные контейнеры тоже хороши, но я предполагаю, что они вам не нравятся / не нужны, потому что вы даже не упомянули их, и они не являются независимым от поставщика решением.
Если вы хотите что-то «более простое» и более любительское, вы можете попробовать firejail , я использовал его для некоторых «приложений» на рабочем столе, и он делает свою работу (создать шаблон для вашего пользовательского приложения довольно просто, используйте «private») монтируется поверх ваших директорий и ограничивает сеть только для локального использования, порожденные процессы наследуют для родителя и продолжают ...).
Приветствия и веселиться, не сходя с ума. ;)
источник
seccomp-bpf - еще одна опция, которая хорошо работает для OpenSSH, vsftpd и Chromium, она имеет только exit (), sigreturn (), read (), она также использует write (), хотя она позволяет фильтровать системные вызовы с использованием настраиваемых правил Berkeley Packet Filter. Он также может быть использован в сочетании с cgroups для памяти, процессора и т.д ...
https://wiki.mozilla.org/Security/Sandbox/Seccomp
источник
Возможно, вы захотите взглянуть на сеточные вычислительные системы. В частности, BOINC ( http://boinc.berkeley.edu ) проверяет почти все ваши поля.
Я считаю, что это работает на ваших параметрах как таковых:
fs: может читать / писать в своем собственном каталоге, больше нигде
net: может быть настроен так, чтобы разрешить только сетевой доступ к вашему серверу BOINC, но не по умолчанию из коробки IIRC
mem: да, раздельные ограничения памяти для незанятых и незанятых машин
процессор: да, можно даже сказать "не работать, если компьютер не работает"
источник