SELinux на веб-сервере

Введение

Когда-то, настраивая nginx+php-fpm, я просто делал setenforce 0 или правил /etc/selinux/config, перманентно отключая selinux на сервере

/etc/selinux/config

Теперь, наконец разобравшись, я понял, что никогда больше не буду выключать selinux

Почему?

Вот есть у вас процесс php-fpm, работающий от пользователя nginx и вы изменили владельца папки проекта тоже на nginx,

чтобы код, выполняемый с помощью php-fpm, мог изменять содержимое папки проекта — например, писать в папку cache или заливать файлы в папку upload. Так в чём проблема?

Проблема в том, что без selinux пользователь nginx и запущенный от его имени процесс php-fpm сможет выполнять действия над файлами и папками согласно заданным стандартным rwx разрешениям. То есть то, что в системе открыто на чтение для всех, можно прочитать и через, скажем, залитый php-шелл.

Если же selinux будет включён, то помимо стандартных разрешений будут проверяться разрешения на доступ домена, в которым работает процесс (в случае с php-fpm в CentOS7 это httpd_t), к контексту файлов/директорий, заданных для них. И что это даст?

А ничего это не даст, потому что домен httpd_t включает в себя правила для домена nsswitch_domain

seinfo -thttpd_t -x

из-за чего, процесс php-fpm сможет читать, скажем, /etc/passwd, контекст которого passwd_file_t

ll -Z /etc/passwd

sesearch --allow --source httpd_t --target passwd_file_t

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