Как я могу использовать SELinux для ограничения PHP-скриптов?

Я хочу разделить различные приложения PHP на моем веб-сервере SL6.4 (перестройка RHEL 6.4), чтобы они не могли получить доступ к данным друг друга. Кажется, что SELinux мог бы сделать это, но я не уверен в деталях. Мой вопрос состоит из двух частей:

  1. Как SElinux управляет сценариями PHP, работающими в процессе Apache, с помощью mod_php? Процесс каким-то образом входит в контекст сценария при запуске сценария PHP или это работает только тогда, когда сценарии выполняются вне процесса через CGI или FastCGI? Если он переходит в контекст скрипта для запуска скрипта PHP, что мешает ошибке PHP вернуться к основному контексту httpd? Если мне нужен альтернативный метод развертывания PHP, это было бы полезно знать.
  2. Как я могу отделить скрипты / приложения, чтобы, например, TinyTinyRSS не мог получить доступ к вещам, принадлежащим OpenCloud? Похоже, я должен быть в состоянии сделать это, отключив httpd_unified и предоставление отдельных httpd_ttrss_* а также httpd_opencloud_* наборы контекстов, параллельных httpd_user_foo а также httpd_sys_foo, Мне даже может быть достаточно использовать различие sys / user без новых контекстов, учитывая количество приложений, которые я могу использовать. Но я не нашел много документации о том, что именно означает отключение httpd_unified Есть, или как настроить различные HTTP-контексты. Особенно с PHP скриптами, запускаемыми через mod_php,

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

Если попытка сделать это разделение просто с помощью SELinux не имеет смысла, и мне нужно раскрутить отдельные httpds в разных контекстах или, возможно, даже в контейнерах LXC, это также будет полезным ответом.

1 ответ

Лучший способ достичь этого уровня разделения - не использовать переходы типа, а переходы категории / MCS. Это действует немного как svirt реализация в libvirt KVM материал.

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

В любом случае вы можете пересобрать пакет из исходников fedora. Я сделал это на машине Fedora, но вы можете просто загрузить тот же пакет с зеркала. Я использовал F16 в качестве базы, поскольку он работает httpd-2.2,

yumdownloader --source mod_selinux --releaserver=16
...
mod_selinux-2.2.2454-3.fc15.src.rpm                        |  23 kB   00:00

Затем, после загрузки, перестройте на свой ящик EL6.

rpmbuild --rebuild mod_selinux-2.2.2454-3.fc15.src.rpm
...
Wrote: /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

Наконец, установите модуль.

rpm -i /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

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

Файл для этого модуля установлен в /etc/httpd/conf.d/mod_selinux.conf,

Первым этапом этого процесса является увеличение количества категорий, в которых работает основной процесс httpd, чтобы он мог создавать дочерние потоки, которые охватывают правильный диапазон. В файле изменения:

selinuxServerDomain     *:s0

к

selinuxServerDomain     *:s0-s0:c0.c1023

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

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host1
    ServerName host1.virtual
    selinuxDomainVal *:s0:c0
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host2
    ServerName host2.virtual
    selinuxDomainVal *:s0:c1
</VirtualHost>

Затем, в корне документа для каждого хоста, пометьте их корни документа в той же категории, что и в конфигурации httpd.

chcon -R -l s0:c0 /var/www/vhosts/host1
chcon -R -l s0:c1 /var/www/vhosts/host2

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

semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c0 '/var/www/vhosts/host1(/.*)?'
semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c1 '/var/www/vhosts/host2(/.*)?'

И это все! Невозможно оставить свой корень документа и перейти к изучению других.

Я знаю, что этому вопросу 7 лет, однако ответ на него @MatthewIfe выше был полезен, но потребовал несколько дополнительных шагов. Мы используем CentOS8, который до сих пор не включает mod_selinux прямо из коробки, поэтому приведенный выше ответ был идеальным для его установки.

Однако после установки и после правильной настройки apache не прошел тесты AVC и не запускался. Ошибки, доступные в /var/log/httpd/error.log, /var/log/messages, и /var/log/audit/audit.log не очень помогли.

В конце концов, мне пришлось установить две дополнительные утилиты, которые позволили мне устранять ошибки selinux AVC, что указывало на то, что мне пришлось создать настраиваемую политику, чтобы разрешить httpd сервисный доступ к setcurrent команда в selinux.

Вы можете найти решение здесь: Разделение привилегий Apache vhost с использованием контекстов SELinux в CentOS8

Надеюсь, что это поможет кому-нибудь еще наткнуться на это.

Другие вопросы по тегам