#linux #security #cgi #sandbox
#linux #Безопасность #cgi #песочница
Вопрос:
Я пишу cgi-программы для своих веб-сайтов (все они размещены с помощью одной службы lighttpd). Программы считывают каталоги и файлы во вложенных папках, в которых они находятся. Они запускаются с использованием идентификатора пользователя веб-сервера.
Я хотел бы убедиться, что не произойдет никаких сбоев, которые могли бы привести к тому, что мои программы будут читать за пределами их предполагаемой рабочей области. Я представляю себе добавление строки где-нибудь во время выполнения в верхней части моих программ cgi, которая выглядит так:
restrict_io(".");
все, что после этой строки, приведет к ошибкам доступа, если они будут делать что-то странное, например, пытаться запускать произвольные вещи из /usr/bin или открывать файлы в ../other_website/stuff .
Есть какое-нибудь простое решение? Я просмотрел различные решения, но все они, похоже, требуют больших инвестиций с моей стороны, чтобы понять, действительно ли они могут делать то, что я хочу.
в документе chroot (2) говорится, что «он не предназначен для использования в каких-либо целях безопасности, ни для полной изолированности процесса, ни для ограничения системных вызовов файловой системы». Ему также нужны возможности или root, которых у веб-пользователя нет. Это также может быть слишком сложным, поскольку я подозреваю, что вам нужно тщательно подготовить новый «/».
документ seccomp (2) довольно длинный и утомительный для чтения. Похоже, что это многое делает, но неясно, может ли он делать то, что я хочу.
pledge (2) — это только BSD, а мой сервер представляет собой разновидность Linux, и я хочу сохранить его таким, потому что я использую эту машину не только для веб-хостинга. Опять же, я не уверен, что pledge делает то, что я хочу.
LXC, еще не читал об этом.
Docker выглядит как продукт какой-то компании. Я не читал, если это бесплатно, с открытым исходным кодом.
Если вы еще не читали между строк, решение C было бы лучшим, но если не C, не стесняйтесь тоже внести свой ответ. Фрагмент кода стоит тысячи слов.
Ответ №1:
Я обнаружил, что AppArmor (часть ядра Linux) делает именно то, что я хочу.
Вы вызываете aa_change_profile(const char * profile) в своем коде. Профиль сначала регистрируется в CLI util apparmor_parser как root. Возможно, вам потребуется включить apparmor с параметрами ядра и запустить службу:
linux ... apparmor=1 security=apparmor
sudo systemctl включить apparmor
Пример cgi.armor:
profile restricted_cgi {
deny network,
/home/pi/website1/** r,
}
sudo apparmor_parser — cgi.armor
Пример my_program.c, скомпилированный с помощью -lapparmor:
#include <sys/apparmor.h>
...
int armor = aa_change_profile("restricted_cgi");
if(armor) {
printf("Armor error: %sn", strerror(errno));
return 1;
}