Я пытаюсь создать веб-приложение (работающее на серверах Linux), в котором пользователь будет загружать исполняемый файл, исполняемый файл будет запускаться на конкретном входе, доступном на сервере (подается через STDIN), а вывод (читается из STDOUT) будет возвращен пользователю.
Конечно, я не хочу, чтобы пользователь мог делать что-либо вредоносное на моем сервере. Я хотел бы запустить исполняемый файл в песочницаили иным образом запретить исполняемому файлу выполнять важные системные вызовы.
Понятия не имею, с чего начать. Я проверил Пользовательский режим Linux, но кажется, что у него слишком много накладных расходов (многие исполняемые файлы будут работать параллельно, и наличие виртуальной машины для каждого из них - слишком много накладных расходов).
Как мне продолжить?
редактировать: Я понимаю, что обычно этого избегают. Я понимаю, что есть риски. Считайте это чем-то, что вы бы сделали, чтобы узнать, как это можно сделать. Я видел это раньше в таких местах, как CodePad и Джорди, иногда это очень удобно.
Вы берете массивный, массивный рискуют запустить ненадежный код. Я бы полностью переосмыслил как то, что я хотел сделать, так и фундаментальные предположения моего проекта, если бы ответом на мою проблему, которую я придумал, было «запускать ненадежный код от произвольных пользователей на моем сервере».
Вы можете попробовать librestrict.
Это небольшая библиотека, предназначенная для LD_PRELOAD-ed перед запуском данного исполняемого файла, в основном работает путем chroot () в заданный каталог, затем удаляет все возможности (кроме тех, которые основаны на белом списке), а затем setuid () - в заданном user, не позволяя данному исполняемому файлу делать неприятные вещи.
Одно из преимуществ этой программы в том, что она выполняет chroot () после того, как система загрузила все необходимые библиотеки, поэтому, если вам повезет (она не хочет использовать dl () в некоторых других библиотеках), вы можете использовать ее с пустым каталогом. , как среда chroot ().
Хотя он немного старый и недокументированный, вы можете попробовать, я могу помочь вам.
Я думаю, что запуск исполняемых файлов на виртуальной машине является ваш лучший выбор. Например, на IRC-канале #bash есть бот, который позволяет выполнять произвольный код оболочки ... путем запуска его внутри виртуальной машины на основе qemu и последующего захвата stdout этого процесса. UML, вероятно, является достаточно хорошим решением.
Новый материал lguest (http://lguest.ozlabs.org/) наверное лучше; это скорее «контейнерный» механизм, чем полноценное решение «виртуализации»; что-то вроде Зоны Соляриса. Я не знаю, в каком состоянии сейчас находится этот проект.
Это должен быть исполняемый файл? Не могли бы вы ограничить загружаемые программы, например, исходным кодом на каком-нибудь языке сценариев (python, ruby), который имеет какую-то среду выполнения в песочнице. Или байт-код для чего-то вроде C # или Java? По крайней мере, C # и Java имеют встроенный механизм безопасности для разрешения и запрещения операций.
Тогда вам будет проще ограничить то, что загруженные программы могут и не могут делать.
Я пробовал нечто подобное и выбрал ядро с поддержкой grsecurity плюс монтирование привязки только для чтения для обмена системными файлами между хостом и песочницей. Затем приложение для тестирования было запущено в изолированной песочнице. Когда это будет сделано, все процессы, принадлежащие пользователю песочницы, будут уничтожены с помощью SIGKILL, а все изменяемые пользователем файлы будут удалены и заменены из оригинала. Хотя он может быть не настолько безопасным, как виртуальная машина, он очень близко подходит, если все сделано правильно. Преимущество намного меньше накладных расходов.