Мандатный контроль доступа: SELinux и AppArmor [333.2]

Рейтинг: 65.7% · 17 голосов
Специализация LPIC-3 303 (v3.0): криптография и PKI/X.509, шифрование ФС (LUKS/TPM2/Clevis), DNSSEC, hardening хоста, IDS, контроль доступа (SELinux/AppArmor), сетевая безопасность, nftables, VPN, пентест.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Мандатный контроль доступа: SELinux и AppArmor [333.2]

Сообщение Sergey_Sysadmin »

Оглавление курса (16)
  1. Введение в LPIC-3 303: безопасность Linux
  2. X.509 и инфраструктура открытых ключей [331.1]
  3. X.509 для шифрования, подписи и аутентификации [331.2]
  4. Шифрование файловых систем [331.3]
  5. DNS и криптография [331.4]
  6. Усиление защиты хоста [332.1]
  7. Урок 6. Обнаружение вторжений на хосте: AIDE, auditd, сканеры руткитов и OpenSCAP
  8. Контроль ресурсов [332.3]
  9. Дискреционный контроль доступа: ACL и атрибуты [333.1]
  10. Мандатный контроль доступа: SELinux и AppArmor [333.2] (вы здесь)
  11. Усиление сетевой защиты [334.1]
  12. Сетевое обнаружение вторжений
  13. Фильтрация пакетов [334.3]
  14. Виртуальные частные сети (VPN) [334.4]
  15. Уязвимости и угрозы [335.1]
  16. Основы тестирования на проникновение [335.2]
Урок 9. Мандатный контроль доступа: SELinux и AppArmor [333.2]

Классические права Unix (rwx, владелец, группа) - это дискреционный контроль доступа (DAC): владелец файла сам решает, кому дать доступ, и процесс, запущенный от root, может делать буквально всё. Мандатный контроль доступа (MAC) добавляет второй, неотключаемый владельцем слой: правила задаёт администратор через политику, и даже процесс root подчиняется ей. В этом уроке разберём два рабочих механизма MAC в Linux - SELinux (родной для семейства RHEL) и AppArmor (родной для Debian/Ubuntu/SUSE), научимся читать контексты, переключать режимы, чинить отказы и писать локальные исключения. Smack посмотрим обзорно как третий вариант.

Изображение

Как это работает

SELinux реализует MAC через метки (labels), которые ядро через модуль LSM проверяет при каждом системном вызове доступа. У каждого процесса, файла, порта, сокета есть контекст безопасности из четырёх полей: пользователь SELinux, роль, тип и уровень MLS. Пример контекста файла: system_u:object_r:httpd_sys_content_t:s0. Ключевое поле для целевой (targeted) политики - это тип. Решение принимается по правилам вида allow: процессу с типом httpd_t разрешено читать файлы с типом httpd_sys_content_t. Нет правила - нет доступа, по умолчанию запрещено всё. Эта модель называется Type Enforcement.

Целевая политика, которая стоит по умолчанию в RHEL 10 и Fedora 41+, ограничивает не всё подряд, а только перечисленные сетевые и системные сервисы (демоны). Процессы, для которых нет специальной политики, работают в неограниченном домене unconfined_t и фактически живут по старым правилам DAC. Это разумный компромисс: защищаем то, что смотрит в сеть, не ломая остальное.

У SELinux три режима. Enforcing - правила реально применяются, нарушения блокируются и пишутся в аудит. Permissive - нарушения только логируются, но пропускаются; это режим отладки, а не безопасности. Disabled - модуль выключен (в RHEL 9+ полностью выключить через конфиг уже нельзя, только через параметр ядра selinux=0, и так делать не надо). Булевы переключатели (booleans) - это готовые тумблеры в политике, которые включают и выключают целые куски правил без перекомпиляции, например разрешить веб-серверу исходящие сетевые соединения.

AppArmor устроен принципиально иначе: он привязывает правила не к меткам, а к пути исполняемого файла. Профиль описывает, к каким путям, capability и сетевым операциям имеет доступ конкретная программа. Профиль работает в режиме enforce (нарушения блокируются) или complain (только логируются, аналог permissive). Подход по путям проще читать и писать, но он слабее там, где важны жёсткие, текстовые ссылки, монтирования и переименования. Smack (Simplified Mandatory Access Control Kernel) - третий LSM на метках, заметно проще SELinux; применяется в основном во встраиваемых системах и в Tizen, на серверах встречается редко.

Команды и примеры

Проверить статус и режим SELinux (RHEL/Fedora):

Код: Выделить всё

getenforce              # Enforcing / Permissive / Disabled
sestatus                # подробно: текущий и из конфига режим, тип политики
setenforce 0            # временно в permissive (до перезагрузки)
setenforce 1            # обратно в enforcing
Постоянный режим задаётся в /etc/selinux/config параметром SELINUX=enforcing. После правки нужна перезагрузка.

Посмотреть контексты (флаг -Z есть у большинства утилит):

Код: Выделить всё

ls -Z /var/www/html/index.html
ps -eZ | grep httpd
id -Z                   # контекст текущего пользователя
Управление контекстами и политикой через semanage и restorecon:

Код: Выделить всё

# Назначить тип каталогу нестандартного веб-корня НАВСЕГДА (в базе fcontext)
semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
restorecon -Rv /srv/web        # применить из базы к файлам

# Открыть нестандартный порт для веб-сервера
semanage port -a -t http_port_t -p tcp 8088
semanage port -l | grep http_port_t
Разница важна: chcon меняет метку только сейчас и на лету, а после restorecon или relabel она вернётся к значению из базы. semanage fcontext пишет в базу - это правильный, переживающий перезагрузку способ.

Булевы переключатели:

Код: Выделить всё

getsebool -a | grep httpd
setsebool -P httpd_can_network_connect on   # -P = постоянно
Разбор отказа. Все отказы SELinux идут в аудит как AVC-записи:

Код: Выделить всё

ausearch -m AVC -ts recent
# либо человеко-читаемые подсказки:
sealert -a /var/log/audit/audit.log
# сгенерировать локальный модуль-исключение:
ausearch -m AVC -ts recent | audit2allow -M my_httpd_fix
semodule -i my_httpd_fix.pp
В Debian 13 / Ubuntu 24.04 LTS по умолчанию работает AppArmor:

Код: Выделить всё

aa-status                          # сколько профилей, в каком режиме
apt install apparmor-utils         # утилиты aa-*
aa-complain /etc/apparmor.d/usr.sbin.nginx   # профиль в complain
aa-enforce  /etc/apparmor.d/usr.sbin.nginx   # обратно в enforce
aa-logprof                         # интерактивно дополнить профиль по логам
На RHEL утилиты SELinux ставятся пакетами policycoreutils, policycoreutils-python-utils и setroubleshoot-server (через dnf, не yum - yum это псевдоним к dnf с RHEL 8, а в RHEL 10 уже dnf5).

Частые грабли
  • Считать permissive безопасным режимом. Permissive ничего не блокирует - это только для отладки. Прод должен быть в enforcing.
  • Чинить отказ через chcon и удивляться, что после ребута или autorelabel всё сломалось снова. Постоянное решение - semanage fcontext плюс restorecon.
  • Слепо скармливать весь audit.log в audit2allow и устанавливать модуль. Так можно разрешить лишнее. Сначала прочитайте, что именно отказано, и нет ли готового boolean.
  • Менять SELINUX=disabled в конфиге на работающей системе. После выключения метки протухают, и обратное включение требует полной перемаркировки (touch /.autorelabel плюс перезагрузка).
  • Забыть открыть нестандартный порт через semanage port - сервис не стартует, а в логе AVC на name_bind.
  • В AppArmor ждать защиты от жёстких ссылок: правила по путям обходятся через hardlink на тот же inode под другим именем, если профиль это не учитывает.
  • Отсутствие setroubleshoot-server - тогда sealert не работает и подсказок в журнале нет, остаётся только ausearch.
Мини-лаба
  • На стенде с RHEL 10 или Fedora убедитесь, что SELinux в enforcing (getenforce, sestatus).
  • Установите httpd, создайте нестандартный веб-корень /srv/site, положите туда index.html и пропишите его в DocumentRoot.
  • Перезапустите httpd, откройте страницу - получите 403. Найдите AVC через ausearch -m AVC -ts recent.
  • Назначьте тип через semanage fcontext -a -t httpd_sys_content_t '/srv/site(/.*)?' и примените restorecon -Rv /srv/site. Проверьте доступ.
  • Переведите httpd слушать порт 8088, через semanage port -a -t http_port_t -p tcp 8088 разрешите его, перезапустите.
  • Включите подходящий boolean (например httpd_can_network_connect) и убедитесь через getsebool, что значение постоянное.
  • Бонус на Ubuntu 24.04: aa-status, переведите профиль nginx в complain, вызовите нарушение, посмотрите лог, верните enforce через aa-enforce.
Контрольные вопросы
  • Чем MAC отличается от DAC и почему root не всемогущ при включённом SELinux в enforcing?
  • Из каких полей состоит контекст безопасности и какое из них решающее в целевой политике?
  • В чём разница между chcon, semanage fcontext и restorecon - что переживает перезагрузку и почему?
  • Какой режим SELinux пригоден для отладки и почему его нельзя оставлять на проде?
  • Как из AVC-отказа получить рабочий локальный модуль политики и какие тут опасности?
  • Чем модель AppArmor по путям принципиально отличается от модели SELinux по меткам и где у каждой слабые места?
👍3 ❤️1 🔥3 😄 🤔1
Аватара пользователя
Nikdodin
Сообщения: 2
Зарегистрирован: 22 май 2026, 14:55

Re: Мандатный контроль доступа: SELinux и AppArmor [333.2]

Сообщение Nikdodin »

А если у меня нестандартный веб-корень в /opt, restorecon же не знает про него - надо сначала semanage fcontext добавить, потом restorecon? Иначе он мне default_t влепит?
👍 ❤️1 🔥 😄 🤔
Аватара пользователя
wizard_grisha
Сообщения: 1
Зарегистрирован: 30 май 2026, 01:45

Re: Мандатный контроль доступа: SELinux и AppArmor [333.2]

Сообщение wizard_grisha »

На permissive поймал AVC только когда в проде включил enforcing - оказалось пол-логов копилось молча. Теперь делаю audit2why перед переключением.
👍1 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Дискреционный контроль доступа: ACL и атрибуты [333.1]
Следующая глава →
Усиление сетевой защиты [334.1]

Все главы курса «LPIC-3 303: безопасность Linux»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-3 303: безопасность Linux»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость