Назад | Перейти на главную страницу

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

Я хочу разделить различные PHP-приложения на моем веб-сервере SL6.4 (RHEL 6.4 rebuild), чтобы они не могли получить доступ к данным друг друга. Кажется, что 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, это также будет полезным ответом.

Лучший способ достичь этого уровня разделения - не использовать переходы типов, а переходы категорий / 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

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