Я работаю под управлением Fedora 31 (ядро Linux 5.4.13, Nginx 1.16.1, fcgiwrap 1.1.0) с SELinux в принудительном режиме (политика: targeted 3.14.4-44.fc31).
На моем ящике размещен сервер, работающий под управлением Nginx. Часть из них основана на скриптах Perl. Nginx настроен на передачу выполнения CGI через FastCGI с fcgiwrap (подключение через сокет Unix /var/run/fcgiwrap/[email protected]).
Все было протестировано в режиме «Permissive». Затем оно было переведено в режим «Enforcing». Я получил кучу AVC, которые можно было обработать либо изменением булевых значений, либо созданием пользовательских политик, как предлагалось в комментариях аудита.
Однако один AVC не может быть решен. Журнал сообщает:
type=AVC msg=audit(1580046727.459:548): avc: denied { connectto } for pid=4619 comm="nginx" path="/run/fcgiwrap/fcgiwrap-0.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:unconfined_service_t:s0 tclass=unix_stream_socket permissive=0
Пользовательская политика содержит следующее:
module nginx 1.0;
require {
type httpd_t;
type soundd_port_t;
type http_port_t;
type tor_port_t;
type unconfined_service_t;
type httpd_user_content_t;
class tcp_socket { name_bind name_connect };
class file { getattr read };
class unix_stream_socket connectto;
}
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t http_port_t:tcp_socket name_connect;
#!!!! This avc is allowed in the current policy
allow httpd_t httpd_user_content_t:file { getattr read };
allow httpd_t soundd_port_t:tcp_socket name_bind;
#!!!! This avc is allowed in the current policy
allow httpd_t tor_port_t:tcp_socket name_connect;
allow httpd_t unconfined_service_t:unix_stream_socket connectto;
Как видно из автоматически сгенерированных комментариев, эта пользовательская политика не имеет никакого эффекта, поскольку она уже включена в глобальную политику.
После добавления этого модуля ничего не меняется. Я все еще получаю оповещения AVC, предлагающие то же самое исправление.
Если я вернусь к «Разрешающему» режиму или установлю доменhttpdв разрешающем режиме выполняются CGI-скрипты, и я получаю ожидаемый вывод.
ls -Z /var/run/fcgiwrap/fcgiwrap-0.sock
возвращает:
system_u:object_r:httpd_var_run_t:s0 /var/run/fcgiwrap/fcgiwrap-0.sock
Мне не удалось найти, где httpd_var_run_t
использовалась метка и контролировался ли доступ к этому типу файла логическим значением (я совсем новичок в настройке SELinux).
Как предоставить доступ к сокету в режиме «Enforcing»?
ИЗМЕНИТЬ 2020-01-27
Похоже, в модуле уже есть правило перехода.апачдля:
allow httpd_t unconfined_service_t:unix_stream_socket connectto;
но он неэффективен или другой модуль (какой?) блокирует его. Временный способ обойти это поставить доменhttpdв разрешительном режиме, но мне это не нравится, потому что теперь любому веб-серверу разрешено делать все, что угодно.
Есть идеи, почему в переходе отказано?
решение1
Я не проверял и не тестировал это должным образом — на самом деле, я почти уверен, что само по себе это не сработает.
Я предполагаю, что создание пути /var/run/fcgiwrap
имеет тип каталога unconfined_service_t
, но я не уверен, так ли это на самом деле.
Однако это должно помочь вам с чего-то начать.
policy_module(nginx_local, 31.0.0)
require {
type httpd_t;
type unconfined_service_t;
}
stream_connect_pattern(httpd_t, unconfined_service_t, unconfined_service_t, unconfined_service_t)
Что касается сетевых проблем, вы можете просто включить булеву переменную, httpd_can_network_connect
которая должна отключить некоторые из них. Если только вы не хотите быть конкретными.
В лучшем и идеальном случае было бы идеально создать политику, специфичную для ваших процессов fcgi, но это гораздо более сложная задача, поэтому заставить nginx просто взаимодействовать с неограниченными службами — хотя это и менее безопасно — гораздо проще.