Настройка SELinux для Apache/Nginx в Unix/Linux

Настройка SELinux для Apache/Nginx в Unix/Linux

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

Многие из вас, уже сталкивались со следующей проблемой: При попытки использовать httpd сервер ( как пример) с включенным  SELinux на борту — апач не работал вообще ( и не спроста, т.к SELinux блокирует пакеты).

Сейчас я, воспроизведу проблему. Для начала, установлю httpd сервер ( на примере CentOS):

$ sudo yum install httpd -y

Или, проверим имеется ли он в ОС:

$ rpm -qa | grep httpd

Мой вывод такой:

httpd-2.2.15-54.el6.centos.x86_64
httpd-tools-2.2.15-54.el6.centos.x86_64

Видим что апач установлен. Проверим, работает ли SELinux, для этого служат несколько команд ( но речь не об этом), я возьму одну из них:

# getenforce
Enforcing

Это означает что он включен на сервере.

PS: вот чтиво как можно выключить SELinux:

Как отключить SELinux на CentOS

Запускаем апач:

$ service httpd restart

Запустить команду для просмотра процессов httpd:

# ps -eZ | grep httpd

unconfined_u:system_r:httpd_t:s0  3182 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3185 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3186 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3187 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3188 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3189 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3190 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3191 ?        00:00:00 httpd
unconfined_u:system_r:httpd_t:s0  3192 ?        00:00:00 httpd

Контекст SELinux, связанный с процессами httpd, является unconfined_u: system_r: httpd_t: s0. Вторая последняя часть контекста, httpd_t, является типом. Тип определяет домен для процессов и тип для файлов. В этом случае процессы httpd выполняются в домене httpd_t.

Политика SELinux определяет, как процессы, запущенные в ограниченных доменах, такие как httpd_t, взаимодействуют с файлами, другими процессами и системой в целом. Файлы должны быть помечены правильно, чтобы разрешить доступ httpd к ним. Например, httpd может читать файлы, типом httpd_sys_content_t, но не может их писать, даже если разрешения Linux разрешают доступ на запись. Например разрешение доступа к скрипта сети, позволяя httpd обращаться к файловым системам NFS и CIFS, а httpd разрешено выполнять сценарии Common Gateway Interface (CGI).

Когда вы настраиваете /etc/httpd/conf/httpd.conf для того, чтобы httpd прослушивал порт, отличный от TCP-порта 80, 443, 488, 8008, 8009 или 8443, команда semanage port должна использоваться для добавления нового номера порта Конфигурация политики SELinux. В следующем примере демонстрируется настройка httpd для прослушивания порта, который не определен в конфигурации SELinux для httpd.

Для начала, останавливаем апач:

# service httpd stop && service httpd status

При использовании semanage, у меня возникли проблемы, я получил следующую ошибку:

-bash: semanage: command not found

Исправление:
Исправляем «semanage: command not found» в Unix/Linux

Запустим команду для просмотра httpd портов SELinux ( которые дают возможность httpd, прослушивать порты):

# semanage port -l | grep -w http_port_t

http_port_t tcp 80, 443, 488, 8008, 8009, 8443

Видим что стандартные порты используются и работают. Но если нас интересует кастомный проброс определенного порта? Давайте рассмотрим пример. Редактируем конфиг апача:

$ sudo vim /etc/httpd/conf/httpd.conf

И настраиваем прослушивание порта ( предположим, что нужно прослушивать порт 54321)

Находим строку:

Listen 80

Или:

Listen 127.0.0.1:80

И приводим к виду:

Listen 127.0.0.1:12345

Или ( как я сделал себе)

Listen 12345

Запускаем службу апач:

# service httpd restart

И, получаем ошибку:

Starting httpd: (13)Permission denied: make_sock: could not bind to address 127.0.0.1:12345
no listening sockets available, shutting down
Unable to open logs
                                                           [FAILED]

Смотрим лог:

[root@localhost ~]# cat /var/log/messages| grep SELinux
Jan 19 19:29:22 localhost kernel: SELinux:  Initializing.
Jan 19 19:29:22 localhost kernel: dracut: Loading SELinux policy
Sep 22 16:31:28 localhost kernel: SELinux:  Initializing.
Sep 22 16:31:28 localhost kernel: dracut: Loading SELinux policy
Sep 22 16:36:52 localhost kernel: SELinux:  Initializing.
Sep 22 16:36:52 localhost kernel: dracut: Loading SELinux policy
Apr  1 23:37:57 localhost kernel: SELinux:  Initializing.
Apr  1 23:37:57 localhost kernel: dracut: Loading SELinux policy
Apr  4 10:16:06 localhost kernel: SELinux:  Initializing.
Apr  4 10:16:06 localhost kernel: dracut: Loading SELinux policy
Apr  4 11:04:50 localhost kernel: SELinux:  Initializing.
Apr  4 11:04:50 localhost kernel: dracut: Loading SELinux policy
Apr  5 01:07:48 localhost kernel: SELinux:  Initializing.
Apr  5 01:07:48 localhost kernel: dracut: Loading SELinux policy
Apr  5 01:46:00 localhost kernel: SELinux:  Initializing.
Apr  5 01:46:00 localhost kernel: dracut: Loading SELinux policy
[root@localhost ~]# 

И так, нужно разрешить 12345 порт в SELinux, чтобы чтобы httpd мог прослушивать его 12345, как используется в этом примере, требуется следующая команда:

# semanage port -a -t http_port_t -p tcp 12345

Теперь, пробуем запустить снова апач:

# service httpd restart
Starting httpd: [ OK ]

Теперь, когда SELinux был сконфигурирован так, чтобы httpd мог прослушивать нестандартный порт (в нашем примере TCP 12345), httpd успешно запускается на этом порту.
Чтобы доказать, что httpd прослушивает и передает на 12345 TCP-порт , откройте telnet-соединение с указанным портом и выполните команду HTTP GET, как показано ниже:

[root@localhost ~]# telnet localhost 12345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
HTTP/GET/1.1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Method Not Implemented</title>
</head><body>
<h1>Method Not Implemented</h1>
<p>HTTP/GET/1.1 to / not supported.<br />
</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at localhost.localdomain Port 80</address>
</body></html>
Connection closed by foreign host.
[root@localhost ~]# 

Как-то так!

Создание политик. 

Создайте политику, чтобы назначить httpd_sys_content_t контекст для /webapps папки, а также для всех дочерних каталогов и файлов:

# semanage fcontext -a -t http_sys_content_t "/webapps(/.*)?"

Создайте политику, чтобы назначить httpd_log_t контекст для ведения логов:

semanage fcontext -a -t httpd_log_t "/webapps/logs(/.*)?"

Создайте политику, чтобы назначить httpd_log_t контекст для использования кешей:

semanage fcontext -a -t httpd_cache_t "/webapps/cache(/.*)?"

Разрешаем чтение и запись (ReadWrite)

Apache теперь имеет право использовать наши собственные каталоги. Тем не менее, он не имеет доступа для чтения ко всему. Если у вашего приложения есть файлы или каталоги ( например WordPress), то можно создать правило и разрешить чтение-запись для определенных файлов\папок.

Следующему будет присвоен  readwrite для Apache и он сможет писать или изменять данные:

# semanage fcontext -a httpd_sys_rw_content_t "/webapps/app1/public_html/uploads(/.*)?"

Создайте политику, чтобы назначить  httpd_sys_rw_content_t контекст для файла с конфигурацией WordPress (wp-config.php):

# emanage fcontext -a httpd_sys_rw_content_t "/webapps/app1/public_html/wp-config.php"

Применяем SELinux политики

Наши политики созданы и готовы к применению. Чтобы все проделанные действия заработали, необходимо перечитать политики самого SELinux:

# restorecon -Rv /webapps

Все работает, а я завершаю свою статью «Настройка SELinux для Apache/Nginx в Unix/Linux».

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *