Однажды я решил, что дальше так жить нельзя. В смысле, что нужно перестать отключать SELinux. Далее описано что делать, чтобы и SELinux не отключать и чтобы сервер в бесполезную тыкву не превращался.
Понять куда копать обычно помогает командочка
grep denied /var/log/audit/audit.log
- Если апач не стартует, рассказывая про permission denied для одного из конфиг-файлов, то в audit.log есть что-то типа:
type=AVC msg=audit(1501594149.023:2543): avc: denied { getattr } for pid=14324 comm="httpd" path="/vhosts/conf/httpd.conf" dev="dm-2" ino=100663502 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
Лечится это так:
semanage fcontext -a -t httpd_config_t "/vhosts/conf(/.*)?"
restorecon -Rv /vhosts/conf
- Если в audit.log видим
type=AVC msg=audit(1501594181.889:2546): avc: denied { write } for pid=14349 comm="httpd" name="logs" dev="dm-2" ino=90 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=dir
То делаем:
semanage fcontext -a -t httpd_log_t "/vhosts/logs(/.*)?"
restorecon -Rv /vhosts/logs
- Если при попытке доступа к любому файлу сайта апач выдает 403, то в audit.log обычно видим
type=AVC msg=audit(1501594423.783:2553): avc: denied { getattr } for pid=14390 comm="httpd" path="/vhosts/host1_html/index.html" dev="dm-2" ino=67148571 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file
Лечится вот так:
semanage fcontext -a -t httpd_sys_content_t "/vhosts/host1_html(/.*)?"
restorecon -vR /vhosts/host1_html
- Если веб-приложению нужен доступ на запись к определённым файлам сайта, то вместо httpd_sys_content_t следует использовать httpd_sys_rw_content_t. Например, для WordPress почти всегда нужно сделать что-то типа:
semanage fcontext -t httpd_sys_rw_content_t -a "/vhosts/host1_html/wp-content/uploads(/.*)?"
semanage fcontext -t httpd_sys_rw_content_t -a "/vhosts/host1_html/wp-content/upgrade(/.*)?"
restorecon -vR /vhosts/host1_html
- Если php не может отправить почту, в maillog-е "postfix/sendmail[14409]: fatal: open /etc/postfix/main.cf: Permission denied" и в audit.log видим
type=AVC msg=audit(1502447179.083:18392): avc: denied { read } for pid=14409 comm="sendmail" name="main.cf" dev="dm-0" ino=17209129 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:postfix_etc_t:s0 tclass=file
то делаем:
setsebool -P httpd_can_sendmail=1
Параметр -P означает, что это нужно сохранить перманентно. Не добавляйте, если не требуется делать такие изменения навсегда.
- Если php не может подключиться к mysql-базе и в audit.log такое
type=AVC msg=audit(1501600773.859:125): avc: denied { name_connect } for pid=3082 comm="php-fpm" dest=3306 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket
то делаем
setsebool -P httpd_can_network_connect_db 1
- Если php не может подключиться к memcache и в audit.log такое
type=AVC msg=audit(1532103361.735:38182): avc: denied { name_connect } for pid=12892 comm="php-fpm" dest=11211 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:memcache_port_t:s0 tclass=tcp_socket
то делаем
setsebool -P httpd_can_network_memcache=1
- Если вы решили перевесить SSH-сервер на какой-то нестандартный порт, например, 2229, то нужно не забыть сказать об этом селинуксу:
semanage port -a -t ssh_port_t -p tcp 2229
После чего проверка должна показать нечто такое:
semanage port --list | grep -i ssh
ssh_port_t tcp 2229, 22
- Если используется php-fpm на кастомном порту, например, 9013, то делаем так:
semanage port -a -t http_port_t -p tcp 9013
После чего проверка должна показать нечто такое:
semanage port --list | grep -i http_port_t
http_port_t tcp 9013, 80, 81, 443, 488, 8008, 8009, 8443, 9000
- Если вы решили переместить базы данных mysql в какое-то нестандартное место (например, из /var/lib/mysql в /home/mysql), то нужно сделать
semanage fcontext -a -t mysqld_db_t "/home/mysql(/.*)?"
restorecon -Rv /home/mysql
В некоторых случаях даже после внимательного прочтения audit.log просветления не приходит и непонятно что нужно подкрутить. Тогда может помочь утилитка audit2allow (входит в состав пакета policycoreutils-python), которой надо скормить сточку с denied из audit.log. С помощью ключа -M задается какое-то произвольное имя, которое будет использовано для формирования файлов с результатами. В файле с расширением .te будет текстовая человекочитабельная версия, а в файле .pp - собственно нужный нам модуль, который затем инсталлируется с помощью команды semodule:
grep denied /var/log/audit/audit.log | tail -n1 | audit2allow -M exim-dovecot
ls
exim-dovecot.pp exim-dovecot.te
file exim-dovecot.pp
exim-dovecot.pp: SE Linux modular policy version 1, 1 sections, mod version 19, MLS, module name exim-dovecot\003
semodule -i exim-dovecot.pp
В Fedora пришлось столкнуться с вот таким, появляющимся стабильно раз в сутки по ночам:
type=AVC msg=audit(1598149501.525:94279): avc: denied { dac_override } for pid=27800 comm="tmpwatch" capability=1 scontext=system_u:system_r:tmpreaper_t:s0-s0:c0.c1023 tcontext=system_u:system_r:tmpreaper_t:s0-s0:c0.c1023 tclass=capability permissive=0
Полезные ссылки по теме, объясняющие откуда здесь ноги растут:
https://danwalsh.livejournal.com/79643.html
https://danwalsh.livejournal.com/80232.html
Фишечка с dontaudit понравилась.