Устранение неполадок, связанных с SELinux
Если вы планируете включить SELinux в системах, где он ранее был отключён, или если вы запускаете службу в нестандартной конфигурации, вам может потребоваться устранение неполадок в ситуациях, потенциально блокируемых SELinux. Обратите внимание, что в большинстве случаев отказы SELinux являются признаками неправильной настройки.
Выявление отказов SELinux
Выполняйте только необходимые шаги из этой процедуры; в большинстве случаев вам нужно выполнить только шаг 1.
Процедура
-
Когда ваш сценарий блокируется SELinux, файл
/var/log/audit/audit.log— это первое место, где следует искать дополнительную информацию об отказе. Для запроса журналов Audit используйте инструментausearch. Поскольку решения SELinux, такие как разрешение или запрет доступа, кэшируются и этот кэш известен как Access Vector Cache (AVC), используйте значенияAVCиUSER_AVCдля параметра типа сообщения, например:$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recentЕсли совпадений нет, проверьте, запущен ли демон Audit. Если нет, повторите сценарий с отказом после запуска auditd и снова проверьте журнал Audit.
-
Если auditd запущен, но в выводе ausearch нет совпадений, проверьте сообщения, предоставляемые журналом systemd:
$ sudo journalctl -t setroubleshoot -
Если SELinux активен и демон Audit не запущен в вашей системе, найдите определённые сообщения SELinux в выводе команды dmesg:
$ sudo dmesg | grep -i -e type=1300 -e type=1400 -
Даже после предыдущих трёх проверок всё ещё возможно, что вы ничего не нашли. В этом случае отказы AVC могут быть заглушены из-за правил
dontaudit.Чтобы временно отключить правила
dontaudit, позволяя регистрировать все отказы:$ sudo semodule -DBПосле повторного запуска сценария с отказом и поиска сообщений об отказах с помощью предыдущих шагов следующая команда снова включает правила
dontauditв политике:$ sudo semodule -B -
Если вы применили все четыре предыдущих шага, а проблема всё ещё остаётся невыявленной, подумайте, действительно ли SELinux блокирует ваш сценарий:
-
Переключитесь в разрешающий режим:
$ sudo setenforce 0 $ getenforce Permissive -
Повторите ваш сценарий.
-
Если проблема всё ещё возникает, ваш сценарий блокирует что-то другое, а не SELinux.
Анализ сообщений об отказах SELinux
После выявления того, что SELinux блокирует ваш сценарий, вам может потребоваться проанализировать первопричину, прежде чем выбрать исправление.
Предварительные требования
-
Пакеты
policycoreutils-python-utilsиsetroubleshoot-serverустановлены в вашей системе.
Процедура
-
Выведите более подробную информацию о зарегистрированном отказе с помощью команды
sealert, например:$ sealert -l "*" SELinux is preventing /usr/bin/passwd from write access on the file /root/test. ***** Plugin leaks (86.2 confidence) suggests ***************************** If you want to ignore passwd trying to write access the test file, because you believe it should not need this access. Then you should report this as a bug. You can generate a local policy module to dontaudit this access. Do # ausearch -x /usr/bin/passwd --raw | audit2allow -D -M my-passwd # semodule -X 300 -i my-passwd.pp ***** Plugin catchall (14.7 confidence) suggests ************************** ... Raw Audit Messages type=AVC msg=audit(1553609555.619:127): avc: denied { write } for pid=4097 comm="passwd" path="/root/test" dev="dm-0" ino=17142697 scontext=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0 .. Hash: passwd,passwd_t,admin_home_t,file,write -
Если вывод, полученный на предыдущем шаге, не содержит чётких рекомендаций:
-
Включите аудит полных путей, чтобы видеть полные пути к объектам, к которым произошёл доступ, и сделать видимыми дополнительные поля событий Linux Audit:
$ sudo auditctl -w /etc/shadow -p w -k shadow-write -
Очистите кэш
setroubleshoot:$ sudo rm -f /var/lib/setroubleshoot/setroubleshoot.xml -
Воспроизведите проблему.
-
Повторите шаг 1.
После завершения процесса отключите аудит полных путей:
$ sudo auditctl -W /etc/shadow -p w -k shadow-write
-
-
Если
sealertвозвращает только предложенияcatchallили предлагает добавить новое правило с помощью инструментаaudit2allow, сопоставьте свою проблему с примерами, перечисленными и объяснёнными в разделе об отказах SELinux в журнале Audit.
Дополнительные ресурсы
-
страница руководства
sealert(8)
Исправление проанализированных отказов SELinux
В большинстве случаев рекомендации, предоставляемые инструментом sealert, дают вам правильное руководство о том, как исправить проблемы, связанные с политикой SELinux. Информацию о том, как использовать sealert для анализа отказов SELinux, см. в разделе «Анализ сообщений об отказах SELinux».
Будьте осторожны, когда инструмент предлагает использовать audit2allow для изменений конфигурации. Не следует использовать audit2allow для генерации локального модуля политики в качестве первого варианта, когда вы видите отказ SELinux. Устранение неполадок следует начинать с проверки, нет ли проблемы с маркировкой. Второй по частоте случай — вы изменили конфигурацию процесса и забыли сообщить об этом SELinux.
Проблемы с маркировкой
Распространённой причиной проблем с маркировкой является использование нестандартного каталога для службы. Например, вместо использования /var/www/html/ для веб-сайта администратор может захотеть использовать /srv/myweb/. В Red Hat Enterprise Linux каталог /srv помечен типом var_t. Файлы и каталоги, созданные в /srv, наследуют этот тип. Кроме того, вновь созданные объекты в каталогах верхнего уровня, таких как /myserver, могут быть помечены типом default_t. SELinux запрещает веб-серверу Apache HTTP Server (httpd) доступ к обоим этим типам. Чтобы разрешить доступ, SELinux должен знать, что файлы в /srv/myweb/ должны быть доступны для httpd:
$ sudo semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
Эта команда semanage добавляет контекст для каталога /srv/myweb/ и всех файлов и каталогов под ним в конфигурацию файловых контекстов SELinux. Утилита semanage не изменяет контекст. От имени root используйте утилиту restorecon, чтобы применить изменения:
$ sudo restorecon -R -v /srv/myweb
Неправильный контекст
Утилита matchpathcon проверяет контекст пути к файлу и сравнивает его с меткой по умолчанию для этого пути. Следующий пример демонстрирует использование matchpathcon для каталога, содержащего неправильно помеченные файлы:
$ matchpathcon -V /var/www/html/*
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
В этом примере файлы index.html и page1.html помечены типом user_home_t. Этот тип используется для файлов в домашних каталогах пользователей. Использование команды mv для перемещения файлов из вашего домашнего каталога может привести к тому, что файлы будут помечены типом user_home_t. Этот тип не должен существовать вне домашних каталогов. Используйте утилиту restorecon, чтобы восстановить такие файлы до их правильного типа:
$ sudo restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
Чтобы восстановить контекст для всех файлов в каталоге, используйте параметр -R:
$ sudo restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
Изолированные приложения, настроенные нестандартными способами
Службы можно запускать различными способами. Чтобы учесть это, вам нужно указать, как вы запускаете свои службы. Это можно сделать с помощью логических переменных SELinux (booleans), которые позволяют изменять части политики SELinux во время выполнения. Это позволяет вносить изменения, например, разрешать службам доступ к томам NFS, без перезагрузки или перекомпиляции политики SELinux. Кроме того, запуск служб на портах, отличных от портов по умолчанию, требует обновления конфигурации политики с помощью команды semanage.
Например, чтобы разрешить Apache HTTP Server взаимодействовать с MariaDB, включите логическую переменную httpd_can_network_connect_db:
$ sudo setsebool -P httpd_can_network_connect_db on
Обратите внимание, что параметр -P делает настройку постоянной между перезагрузками системы.
Если доступ запрещён для конкретной службы, используйте утилиты getsebool и grep, чтобы узнать, доступны ли какие-либо логические переменные для разрешения доступа. Например, используйте команду getsebool -a | grep ftp для поиска логических переменных, связанных с FTP:
$ getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off
ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
Чтобы получить список логических переменных и узнать, включены они или отключены, используйте команду getsebool -a. Чтобы получить список логических переменных с их значениями и узнать, включены они или отключены, установите пакет selinux-policy-devel и используйте команду semanage boolean -l от имени root.
*Номера портов
В зависимости от конфигурации политики, службам может быть разрешено работать только на определённых номерах портов. Попытка изменить порт, на котором работает служба, без изменения политики может привести к тому, что служба не запустится. Например, выполните команду semanage port -l | grep http от имени root, чтобы вывести список портов, связанных с http:
$ sudo semanage port -l | grep http
http_cache_port_t tcp 3128, 8080, 8118
http_cache_port_t udp 3130
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
Тип порта http_port_t определяет порты, которые может прослушивать Apache HTTP Server, в данном случае это TCP-порты 80, 443, 488, 8008, 8009 и 8443. Если администратор настроит httpd.conf так, чтобы httpd прослушивал порт 9876 (Listen 9876), но политика не будет обновлена, чтобы отразить это, следующая команда завершится с ошибкой:
$ sudo systemctl start httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
$ sudo systemctl status httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago
Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS)
Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Сообщение об отказе SELinux, подобное следующему, записывается в /var/log/audit/audit.log:
type=AVC msg=audit(1225948455.061:294): avc: denied { name_bind } for pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
Чтобы разрешить httpd прослушивать порт, который не указан для типа порта http_port_t, используйте команду semanage port, чтобы назначить порту другую метку:
$ sudo semanage port -a -t http_port_t -p tcp 9876
Параметр -a добавляет новую запись; параметр -t определяет тип; параметр -p определяет протокол. Последний аргумент — номер порта, который нужно добавить.
Особые случаи, развивающиеся или сломанные приложения и скомпрометированные системы
Приложения могут содержать ошибки, из-за которых SELinux запрещает доступ. Кроме того, правила SELinux развиваются — SELinux может не встречать приложение, работающее определённым образом, что может привести к запрету доступа, даже если приложение работает как ожидалось. Например, если выпущена новая версия PostgreSQL, она может выполнять действия, которые текущая политика не учитывает, что приводит к запрету доступа, даже если доступ должен быть разрешён.
В таких ситуациях после запрета доступа используйте утилиту audit2allow, чтобы создать пользовательский модуль политики для разрешения доступа. Вы можете сообщить об отсутствующих правилах в политике SELinux в Red Hat Bugzilla. Для Red Hat Enterprise Linux 8 создавайте ошибки для продукта Red Hat Enterprise Linux 8 и выбирайте компонент selinux-policy. Включайте в такие отчёты об ошибках вывод команд audit2allow -w -a и audit2allow -a.
Если приложение запрашивает значительные привилегии безопасности, это может быть признаком того, что приложение скомпрометировано. Используйте инструменты обнаружения вторжений, чтобы исследовать такое подозрительное поведение.
Solution Engine на портале Red Hat Customer Portal также может предоставить руководство в виде статьи, содержащей возможное решение той же или очень похожей проблемы, с которой вы столкнулись. Выберите соответствующий продукт и версию и используйте ключевые слова, связанные с SELinux, такие как selinux или avc, вместе с именем заблокированной службы или приложения, например: selinux samba.
Отказы SELinux в журнале audit
Система Linux Audit по умолчанию сохраняет записи журнала в файле /var/log/audit/audit.log.
Чтобы вывести только записи, связанные с SELinux, используйте команду ausearch с параметром типа сообщения, установленным как минимум в AVC и AVC_USER, например:
$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR
Запись об отказе SELinux в файле журнала Audit может выглядеть так:
type=AVC msg=audit(1395177286.929:1638): avc: denied { read } for pid=6591 comm="httpd" name="webpages" dev="0:37" ino=2112 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=dir
Наиболее важные части этой записи:
-
avc: denied— действие, выполненное SELinux и записанное в Access Vector Cache (AVC) -
{ read }— запрещённое действие -
pid=6591— идентификатор процесса субъекта, который пытался выполнить запрещённое действие -
comm="httpd"— имя команды, которая использовалась для запуска анализируемого процесса -
httpd_t— тип SELinux процесса -
nfs_t— тип SELinux объекта, затронутого действием процесса -
tclass=dir— класс целевого объекта
Предыдущую запись журнала можно перевести так:
SELinux запретил процессу httpd с PID 6591 и типом httpd_t читать из каталога с типом nfs_t.
Следующее сообщение об отказе SELinux возникает, когда Apache HTTP Server пытается получить доступ к каталогу, помеченному типом для набора Samba:
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
-
{ getattr }— записьgetattrуказывает, что исходный процесс пытался прочитать информацию о состоянии целевого файла. Это происходит перед чтением файлов. SELinux запрещает это действие, потому что процесс обращается к файлу, а тот не имеет подходящей метки. Часто встречающиеся разрешения включаютgetattr,readиwrite. -
path="/var/www/html/file1"— путь к объекту (цели), к которому пытался получить доступ процесс. -
scontext="unconfined_u:system_r:httpd_t:s0"— контекст SELinux процесса (источника), который пытался выполнить запрещённое действие. В этом случае это контекст SELinux Apache HTTP Server, работающего с типомhttpd_t. -
tcontext="unconfined_u:object_r:samba_share_t:s0"— контекст SELinux объекта (цели), к которому пытался получить доступ процесс. В этом случае это контекст SELinux файлаfile1.
Этот отказ SELinux можно перевести так:
SELinux запретил процессу httpd с PID 2465 доступ к файлу /var/www/html/file1 с типом samba_share_t, который недоступен процессам, работающим в домене httpd_t, если не настроено иное.
Дополнительные ресурсы
-
страницы руководства
auditd(8)иausearch(8)
Want to help? Learn how to contribute to Fedora Docs ›