Запустите ненадежную программу C в песочнице в Linux, которая не позволяет ей открывать файлы, разветвлять и т. д.?


Мне было интересно, существует ли способ запустить ненадежную программу C под песочницей в Linux. Что-то, что помешало бы программе открывать файлы или сетевые подключения, или разветвление, exec и т. д.?

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

11 104

11 ответов:

я использовал Systrace для песочницы ненадежных программ как в интерактивном, так и в автоматическом режиме. Он имеет ptrace()-основанный бэкэнд, который позволяет использовать его в системе Linux без особых привилегий, а также гораздо более быстрый и мощный бэкэнд, который требует исправления ядра.

также можно создать "песочницу" на UNIX-подобных системах с помощью chroot(1), хотя это не совсем так просто и безопасно. Linux Контейнеры и FreeBSD jails являются лучшей альтернативой chroot. Другой альтернативы на Linux заключается в использовании системы безопасности, такие как SELinux или AppArmor, что я бы предложил для производственных систем.

мы могли бы помочь вам больше, если бы вы сказали, как именно это то, что вы хотите сделать.

EDIT:

Systrace будет работать для вашего случая, но я думаю, что что-то основано на Модель Безопасности Linux как AppArmor или SELinux является более стандартным, и поэтому предпочтительным, альтернативой, в зависимости от вашего распределения.

EDIT 2:

пока chroot(1) доступна на большинстве (всех?) Unix-подобные системы, он имеет довольно много проблем:

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

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

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

  • chroot() защищает только файловую систему. Это не мешает вредоносная программа от открытия сетевых сокетов или плохо написанная от всасывания каждого доступного ресурса.

проблема использования ресурсов является общей для всех альтернатив. квоты файловой системы предотвратит заполнение диска программами. Правильно ulimit (setrlimit() в C) настройки могут защитить от чрезмерного использования памяти и любых вилочных бомб, а также остановить процессорные свиньи. nice(1) можно опустить приоритет этих программ, так что компьютер может быть использован для любых задач, которые считаются более важными без проблем.

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

Seccomp будет немного сложно, так как код не может даже выделить память.

SELinux-это другой вариант, но я думаю, что это может быть больше работы, чем емкость.

вы можете использовать Qemu для быстрого тестирования заданий. Эта процедура ниже занимает менее 5 секунд на моем 5-летнем ноутбуке.

предположим, что студент должен разработать программу, которая принимает неподписанные ints, каждый на своей собственной строке, пока не появится строка с "-1". Затем программа должна усреднить все ints и вывести "Average: %f". Вот как вы могли бы протестировать программу полностью изолированы:

  1. во-первых, сделать root.bin от Jslinux, мы будем использовать это как userland (у него есть TCC C-компилятор):

    wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin

  2. мы хотим поместить представление студента в root.bin, Так что настроить устройство цикла:

    sudo losetup /dev/loop0 root.bin

    (вы можете использовать fuseext2 для этого тоже, но это не очень стабильно. Если он стабилизируется, вам не понадобится root для всего этого)

  3. создать пустой каталог:

    mkdir mountpoint

  4. Гора root.bin:

    sudo mount /dev/loop0 mountpoint

  5. введите смонтированную файловую систему:

    cd mountpoint.

  6. исправить права:

    sudo chown -R `whoami` .

  7. mkdir -p etc/init.d
  8. vi etc/init.d:

    #!/bin/sh
    cd /root
    echo READY 2>&1 > /dev/ttyS0
    tcc assignment.c 2>&1 > /dev/ttyS0
    ./a.out 2>&1 > /dev/ttyS0
    
  9. chmod +x etc/init.d/rcS

  10. скопируйте представление в виртуальную машину:

    cp ~/student_assignment.c root/assignment.c

  11. выход из виртуальной машины корень FS:

    cd ..

  12. sudo umount mountpoint
  13. теперь изображение готово, нам просто нужно, чтобы запустить его. Он будет компилировать и запускать представление после загрузки.
  14. mkfifo /tmp/guest_output
  15. откройте отдельный терминал и начните прослушивать гостевой вывод:

    dd if=/tmp/guest_output bs=1

  16. в другом терминале:

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (Я просто использовал ядро Ubuntu здесь, но многие ядра будут работа)

  17. когда гостевой вывод показывает "готов", вы можете отправить ключи к виртуальной машине из приглашения qemu. Например, чтобы проверить это задание, вы можете сделать

    (qemu) sendkey 1
    (qemu) sendkey 4
    (qemu) sendkey ret
    (qemu) sendkey 1
    (qemu) sendkey 0
    (qemu) sendkey ret
    (qemu) sendkey minus
    (qemu) sendkey 1
    (qemu) sendkey ret
    
  18. теперь Average = 12.000000 должен появиться на выходе трубы. Если это не так, студент потерпел неудачу.

  19. выйти из qemu:quit

программа, проходящая тест здесь:https://stackoverflow.com/a/14424295/309483. Просто используйте tcclib.h вместо stdio.h.

попробовать пользовательский режим Linux. Он имеет около 1% накладных расходов производительности для заданий с интенсивным ЦП, но может быть в 6 раз медленнее для заданий с интенсивным вводом-выводом.

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

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

когда речь заходит о санбоксинге на основе ptrace (strace) check-out:

" sydbox" песочницы и "pinktrace" библиотека программирования (это C99, но есть привязки к python и ruby, насколько я знаю).

собрали ссылки, связанные с темой:

http://www.diigo.com/user/wierzowiecki/sydbox

(извините, что не прямые ссылки, но пока недостаточно очков репутации)

seccomp и seccomp-bpf выполняют это с наименьшими усилиями:https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

Firejail является одним из наиболее полных инструментов для этого - он поддерживает seccomp, контейнеры файловой системы, возможности и многое другое:

https://firejail.wordpress.com/features-3/

эта библиотека должна хорошо служить вашей цели

http://sandbox.sourceforge.net

удачи!

Это тоже кажется многообещающим. Песочница файловой системы для Linux с использованием перехватов syscall.

https://github.com/adtac/fssb

хорошо, спасибо за все ответы, они мне очень помогли. Но я бы не предложил ни одного из них в качестве решения для человека, который задал первоначальный вопрос. Все упомянутые инструменты требуют большой работы с целью тестирования кода студентов в качестве преподавателя, репетитора, проф. лучшим способом в этом случае будет, на мой взгляд, virtualbox. Хорошо, он эмулирует полную x68-систему и не имеет никакого отношения к смыслу песочницы таким образом, но если я представлю своего учителя программирования, это будет лучше для него. Итак, "apt-get install virtualbox" на системах на базе debian, все остальные переходят на http://virtualbox.org/, создать виртуальную машину, добавить iso, нажмите кнопку Установить, подождите некоторое время и повезет. Это будет гораздо проще в использовании, как настроить пользовательский режим-linux или делать некоторые тяжелые strace вещи...

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

кроме того, если есть класс и 1% от него так же хорошо, как он мог бы делать такие вещи, не утомляйте их такими простыми задачами и дайте им некоторые большие, где они должны кодировать еще немного. Интегративное обучение лучше всего подходит для всех, поэтому не ретранслируйте старые тупиковые структуры...

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

используйте автономный компьютер для важных вещей и он-лайн компьютер для всех других вещей.

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

... на чем я остановился ... для всех остальных:

всего доброго !!