Вопрос или проблема
У меня есть Type=simple
/etc/systemd/system/custom.service
.
В нем указано ExecStart=/root/scripts/custom.sh
.
Я использую это, чтобы различные административные задачи выполнялись автоматически после загрузки.
Это хорошо работало до Redhat 7.9, проблем с selinux не было при установленном selinux=enforcing
.
В RHEL 8.8 я получаю отказ вызова AVC в /var/log/messages
.
systemd[1]: Запущен пользовательский сервис.
systemd[96691]: custom.service: Не удалось выполнить команду: Отказ в доступе
systemd[96691]: custom.service: Не удалось на этапе EXEC при порождении /root/scripts/custom.sh: Отказ в доступе
systemd[1]: custom.service: Основной процесс завершился, код=выход, статус=203/EXEC
systemd[1]: custom.service: Не удалось с результатом 'exit-code'.
SELinux предотвращает доступ к выполнению для /usr/lib/systemd/systemd к файлу custom.sh.
Для получения полных сообщений SELinux выполните: sealert -l 84fa818f-e23a-4686-afb5-3f2399d0d6ea
setroubleshoot[96693]: SELinux предотвращает доступ к выполнению для /usr/lib/systemd/systemd к файлу custom.sh.#012#012
*****Plugin catchall (100. confidence) предлагает
**************************#012#012Если вы считаете, что systemd следует разрешить доступ к выполнению
к файлу custom.sh по умолчанию.#012Тогда вам следует сообщить об этом как об ошибке.#012Вы можете сгенерировать
локальный модуль политики, чтобы разрешить этот доступ.
#012Пока#012разрешите этот доступ, выполнив:
#012# ausearch -c '(ation.sh)' --raw | audit2allow -M my-ationsh#012# semodule -X 300 -i my-ationsh.pp#012
Так что я знаю, что мой скрипт /root/scripts/custom.sh
не имеет правильного контекста selinux. Но что мне использовать?
Мой /etc/systemd/system/custom.service
автоматически получил systemd_unit_file_t
, так что я думаю, что это все настроено.
Мой /root/scripts/custom.sh
в настоящее время имеет unconfined_u:object_r:admin_home_t:s0
.
Проверяя другие элементы ExecStart с помощью ls -ldZ
из других сервисов в этой папке, я вижу:
-rwxr-xr-x. 1 root root system_u:object_r:bluetooth_exec_t:s0 1375048 May 17 2022 /usr/libexec/bluetooth/bluetoothd
-rwxr-xr-x. 1 root root system_u:object_r:NetworkManager_exec_t:s0 67752 Feb 23 04:51 /usr/libexec/nm-dispatcher
-rwxr-xr-x. 1 root root system_u:object_r:avahi_exec_t:s0 146208 Nov 3 2020 /usr/sbin/avahi-daemon
-rwxr-xr-x. 1 root root system_u:object_r:xdm_exec_t:s0 471744 Dec 12 2022 /usr/sbin/gdm
-rwxr-xr-x. 1 root root system_u:object_r:modemmanager_exec_t:s0 2203464 Dec 13 2022 /usr/sbin/ModemManager
-rwxr-xr-x. 1 root root system_u:object_r:syslogd_exec_t:s0 742168 Jan 10 06:46 /usr/sbin/rsyslogd
-rwxr-xr-x. 1 root root system_u:object_r:timedatex_exec_t:s0 33984 Aug 12 2018 /usr/sbin/timedatex
- Мне нужно создавать контекст типа
customservice_exec_t
? Если да, то как? - Я думал, что наткнулся на
bin_t
, когда не видел соответствующей синтаксической конструкцииexec_t
для некоторых сервисов, когда я искал. Является лиbin_t
хорошим контекстом, который можно использовать, чтобы сэкономить время на создание контекста? - Какова правильная конвенция здесь для того, что я делаю, чтобы это не перестало работать в будущем из-за того, что я сделал что-то неправильно? Мне нужно иметь
selinux=enforcing
, так что установка его в режим permissive не является решением.
Мне нужно создавать контекст типа customservice_exec_t? Если да, то как?
Вам не нужно этого делать, это было бы необходимо только если вы хотите создать очень специфические правила и быть уверенным в контроле каждого типа, который к нему обращается, что требует много времени на создание и высоких затрат на обслуживание. Похоже, что вы просто хотите использовать лучшие практики selinux с низким обслуживанием.
Хотя вы можете проверить здесь, как это сделать.
Я думал, что наткнулся на bin_t, когда не видел соответствующей синтаксиса exec_t для некоторых сервисов, когда я искал. Является ли bin_t хорошим контекстом, чтобы сэкономить время на создание контекста?
Да, bin_t
является хорошим контекстом для использования здесь, он используется для перехода сервисов в общий контекст для пользовательских сервисов (unconfined_service_t
), который лишь слегка ограничен политикой SELinux:
# sesearch -T -s init_t -t bin_t -c process
type_transition init_t bin_t:process unconfined_service_t;
Какова правильная конвенция здесь для того, что я делаю, чтобы это не перестало работать в будущем из-за того, что я сделал что-то неправильно
Вы можете скопировать свой скрипт в /bin
и затем выполнить restorecon -RF /bin/custom.sh
, или предоставить вашей папке scripts
правильный контекст с помощью:
# semanage fcontext -a -t bin_t "/root/scripts(/.*)?"
# restorecon -vRF /root/scripts
Ответ или решение
Контекст SELinux для ExecStart кастомного сервиса systemd
Ваша проблема с SELinux в RHEL 8.8 заключается в том, что ваш исполняемый скрипт /root/scripts/custom.sh
не имеет правильного контекста SELinux. Вы получаете ошибки на уровне выполнения, что указывает на то, что доступ к файлу был запрещен политиками SELinux. В этом ответе мы подробно рассмотрим подходы к разрешению этой проблемы и лучшую практику применения SELinux.
1. Установление правильного контекста SELinux
Ваш текущий контекст файла /root/scripts/custom.sh
:
unconfined_u:object_r:admin_home_t:s0
Этот контекст не позволяет системе выполнять скрипт через systemd
из-за ограничений политики SELinux в RHEL 8.8. Чтобы решить эту проблему, необходимо применить правильный контекст для исполняемых файлов.
Рекомендация по контекстам:
- Если вы не планируете создавать специфические правила SELinux, можно использовать контекст
bin_t
, который предназначен для пользовательских скриптов и программ. Это позволит избежать сложности, связанной с созданием нового контекста.
2. Применение контекста bin_t
Чтобы применить контекст bin_t
к вашему скрипту, выполните следующие команды:
# Добавьте правило для контекста
semanage fcontext -a -t bin_t "/root/scripts(/.*)?"
# Примените изменения контекста
restorecon -vRF /root/scripts
Эти команды добавят соответствующий контекст к файлам в директории /root/scripts
и применят его ко всем существующим файлам.
3. Создание специфического контекста (по желанию)
Если вы всё же хотите создать специализированный контекст, вы можете создать новый тип, например customservice_exec_t
. Для этого вам потребуются следующие шаги:
- Создать файл модуля политики SELinux.
- Скомпилировать и установить его с помощью команд:
# проблемы с аудированием
ausearch -c 'custom.sh' --raw | audit2allow -M customservice_exec_t
# установка модуля
semodule -X 300 -i customservice_exec_t.pp
Использование специализированного контекста может дать вам больше контроля, но потребует также большего внимания к управлению политиками.
4. Убедитесь в долговечности решения
Для обеспечения устойчивости вашего решения всегда используйте restorecon
после изменения контекста, чтобы гарантировать, что в будущем изменения не потеряются. Также полезно:
- Регулярно проверять логи SELinux.
- Проводить аудит ваших пользовательских скриптов и запусков на наличие новых AVC-отказов.
Заключение
Лучшей практикой для вашего сценария будет использование bin_t
для вашего скрипта, так как это обеспечит более низкие накладные расходы на администрирование политики SELinux в будущем. Если возникнет необходимость в более специфичном контроле, вы всегда сможете создать свой собственный контекст.
Следуйте этим рекомендациям, чтобы избежать проблем с SELinux, сохранив при этом безопасность вашего сервера, который работает под управлением политики SELinux в режиме принуждения (enforcing).