6

Я должен отметить код C, и часть этого включает в себя запуск и синхронизацию их представления. Проблема в том, что их код запускается как я, и они в принципе могут делать все что угодно, используя мои настройки разрешений. Например, они могут скопировать мой закрытый ключ ssh.

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

Есть ли хороший способ настроить среду, в которой вы можете запускать код, написанный другими, но ограничивать наносимый им ущерб?

6 ответов6

10

На самом деле существует несколько типов виртуальных машин, которые, как бы пропускаются в других ответах. У вас может быть так называемая виртуализация контейнеров - что-то вроде Linux vServer или OpenVZ. Они совместно используют ядро хоста, выполняя так называемые «контейнеры» (со своими собственными средами), а не виртуализируя любое оборудование, и работают почти так же быстро, как голые металлы. (OpenVZ чаще встречается в более дешевых сервисах VPS, но поддерживает только пользовательское ядро 2.6.x, тогда как vServer работает до последней стабильной версии).

Кроме того, издержки полной виртуализации на современной машине не так страшны, как вы думаете! При аппаратной виртуализации на процессорах среднего класса большинство пользователей даже не заметят какого-либо снижения производительности, если только не возникнет конфликт за ресурсы (например, хост или другая виртуальная машина много использовали). Это будет немного медленнее, потому что некоторые ресурсы используются гостевой ОС, но стоимость самой виртуализации практически ничтожна - особенно загрузка ЦП, поскольку она может быть передана на необработанное оборудование без (почти) трансляции, если это аппаратное ускорение. Вы можете попробовать это, вы можете быть удивлены.


Обратите внимание, что каждый из них также имеет разные уровни изоляции. Виртуализация контейнеров значительно упрощает использование ядра и других ошибок для «выхода» из контейнера - LXC совсем не безопасен, хотя OpenVZ считается довольно зрелым и безопасным (и обычно используется в сервисах VPS, где вы продаете контейнеры для недоверенных людей). vServer находится где-то посередине. Полная виртуализация имеет лучшую изоляцию, но некоторые атаки все еще существуют, чтобы вспыхнуть.

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

8

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

ssh как пользователь в вашей системе, и запускайте свои программы.

Вы можете даже написать небольшой сценарий оболочки bash (или любой другой сценарий оболочки) для достижения этой цели.

4
  1. Запустите код как nobody , что должно дать вам минимальные права. В зависимости от того, насколько привлекательна конфигурация, это может быть небезопасно
  2. Запуск в chroot тюрьме. В зависимости от кода это может изменить поведение, и тюрьмы часто могут быть нарушены. Они не являются функцией безопасности.
  3. Запустите на виртуальной машине. Я думаю, что очень мало известных примеров того, как можно вырваться из них, но я не уверен. Например, вы можете использовать Vagrant для настройки очень простой виртуализации. Пример конфигурации и команды.
1

Есть несколько разных возможностей, в зависимости от того, сколько изоляции вы хотите.

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

Следующим шагом является запуск кода в отдельной учетной записи пользователя, как предложил Vigneshwaren. Если вы хотите ограничить доступ к сети специально для конкретной учетной записи пользователя, это можно сделать с помощью сопоставления владельцев iptables. Когда это будет сделано, учетная запись пользователя может быть оставлена или удалена, и любые процессы, выполняющиеся от имени этого пользователя, могут быть полностью уничтожены.

Еще одним шагом вверх является добавление chroot-тюрьмы в отдельную учетную запись пользователя. Это может вызвать проблемы с библиотеками или конфигурационными файлами, которые должны быть на месте, но если это, например, простое упражнение на обработку чисел, это может быть практичным. Это гарантирует, что для этого кода будут доступны только те файлы, к которым у вас есть доступ к коду ученика.

Последний шаг - выполнение кода в совершенно отдельной среде. Представьте себе виртуальную машину, хотя отдельный физический компьютер может выполнить то же самое. Код может выполняться в полностью изолированной среде, в том числе с отключенным кабелем виртуальной сети, и любой ущерб, который он может нанести, в том числе заполнение диска или взрывная вилка, будет изолирован внутри виртуальной машины, и наихудшее, что может произойти, это что вам нужно принудительно отключить его. Поскольку у виртуальной машины будет полностью отдельная установка ОС, особенно если вы удалите сетевое соединение перед запуском программного обеспечения, это не может привести к утечке ваших конфиденциальных данных. С виртуальной машиной вы можете использовать моментальные снимки диска, чтобы вы могли быстро и легко вернуться в известное состояние после запуска программы каждого учащегося.

Все зависит от того, где по шкале «усилия против доверия» вы размещаете своих учеников. Меньшее доверие требует больше усилий с вашей стороны, чтобы ничего плохого не случилось.

0

I have to mark C code

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

Если вы не уверены, что запускаете его через виртуальную машину, но в большинстве случаев вы будете знать, что выполняется

0

Я работал над подобной системой несколько лет назад. Я использовал ptrace для ограничения системных вызовов (см. Код здесь) и, при необходимости, для изменения идентификатора пользователя или chroot. Если программы простые, включающие только чистые алгоритмы и базовые задачи ввода-вывода, это должно быть практическим решением, которое вы могли бы рассмотреть.

Кстати, стоит упомянуть, что вы должны также ограничить время компиляции / использование памяти. Некоторые вредоносные программы могут включать в себя директивы, такие как #include </dev/random> которые могут привести к зависанию компилятора в течение длительного времени, или некоторые рекурсивные макросы, заставляющие компилятор поглощать много памяти.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .