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

110

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

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

Фрэнк
источник
Это похоже на одну программу на C, которую нужно запускать 1 раз в течение 5 минут, или что-то, что вам нужно запускать постоянно?
bwawok
Это будет небольшая программа, которая загружается и на ней выполняются модульные тесты. Так что программа будет недолгой.
Фрэнк
Какой дистрибутив используется в системе? В некоторых дистрибутивах есть готовые инструменты для песочницы. Есть ли в вашей системе какая-либо модель безопасности, такая как SELinux или AppArmor?
thkala
Я использую Fedora 13. Я изучаю политику SELinux Sandbox. Мне интересно, какие еще варианты существуют.
Фрэнк
6
Аналогичные Qs по процессам песочницы / заключения в тюрьму в Linux или Unix: * unix.stackexchange.com/q/6433/4319 * stackoverflow.com/q/3859710/94687 * stackoverflow.com/q/4410447/94687 * stackoverflow.com/q / 1019707/94687
imz - Иван Захарящев

Ответы:

47

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

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

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

РЕДАКТИРОВАТЬ:

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

РЕДАКТИРОВАТЬ 2:

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

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

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

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

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

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

thkala
источник
systrace работал у меня для простых программ, но застрял на неопределенное время, когда GNU as (1) запускался GCC. Так что я отказался от этого. Это нефиксированная ошибка в Systrace: forum.soft32.com/linux/...
Очки
Есть ли способ гарантировать, что разделяемая память, очереди сообщений и семафоры не используются совместно изолированными процессами?
daveagp
1
Ссылка на systrace не работает.
Collin
2
А что насчет Firejail? Вам больше не нужно поддерживать fs, используя его.
m3nda
18

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

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

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

Джастин Кормак
источник
6

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

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

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

    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. Когда выходные данные гостя показывают «READY», вы можете отправить ключи виртуальной машине из командной строки 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.

Янус Троельсен
источник
5

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

PTS
источник
4

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

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

Federico
источник
Это отличный ответ, он действительно заслуживает большего количества голосов, учитывая, что firejail активно поддерживается с отличной документацией, включает в себя большинство, если не все другие ответы, и разработан так, чтобы быть относительно простым в использовании.
Джефф Хайкин
3

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

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

Лоран Паренто
источник
2
Я не знаю насчет OP, но запуск виртуальной машины для каждой тестовой программы во многих случаях был бы неприемлем. В моей среде (я ТА) может быть до 200 студентов, представляющих 10-12 программ каждая в течение 2-часового периода. Ни одна программа не запускается более 10 секунд процессорного времени, но когда количество отправлений накапливается, мы получаем время выполнения 15 минут или больше. Введение виртуальной машины для каждой программы увеличило бы время ЦП до 60 секунд или более на программу, и я вообще не хочу думать о времени оборота. Может быть, виртуальная машина на сеанс, но мы никак не сможем сделать эту программу ...
thkala
@thkala Это хороший момент. Мне нравится идея QEMU, но запускать виртуальную машину для каждой отправки - не лучший вариант.
Фрэнк
Что ж, в этом случае все время должна работать одна и та же виртуальная машина.
Laurent Parenteau
Не могли бы вы сделать что-нибудь, используя снимок виртуальной машины, которая полностью загружена и готова к компиляции и запуску кода? К вашему сведению, виртуальные машины не обязательно защищены от пирсинга. Вы также можете создать аппаратную версию этого - небольшую систему, которая загружает образ резюме с носителя только для чтения или по сети и обеспечивает вывод через сеть или последовательный порт, а затем перезагружается для следующего. Были некоторые улучшения в быстрой загрузке, благодаря которым Linux загружается за несколько секунд.
Крис Стрэттон,
@thkala: Это означает, что вам потребуется менее 3 секунд на отправку, если вы запускаете их последовательно. Подход, который я опубликовал, вероятно, занимает около 3 секунд на современной машине (серийно). Если вы распараллелируете (что вы тоже можете), это будет достаточно быстро.
Янус Троелсен
3

Когда речь идет о sanboxing на основе проверки ptrace (strace):

« Sydbox » песочница и « pinktrace » программирование библиотеки (это C99 , но есть привязка к питона и рубиновый, насколько я знаю).

Собраны ссылки по теме:

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

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

Гжегож Вежовецкий
источник
1

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

http://sandbox.sourceforge.net

Удачи!

thoaionline
источник
8
Кажется, что это не поддерживается активно. Также, похоже, требуется патч ядра Linux, что сделало бы его практически бесполезным, учитывая, что его последняя версия датируется 2003 годом.
thkala
1

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

https://github.com/adtac/fssb

mauron85
источник
-1

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

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

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

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

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

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

... где я был ... для всех остальных:

удачного взлома !!

rohySeentrusted
источник