Nginx и SELinux при обновлении до RHEL 6.6/CentOS 6.6

selinux

selinux

При обновлении рабочей системы до Red Hat Enterprise Linux 6.6 или CentOS 6.6, правила доступа SELinux для nginx меняют структуру. Новые правила могут не повлиять на nginx со стандартным конфигом, однако различные пользовательские конфигурации могут быть заблокированы и придется вручную прописывать разрешения для них.

Далее будут описаны некоторые проблемы, с которыми можно столкнуться при обновлении до RHEL/CentOS 6.6 и рекомендации по их решению.

Обзор SELinux

На серверах RHEL и CentOS SELinux включен по-умолчанию. Каждый объект операционной системы (процесс, файловый дескриптор, файл и т.д.) связан с контекстом SELinux, который определяет права доступа и возможные операции с объектом. При обновлении до версии операционной системы 6.6, nginx связывается с контекстом httpd_t:

# ps auZ | grep nginx
unconfined_u:system_r:httpd_t:s0        3234 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
unconfined_u:system_r:httpd_t:s0        3236 ?        Ss     0:00 nginx: worker process

Контекст httpd_t разрешает nginx прослушивать основные веб-порты, получать доступ к конфигурационным файлам в каталоге /etc/nginx и стандартному расположению корневого каталога документов веб /usr/share/nginx. Он не разрешает многие другие операции, такие как проксирование трафика и взаимодействие с другими процессами через сокеты.

Режимы работы SELinux

SELinux может быть запущен в одном из трех режимов работы: enforcing, permissive или disabled. В том случае, если вы делаете изменения конфигурации, которые могут идти в разрез с текущими правилами безопасности, можно перевести SELinux из режима enforcing в permissive, лучше это делать на тестовом окружении. В режиме permissive, SELinux разрешает все операции, но логирует все операции, которые были бы запрещены в режиме enforcing.

Добавление контекста httpd_t в список permissive:

# semanage permissive -a httpd_t

Удаление контекста httpd_t из списка permissive:

# semanage permissive -d httpd_t

Переключение глобального режима работы SELinux

Активация глобального режима permissive:

# setenforce 0

Активация глобального режима работы enforcing:

# setenforce 1

Исключения SELinux

В режиме permissive, все исключения безопасности логируются в /var/log/audit/audit.log. При возникновении проблем с nginx в режиме enforcing, можно переключиться в режим permissive, и откорректировать правила безопасности, основываясь на логах режима permissive.

Пример 1. Подключение прокси запрещено

Конфигурация SELinux по-умолчанию не разрешает nginx подключение к удаленному веб-серверу, fastCGI или другому серверу.

Что мы видим в логе audit.log:

type=AVC msg=audit(1415714880.156:29): avc: denied { name_connect } for pid=1349 comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 success=no exit=-115 a0=b a1=16125f8 a2=10 a3=7fffc2bab440 items=0 ppid=1347 pid=1349 auid=1000 uid=497 gid=496 euid=497 suid=497 fsuid=497 egid=496 sgid=496 fsgid=496 tty=(none) ses=1 comm="nginx" exe="/usr/sbin/nginx" subj=unconfined_u:system_r:httpd_t:s0 key=(null)

Подробности о сообщении 1415714880.156:29 можно узнать с помощью audit2why:

# grep 1415714880.156:29 /var/log/audit/audit.log | audit2why

type=AVC msg=audit(1415714880.156:29): avc: denied { name_connect } for pid=1349 comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket

Was caused by:
One of the following booleans was set incorrectly.
Description:
Allow httpd to act as a relay

Allow access by executing:
# setsebool -P httpd_can_network_relay 1
Description:
Allow HTTPD scripts and modules to connect to the network using TCP.

Предоставляем доступ:

# setsebool -P httpd_can_network_connect 1

audit2why рекомендует настройки для исправления данного запрета. Разрешить данное действие можно как на постоянной основе (-P), так и временно.

Что такое логические параметры

Разобраться в этом вопросе и лучше понять значение логических параметров поможет пакет setools.

Установим setools:

# yum -y install setools

Параметр httpd_can_network_relay

# sesearch -A -s httpd_t -b httpd_can_network_relay
Found 10 semantic av rules:
allow httpd_t gopher_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_client_packet_t : packet { send recv } ;
allow httpd_t ftp_port_t : tcp_socket name_connect ;
allow httpd_t ftp_client_packet_t : packet { send recv } ;
allow httpd_t http_client_packet_t : packet { send recv } ;
allow httpd_t squid_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_port_t : tcp_socket name_connect ;
allow httpd_t http_port_t : tcp_socket name_connect ;
allow httpd_t gopher_client_packet_t : packet { send recv } ;
allow httpd_t memcache_port_t : tcp_socket name_connect ;

Очевидно, что can_network_relay разрешает подключения на различные порты, включая http_port_t:

# semanage port -l | grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

Добавить порт к правилу не сложно:

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

Если порт уже включен в другое правило:

# semanage port -a -t http_port_t -p tcp 8080
/usr/sbin/semanage: Port tcp/8080 already defined
# semanage port -l | grep 8080
http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010

не нужно его переопределять, так как это может повлиять на другие сервисы.

Параметр httpd_can_network_connect

# sesearch -A -s httpd_t -b httpd_can_network_connect
Found 1 semantic av rules:
allow httpd_t port_type : tcp_socket name_connect ;

httpd_can_network_connect разрешает httpd_t подключение ко всем типам tcp сокетов, имеющим атрибут port_type. Их перечень можно получить следующей командой:

# seinfo -aport_type -x

Пример 2. Доступ к файлу запрещен

Конфигурация SELinux по-умолчанию разрешает доступ nginx только к файлам в определенных (традиционных) каталогах.

Что мы видим в логе audit.log:

type=AVC msg=audit(1415715270.766:31): avc: denied { getattr } for pid=1380 comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file

Результат утилиты audit2why:

# grep 1415715270.766:31 /var/log/audit/audit.log | audit2why

type=AVC msg=audit(1415715270.766:31): avc: denied { getattr } for pid=1380 comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file

Was caused by:
Missing type enforcement (TE) allow rule.

You can use audit2allow to generate a loadable module to allow this access.

В случае с запретом доступа к файлам есть два выхода:

Первый: изменение атрибута файла

Изменение атрибута файла так, что бы httpd_t смог получить к нему доступ:

# chcon -v --type=httpd_sys_content_t /www/t.txt

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

# semanage fcontext -a -t httpd_sys_content_t /www/t.txt
# restorecon -v /www/t.txt

Так же, можно изменять атрибуты групп файлов:

# semanage fcontext -a -t httpd_sys_content_t /www(/.*)?
# restorecon -Rv /www

Второй: добавление разрешений для httpd_t

Расширенные разрешения httpd_t для доступа к разным файлам:

# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te
# cat nginx.te

module nginx 1.0;

require {
type httpd_t;
type default_t;
type http_cache_port_t;
class tcp_socket name_connect;
class file { read getattr open };
}

#============= httpd_t ==============
allow httpd_t default_t:file { read getattr open };

#!!!! This avc can be allowed using one of the these booleans:
# httpd_can_network_relay, httpd_can_network_connect
allow httpd_t http_cache_port_t:tcp_socket name_connect;

Создаем готовое правило используя ключ -M:

# grep nginx /var/log/audit/audit.log | audit2allow -M nginx

Загружаем его semodule -i и проверяем результат с ключом -l:

# semodule -i nginx.pp
# semodule -l | grep nginx
nginx 1.0

Эти изменения будут актуальны и после перезагрузки системы.

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

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