Зачем глубже чем selinux-apparmor
Базовый обзор Mandatory Access Control в selinux-apparmor. Здесь policy mechanics: как написать/отладить/расширить правила, как работать с booleans, файловыми контекстами, port labelling.
Реальные сценарии:
- "Apache не может читать
/var/www/data/" → fix file context - "Custom-сервис на нестандартном порту → SELinux блокирует bind" → port label
- "Нужен legitimate exception, не disable" → custom policy module
- "Mass-tuning через переключатели" → SELinux booleans
- "Compliance", fine-grained control с аудитом
Type Enforcement, основа
SELinux имеет четырёхкомпонентный security context:
user_u:role_r:type_t:level
└── user (SELinux user, не Linux user!)
└── role (system_r, unconfined_r, ...)
└── type / domain (httpd_t, sshd_t, var_log_t, ...)
└── MLS/MCS level (s0, s0:c1.c5, ...)
- На процессе type называется домен (
httpd_t,sshd_t) - На файле/сокете/порту, тип (
var_log_t,httpd_sys_content_t) - Type enforcement rule:
allow source_domain target_type:class { permissions };
Пример:
allow httpd_t httpd_sys_content_t:file { read getattr open };→ процесс в домене httpd_t может read/getattr/open файлы типа
httpd_sys_content_t. Всё остальное, denied.
Посмотреть контекст:
ls -Z /var/www/html/ # файлы
ps -eZ | grep httpd # процессы
ss -tnpZ # сокеты
id -Z # текущий user-context
Targeted vs MLS vs MCS
| Policy | Что |
|---|---|
| targeted | default; только конфайнят сервисы (httpd, sshd, named...). Юзеры в unconfined_t свободны |
| mls | Multi-Level Security; для GovHigh-grade с грифами секретности |
| mcs | Multi-Category Security; контейнеры в OpenShift получают разные categories для изоляции |
Активный режим:
sestatus
# SELinux status: enabled
# Loaded policy name: targeted
# Current mode: enforcing
# Mode from config file: enforcing
- enforcing, блокирует и логирует
- permissive, только логирует, не блокирует (для дебага)
- disabled, выключен, метки не ведутся (вернуть = relabel)
audit2allow, генерация rules из denials
Главный workflow при "X не работает из-за SELinux":
# 1. Включить permissive временно (для конкретного домена) или полностью
semanage permissive -a httpd_t # точечно
# ИЛИ
setenforce 0 # глобально, для дебага
# 2. Воспроизвести проблему
systemctl restart httpd
curl http://localhost/
# 3. Найти denials в auditd
ausearch -m AVC -ts recent
# 4. Сгенерить policy-rule
ausearch -m AVC -ts recent | audit2allow -M my-httpd-fix
# Создаст my-httpd-fix.te (текст) и my-httpd-fix.pp (бинарь)
# 5. Загрузить
semodule -i my-httpd-fix.pp
# 6. Вернуть enforcing
semanage permissive -d httpd_t
setenforce 1
audit2allow, это не "правильный путь". Это быстрый патч.
Лучше сначала проверить: может, нужный context уже есть, или есть
boolean.
Booleans, точечные переключатели
Дистрибуция-policy включает десятки booleans для типичных on/off-фичей:
# Смотреть все
getsebool -a | head
# Конкретный
getsebool httpd_can_network_connect
▸off
# Включить временно (до reboot)
setsebool httpd_can_network_connect on
# Включить постоянно
setsebool -P httpd_can_network_connect on
# Описание
semanage boolean -l | grep httpd
Типичные:
httpd_can_network_connect, apache может ходить в сеть (proxy/upstream)httpd_can_sendmailsamba_export_all_rwnfs_export_all_rwssh_chroot_rw_homedirs
Перед audit2allow, всегда проверь boolean. Скорее всего
готовое решение уже есть.
File contexts, semanage fcontext
Контекст файла, это xattr security.selinux (см. extended-attributes).
При создании файла наследуется от parent-директории.
Если положил файл в нестандартное место, контекст будет неправильный:
ls -Z /opt/myapp/index.html
# unconfined_u:object_r:usr_t:s0 ...
# Apache хочет httpd_sys_content_t. Назначить:
semanage fcontext -a -t httpd_sys_content_t '/opt/myapp(/.*)?'
restorecon -Rv /opt/myapp
semanage fcontext, добавляет правило в DB (постоянно)restorecon, применяет правила к существующим файламchcon, меняет контекст без записи в DB (временно, не переживёт relabel)
Список текущих:
semanage fcontext -l | grep httpd
Port labels
SELinux лейблит и сокеты:
# apache хочет порт 8080
systemctl restart httpd # FAIL: SELinux denied
ausearch -m AVC | tail -5 # увидишь denial на name_bind
# Решение:
semanage port -a -t http_port_t -p tcp 8080
systemctl restart httpd # OK
# Список
semanage port -l | grep http
Если sshd на нестандартном, то же:
semanage port -a -t ssh_port_t -p tcp 2222
Custom policy module
Когда нужен legitimate exception, оформить как module:
# my-custom.te
module my-custom 1.0;
require {type httpd_t;
type custom_data_t;
class file { read getattr open };}
allow httpd_t custom_data_t:file { read getattr open };Компиляция и установка:
checkmodule -M -m -o my-custom.mod my-custom.te
semodule_package -o my-custom.pp -m my-custom.mod
semodule -i my-custom.pp
Просмотр загруженных:
semodule -l | head
Удалить:
semodule -r my-custom
Relabel всей FS
После catastrophic-misconfiguration или возврата SELinux из disabled:
# При следующей загрузке
touch /.autorelabel
reboot
# Или интерактивно
fixfiles -F restore
Может занять часы на больших ФС.
sealert, graphical AVC analyzer
dnf install setroubleshoot setroubleshoot-server
systemctl enable --now setroubleshootd
Анализирует AVC-denial и предлагает решение на человеческом языке:
sealert -a /var/log/audit/audit.log
→ "Try changing boolean X" / "Try restorecon" / "If you really need this, generate module".
Полезно для junior'ов и начинающих с SELinux.
Когда что-то пошло не так
- "SELinux is preventing..." в журнале,
sealert -a /var/log/audit/audit.logилиausearch -m AVC -ts recent | audit2allow. Permission deniedбез явных причин, проверьls -Zиgetenforce. Часто проблема не в Linux-permissions, а в SELinux-context.- Правильный mode 644, владелец, group, но read fails, context
не подходит для домена.
restorecon -Rv path. semanageне найден, установиpolicycoreutils-python-utils(RHEL) илиpolicycoreutils-python(старее).- dontaudit-правила скрывают denials, некоторые denials системно
подавляются.
semodule -DBотключает dontaudit для дебага. Не забудь вернуть:semodule -B. - policy module не работает после рестарта, модуль не загружен
в активную policy. Проверь
semodule -l | grep my-custom. Если нет,semodule -iещё раз. - Изменения через chcon потерялись, норма.
chconне пишет в DB. Используйsemanage fcontext+restorecon.
Чек-лист "проблема с SELinux"
getenforce, режим. ЕслиPermissive, проблема не в SELinux.ausearch -m AVC -ts recent, есть ли denial в audit.logls -Z, какой context у файла, который не читаетсяps -eZ | grep procname, какой домен у процессаsemanage boolean -l | grep <тема>, есть ли готовый togglesemanage fcontext -l | grep <путь>, какой context должен бытьrestorecon -Rv, fix existing filesaudit2allowкак последнее средство