Предварительные условия Приложения, настроенные нестандартными способами Номера портов Решение проблем из практики Написание собственной политики SELinux Проверка работы приложения под защитой SELinux Рекомендации по настройке типов файлов
Окружение
Убедитесь, что SELinux включен и работает в режиме Enforcing:
sudo getenforceEnforcing
Необходимо предварительно установить следующие пакеты:
sudo dnf install selinux-policy-devel setroubleshoot gcc rpm-build
Службы могут запускаться различными способами. Чтобы система работала правильно, укажите способ запуска служб. Можно добиться этого с помощью логических переменных SELinux, которые позволяют изменять части политики SELinux во время выполнения. Это позволяет вносить изменения, например, разрешать службам доступ к томам NFS без перезагрузки или перекомпиляции политики SELinux. Кроме того, запуск служб на нестандартных номерах портов требует обновления конфигурации политики с помощью команды semanage.
semanage
Например, чтобы разрешить Apache HTTP-серверу взаимодействовать с MariaDB, включите переменную httpd_can_network_connect_db:
httpd_can_network_connect_db
sudo setsebool -P httpd_can_network_connect_db on
Обратите внимание, что опция -P сохраняет настройку при перезагрузках системы.
-P
Если доступ для определенной службы запрещен, используйте утилиты getsebool и grep, чтобы проверить, доступны ли какие-либо логические значения для разрешения доступа. Например, используйте следующую команду для поиска логических значений, связанных с FTP:
getsebool
grep
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.
getsebool -a
semanage boolean -l
В зависимости от конфигурации политики службам может быть разрешено работать только на определенных номерах портов. Попытка изменить порт, на котором работает служба, без изменения политики может привести к тому, что служба не запустится.
Например, выполните следующую команду, чтобы получить список 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. Если администратор настроит прослушивание нестандартного порта, например, 9876, но политика не обновлена httpd.conf для отражения этого изменения, команда запуска завершится с ошибкой:
http_port_t
sudo systemctl start httpd.serviceJob for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.sudo systemctl status httpd.servicehttpd.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)
Чтобы разрешить httpd прослушивание порта, который не указан в списке для типа порта http_port_t, используйте команду semanage port для назначения порту другой метки:
semanage port
sudo semanage port -a -t http_port_t -p tcp 9876
где:
-a — добавляет новую запись;
-a
-t — определяет тип;
-t
-p — задает протокол;
-p
9876 — номер порта для добавления.
9876
1. Обновление программ приводит к появлению новых уведомлений. Функционал расширяется. Необходимо добавлять новые правила в существующие политики. Обычно можно бэкпортировать изменения или с большой осторожностью воспользоваться инструментом audit2allow.
Перед генерацией модуля политики важно убедиться, что доступ действительно требуется разрешить в рамках одного домена. Другими словами, модуль политики уже существует и его требуется немного расширить для поддержки нового функционала.
Сообщениям аудита характерны запреты в переделах одного домена и это не init_t или init_rc_t. Например:
init_t
init_rc_t
scontext=system_u:system_r:chkpwd_t:s0
scontext=system_u:system_r:ndc_t:s0
scontext=system_u:system_r:fsdaemon_t:s0
scontext=system_u:system_r:haproxy_t:s0
scontext=system_u:system_r:kdump_t:s0
Решение в первую очередь можно поискать в исходниках системных политик известных дистрибутивов. Часто решение уже существует, нужно лишь понять, какое именно исправление подходит для конкретной ситуации.
Иногда проблемы возникают из-за некорректной конфигурации программы на этапе сборки. rpcbind при сборке с конфигурацией по умолчанию открывает сокет на случайном порту. Сборка с конфигурацией --disable-rmtcalls отключает небезопасный функционал.
--disable-rmtcalls
Иногда нужно добавить в существующую политику новые разрешения. Например, в zabbix policy добавлено разрешение kerberos_read_keytab(zabbix_t).
kerberos_read_keytab(zabbix_t)
2. Иногда встречаются ошибки в пространстве пользователей SELinux, подробнее в примере.
3. Пользователь изменил расположение скрипта. Пользователь разместил исполняемый скрипт в каталоге с файлами конфигурации. В результате скрипт получил контекст конфигурационного файла, из-за чего его запуск был заблокирован политикой SELinux, так как выполнение файлов с таким типом запрещено.
4. Пользователь скачал и установил по первой попавшейся из интернета инструкции ПО, имеющее сервис systemd. Распаковал тарбол в домашней директории и переместил, например, в каталог /opt. Файлы получили тип user_home_t. При перемещении файловый контекст сохраняется аналогично дискреционным правам. После запуска исполняемого файла домен процесса будет init_t, унаследованный от systemd, что приведёт к множеству уведомлений. Бездумно добавлять разрешения в существующие домены в данном случае недопустимо. Если скаченное ПО не имеет модуля политик SELinux, правильным будет запустить его в домене unconfind_service_t, назначив исполняемым файлам контекст bin_t. Такой подход, по крайней мере, исключает риск внесения потенциально опасных разрешений в существующие политики.
user_home_t
unconfind_service_t
bin_t
5. Есть случаи, когда одни процессы запускают другие, а переход домена не описан в политике. Появляется множество уведомлений, которые сложно интерпретировать, более того, не следует бездумно разрешать все возникающие запросы. Правильным подходом в такой ситуации будет описание перехода домена в политике, чтобы обеспечить безопасное и корректное выполнение процессов.
chronyd_domtrans_chronyc(NetworkManager_dispatcher_dhclient_t) chronyd_manage_pid(NetworkManager_dispatcher_dhclient_t) chronyd_pid_filetrans(NetworkManager_dispatcher_dhclient_t)
6. Случай, когда в стек PAM добавляется сторонний модуль. Домены, использующие PAM-стек, начинают генерировать уведомления из-за того, что модуль добавляет функционал, не описанный в существующих политиках. Например, модуль pam_usb.so может попытаться записывать данные в домашние каталоги пользователей. В такой ситуации следует быть крайне осторожным и не предоставлять модулю полный доступ, вместо этого рекомендуется создать отдельный тип, например, pamusb_home_t, настроить переход типа файла:
pamusb_home_t
type pamusb_home_t; userdom_user_home_content(pamusb_home_t) manage_dirs_pattern(local_login_t, pamusb_home_t, pamusb_home_t) manage_files_pattern(local_login_t, pamusb_home_t, pamusb_home_t) userdom_user_home_dir_filetrans(local_login_t, pamusb_home_t, dir,".pamusb")
Таким образом, домену local_login_t будет разрешено только взаимодействие с типом pamusb_home_t, а не со всей домашней директорией.
local_login_t
7. В случае использования web-серверов, таких как Apache или Nginx, вероятнее всего проблему можно решить с помощью SELinux булевых переменных seboolen. Многие веб-сценарии предусмотрены политиками, но отключены с помощью логических переключателей.
Обратите внимание, что audit2allow следует использовать осмысленно. Этот инструмент предназначен для анализа уведомлений.
Можно ограничить приложения с помощью SELinux для повышения безопасности хост-систем и данных пользователей. Поскольку каждое приложение имеет особые требования, измените этот пример для создания политики SELinux, которая ограничивает простой демон в соответствии с пользовательским вариантом использования.
Пакет selinux-policy-devel должен быть установлен в системе.
1. Создайте новый файл и откройте его в текстовом редакторе по вашему выбору:
sudo nano mydaemon.c
2. Вставьте следующий код:
#include <unistd.h> #include <stdio.h> FILE *f; int main(void) { while(1) { f = fopen("/var/log/messages","w"); sleep(5); fclose(f); } }
3. Скомпилируйте файл:
sudo gcc -o mydaemon mydaemon.c
4. Создайте файл конфигурации для демона в формате systemd:
sudo nano mydaemon.service
Добавьте в него следующие строки:
[Unit] Description=Simple testing daemon [Service] Type=simple ExecStart=/usr/local/bin/mydaemon [Install] WantedBy=multi-user.target
5. Установите и запустите демон:
sudo cp mydaemon /usr/local/bin/ sudo cp mydaemon.service /usr/lib/systemd/system sudo systemctl start mydaemon
sudo systemctl status mydaemon● mydaemon.service - Simple testing daemon Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; preset: disabled) Drop-In: /usr/lib/systemd/system/service.d └─10-timeout-abort.conf Active: active (running) since Tue 2025-08-19 11:00:26 MSK; 21s ago Main PID: 2907 (mydaemon) Tasks: 1 (limit: 4663) Memory: 168.0K CPU: 8ms CGroup: /system.slice/mydaemon.service └─2907 /usr/local/bin/mydaemon авг 19 11:00:26 localhost.localdomain systemd[1]: Started mydaemon.service - Simple testing daemon.
6. Проверьте, что новый демон не ограничен SELinux:
sudo ps -efZ | grep mydaemon system_u:system_r:unconfined_service_t:s0 root 4117 1 0 16:56 ? 00:00:00 /usr/local/bin/mydaemon
7. Создайте пользовательскую политику для демона:
sepolicy generate --init /usr/local/bin/mydaemonCreated the following files: /root/mydaemon.te # Файл принудительного ограничения по типу /root/mydaemon.if # Файл интерфейса /root/mydaemon.fc # Файл контекстов /root/mydaemon_selinux.spec # Файл спецификаций /root/mydaemon.sh # Сценарий настройки
8. Запустите сгенерированный скрипт настройки:
sudo ./mydaemon.shBuilding and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp …
9. Обратите внимание, что скрипт установки перемаркировывает соответствующую часть файловой системы с помощью команды restorecon:
sudo restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/system
10. Перезапустите демон:
sudo systemctl restart mydaemon
11. Проверьте, что теперь он работает под контролем SELinux:
sudo ps -efZ | grep mydaemonsystem_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
Поскольку демон теперь ограничен SELinux, ему запрещён доступ к файлу /var/log/messages. При попытке такого доступа в журнале аудита SELinux будет отображено соответствующее сообщение об отказе:
sudo ausearch -m AVC -ts recent ... type=AVC msg=audit(1590247112.719:5935): avc: denied { open } for pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ...
12. Дополнительную информацию можно получить с помощью sealert:
sealert -l "*"SELinux is preventing mydaemon from open access on the file /var/log/messages. ***** Plugin catchall (100. confidence) suggests ************************** If you believe that mydaemon should be allowed open access on the messages file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing:# ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon# semodule -X 300 -i my-mydaemon.ppAdditional Information: Source Context system_u:system_r:mydaemon_t:s0 Target Context unconfined_u:object_r:var_log_t:s0 Target Objects /var/log/messages [ file ] Source mydaemon …
13. Используйте audit2allow для просмотра предложенных изменений:
sudo ausearch -m AVC -ts recent | audit2allow -Rrequire { type mydaemon_t; }#============= mydaemon_t ==============logging_write_generic_logs(mydaemon_t)
14. Поскольку правила, предлагаемые audit2allow могут быть неверными для определенных случаев, используйте только часть его вывода, чтобы найти соответствующий интерфейс политики. Проверьте макрос logging_write_generic_logs(mydaemon_t) с помощью macro-expander, чтобы увидеть все правила разрешения, предоставляемые макросом:
logging_write_generic_logs(mydaemon_t)
sudo macro-expander "logging_write_generic_logs(mydaemon_t)" allow mydaemon_t var_t:dir { getattr search open } ; allow mydaemon_t var_log_t:dir { getattr search open read lock ioctl }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:file { open { getattr write append lock ioctl } }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:lnk_file { getattr read };
15. В этом случае можно использовать предложенный интерфейс, поскольку он предоставляет доступ только на чтение и запись к файлам журналов и их родительским каталогам. Добавьте соответствующее правило в файл принудительного применения типов:
sudo echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te
16. Переустановите политику:
./mydaemon.shBuilding and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp
1. Проверьте, что ваше приложение работает под защитой SELinux, например:
ps -efZ | grep mydaemonsystem_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
2. Убедитесь, что пользовательское приложение не вызывает отклонений SELinux:
sudo ausearch -m AVC -ts recent<no matches>
Описан пример предоставления доступа на чтение домену к файлам с типом var_log_t. Однако на практике это не используется. Домен также получит доступ к логам других процессов, работающих с типом var_log_t. Правильным решением будет создать собственный тип для логов и разрешить работу только с ним. Для этого следует использовать механизм file transition. Это решение применимо не только для логов, но и для временных файлов, конфигурационных файлов, файлов PID и других объектов, с которыми работает процесс.
var_log_t
file transition
Рассмотрим httpd policy:
type httpd_var_run_t; files_pid_file(httpd_var_run_t) manage_dirs_pattern(httpd_t, httpd_var_run_t, httpd_var_run_t) manage_files_pattern(httpd_t, httpd_var_run_t, httpd_var_run_t) manage_sock_files_pattern(httpd_t, httpd_var_run_t, httpd_var_run_t) files_pid_filetrans(httpd_t, httpd_var_run_t, { file sock_file dir })
Как видно, файлы, каталоги и сокеты, созданные httpd_t в каталоге /var/run/, получат тип httpd_var_run_t(*filetrans). Так же прописаны разрешения для работы с этими файлами (manage*). Для более детального понимания интерфейсов (макросов) и их применения рекомендуется изучить уже существующие политики.
httpd_t
httpd_var_run_t
(
*filetrans
)
Дата последнего изменения: 21.10.2025
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.
Нажимая «Отправить запрос», вы соглашаетесь с условиями обработки персональных данных.
Вы будете получать только актуальную информацию по обновлению безопасности
Подписываясь на уведомления, вы соглашаетесь с условиями обработки персональных данных.
На ваш почтовый адрес отправлено письмо с подтверждением подписки.