3.4.8.4 Специальные случаи и настройка
Предварительные условия
Приложения, настроенные нестандартными способами
Номера портов
Решение проблем из практики
Написание собственной политики SELinux
Проверка работы приложения под защитой SELinux
Рекомендации по настройке типов файлов
Окружение
- Версия ОС: 8
- Конфигурация ОС: Рабочая станция
- Редакция ОС: Стандартная, Образовательная
Предварительные условия
Убедитесь, что SELinux включен и работает в режиме Enforcing:
sudo getenforce Enforcing
Необходимо предварительно установить следующие пакеты:
sudo dnf install selinux-policy-devel setroubleshoot gcc rpm-build
Приложения, настроенные нестандартными способами
Службы могут запускаться различными способами. Чтобы система работала правильно, укажите способ запуска служб. Можно добиться этого с помощью логических переменных SELinux, которые позволяют изменять части политики SELinux во время выполнения. Это позволяет вносить изменения, например, разрешать службам доступ к томам NFS без перезагрузки или перекомпиляции политики SELinux. Кроме того, запуск служб на нестандартных номерах портов требует обновления конфигурации политики с помощью команды semanage.
Например, чтобы разрешить Apache HTTP-серверу взаимодействовать с MariaDB, включите переменную httpd_can_network_connect_db:
sudo setsebool -P httpd_can_network_connect_db on
Обратите внимание, что опция -P сохраняет настройку при перезагрузках системы.
Если доступ для определенной службы запрещен, используйте утилиты getsebool и grep, чтобы проверить, доступны ли какие-либо логические значения для разрешения доступа. Например, используйте следующую команду для поиска логических значений, связанных с 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.
Номера портов
В зависимости от конфигурации политики службам может быть разрешено работать только на определенных номерах портов. Попытка изменить порт, на котором работает служба, без изменения политики может привести к тому, что служба не запустится.
Например, выполните следующую команду, чтобы получить список 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 для отражения этого изменения, команда запуска завершится с ошибкой:
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)
Чтобы разрешить httpd прослушивание порта, который не указан в списке для типа порта http_port_t, используйте команду semanage port для назначения порту другой метки:
sudo semanage port -a -t http_port_t -p tcp 9876
где:
-
-a— добавляет новую запись; -
-t— определяет тип; -
-p— задает протокол; -
9876— номер порта для добавления.
Решение проблем из практики
1. Обновление программ приводит к появлению новых уведомлений. Функционал расширяется. Необходимо добавлять новые правила в существующие политики. Обычно можно бэкпортировать изменения или с большой осторожностью воспользоваться инструментом audit2allow.
Перед генерацией модуля политики важно убедиться, что доступ действительно требуется разрешить в рамках одного домена. Другими словами, модуль политики уже существует и его требуется немного расширить для поддержки нового функционала.
-
Сообщениям аудита характерны запреты в переделах одного домена и это не
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отключает небезопасный функционал.
-
Иногда нужно добавить в существующую политику новые разрешения. Например, в zabbix policy добавлено разрешение
kerberos_read_keytab(zabbix_t).
2. Иногда встречаются ошибки в пространстве пользователей SELinux, подробнее в примере.
3. Пользователь изменил расположение скрипта. Пользователь разместил исполняемый скрипт в каталоге с файлами конфигурации. В результате скрипт получил контекст конфигурационного файла, из-за чего его запуск был заблокирован политикой SELinux, так как выполнение файлов с таким типом запрещено.
4. Пользователь скачал и установил по первой попавшейся из интернета инструкции ПО, имеющее сервис systemd. Распаковал тарбол в домашней директории и переместил, например, в каталог /opt. Файлы получили тип user_home_t. При перемещении файловый контекст сохраняется аналогично дискреционным правам. После запуска исполняемого файла домен процесса будет init_t, унаследованный от systemd, что приведёт к множеству уведомлений. Бездумно добавлять разрешения в существующие домены в данном случае недопустимо. Если скаченное ПО не имеет модуля политик SELinux, правильным будет запустить его в домене 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, настроить переход типа файла:
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, а не со всей домашней директорией.
7. В случае использования web-серверов, таких как Apache или Nginx, вероятнее всего проблему можно решить с помощью SELinux булевых переменных seboolen. Многие веб-сценарии предусмотрены политиками, но отключены с помощью логических переключателей.
Обратите внимание, что audit2allow следует использовать осмысленно. Этот инструмент предназначен для анализа уведомлений.
Написание собственной политики SELinux
Можно ограничить приложения с помощью SELinux для повышения безопасности хост-систем и данных пользователей. Поскольку каждое приложение имеет особые требования, измените этот пример для создания политики SELinux, которая ограничивает простой демон в соответствии с пользовательским вариантом использования.
Пакет selinux-policy-devel должен быть установлен в системе.
Для этого примера процедуры подготовим простой демон, который открывает /var/log/messages файл для записи.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/mydaemon Created the following files: /root/mydaemon.te # Файл принудительного ограничения по типу /root/mydaemon.if # Файл интерфейса /root/mydaemon.fc # Файл контекстов /root/mydaemon_selinux.spec # Файл спецификаций /root/mydaemon.sh # Сценарий настройки
8. Запустите сгенерированный скрипт настройки:
sudo ./mydaemon.sh Building 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 mydaemon system_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.pp Additional 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 -R
require {
type mydaemon_t;
}
#============= mydaemon_t ==============
logging_write_generic_logs(mydaemon_t)
14. Поскольку правила, предлагаемые audit2allow могут быть неверными для определенных случаев, используйте только часть его вывода, чтобы найти соответствующий интерфейс политики. Проверьте макрос logging_write_generic_logs(mydaemon_t) с помощью macro-expander, чтобы увидеть все правила разрешения, предоставляемые макросом:
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.sh Building 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
Проверка работы приложения под защитой SELinux
1. Проверьте, что ваше приложение работает под защитой SELinux, например:
ps -efZ | grep mydaemon system_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 и других объектов, с которыми работает процесс.
Рассмотрим 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*). Для более детального понимания интерфейсов (макросов) и их применения рекомендуется изучить уже существующие политики.
Дата последнего изменения: 18.12.2025
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.