2.4.8.4 Специальные случаи и настройка
Предварительные условия
Приложения, настроенные нестандартными способами
Номера портов
Решение проблем из практики
Написание собственной политики SELinux
Проверка работы приложения под защитой SELinux
Рекомендации по настройке типов файлов
Окружение
- Версия ОС: 7.3
- Конфигурация ОС: Рабочая станция
- Редакция ОС: Все
Предварительные условия
Убедитесь, что SELinux включен и работает в режиме Enforcing:
sudo getenforce Enforcing
Пакеты selinux-policy-devel и gcc должны быть установлены в системе:
sudo dnf install selinux-policy-devel gcc
Приложения, настроенные нестандартными способами
Службы могут запускаться различными способами. Чтобы учесть это, необходимо указать, как вы запускаете свои службы. Можно добиться этого с помощью логических переменных 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. Обновление с версии РЕД ОС 7.2 на 7.3 приводит к обновлению политик, что добавляет новые файловые контексты, которые требуется разметить. В таких случаях необходимо выполнить autorelabel. Особую опасность представляют ситуации, когда старые модули не могут корректно загрузится в новые политики. Это может привести к сбою формирования системной политики и сделать систему незагружаемой, если SELinux работает в режиме enforce mode. Например, на этапе загрузки первый переход из kernel_t в init_t не произойдёт.
4. Пользователь изменил расположение скрипта. Пользователь разместил исполняемый скрипт в каталоге с файлами конфигурации. В результате скрипт получил контекст конфигурационного файла, из-за чего его запуск был заблокирован политикой SELinux, так как выполнение файлов с таким типом запрещено.
5. Пользователь скачал и установил по первой попавшейся из интернета инструкции ПО, имеющее сервис systemd. Распаковал тарбол в домашней директории и переместил, например, в каталог /opt. Файлы получили тип user_home_t. При перемещении файловый контекст сохраняется аналогично дискреционным правам. После запуска исполняемого файла домен процесса будет init_t, унаследованный от systemd, что приведёт к множеству уведомлений. Бездумно добавлять разрешения в существующие домены в данном случае недопустимо. Если скаченное ПО не имеет модуля политик SELinux, правильным будет запустить его в домене unconfind_service_t, назначив исполняемым файлам контекст bin_t. Такой подход, по крайней мере, исключает риск внесения потенциально опасных разрешений в существующие политики.
6. Есть случаи, когда одни процессы запускают другие, а переход домена не описан в политике. Появляется множество уведомлений, которые сложно интерпретировать, более того, не следует бездумно разрешать все возникающие запросы. Правильным подходом в такой ситуации будет описание перехода домена в политике, чтобы обеспечить безопасное и корректное выполнение процессов.
chronyd_domtrans_chronyc(NetworkManager_dispatcher_dhclient_t)
chronyd_manage_pid(NetworkManager_dispatcher_dhclient_t)
chronyd_pid_filetrans(NetworkManager_dispatcher_dhclient_t)7. Случай, когда в стек 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, а не со всей домашней директорией.
8. В случае использования web-серверов, таких как Apache или Nginx, вероятнее всего проблему можно решить с помощью SELinux булевых переменных seboolen. Многие web-сетапы предусмотрены политиками, но отключены через 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.target5. Установите и запустите демон:
sudo cp mydaemon /usr/local/bin/ sudo cp mydaemon.service /usr/lib/systemd/system sudo systemctl start mydaemon
Проверьте статус. Убедитесь, что статус соответствует active (running).
sudo systemctl status mydaemon
● mydaemon.service - Simple testing daemon
Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago
Main PID: 4117 (mydaemon)
Tasks: 1
Memory: 148.0K
CGroup: /system.slice/mydaemon.service
└─4117 /usr/local/bin/mydaemon
May 23 16:56:01 localhost.localdomain systemd[1]: Started 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. Перед создание пользовательской политики откройте файл на редактирование:
sudo nano /usr/lib/python3.8/site-packages/sepolicy/generate.py
Импортируйте в начале файла:
import distro
Замените две строки:
if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):на:
if (distro.id() in ("redhat", "centos", "suse", "fedora", "mandrake", "mandriva")):Создайте пользовательскую политику для демона:
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*). Для более детального понимания интерфейсов (макросов) и их применения рекомендуется изучить уже существующие политики.
Дата последнего изменения: 14.11.2025
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.