Когда речь заходит про hardening Debian/Ubuntu, почти всегда всплывает выбор: AppArmor или SELinux. Оба механизма относятся к MAC (Mandatory Access Control): они добавляют поверх обычных прав Linux (DAC) дополнительные ограничения, которые действуют даже для root. Но устроены они по-разному, и это напрямую влияет на внедрение, отладку и сопровождение.
Ниже — практичный разбор для админов и devops: где AppArmor удобнее, где SELinux даёт больше контроля, как быстро проверить состояние, что смотреть в логах и как не превратить включение политик в историю «всё упало, откатываем».
Короткая карта отличий: как устроены AppArmor и SELinux
AppArmor — профильная модель: правила привязаны к пути к исполняемому файлу (например, /usr/sbin/nginx) и описывают, какие файлы, сокеты и capability этому процессу можно использовать. Плюс в том, что профиль обычно читается интуитивно: «этому бинарнику можно читать вот тут, писать вот тут».
SELinux — меточная (label-based) модель: объекты (файлы, процессы, порты) имеют контексты безопасности. Политики описывают взаимодействия доменов (типов) и классов объектов. Это мощнее, но требует дисциплины с контекстами и понимания причинно-следственных связей «почему этот домен не может писать в этот тип файла».
Практическая разница для админа
AppArmor проще стартовать на Ubuntu: много готовых профилей, понятный workflow, быстрый эффект для типовых демонов.
SELinux гибче и глубже в сложных системах: много сервисов на одном хосте, строгая сегментация, контейнерные хосты, требования аудита.
Сопровождение: у AppArmor чаще встречается «сломалось после смены пути/юнита», у SELinux — «сломалось из-за контекста (маркировки)».
Что по умолчанию в Debian и Ubuntu
Ubuntu традиционно ориентируется на AppArmor: он обычно установлен и интегрирован «из коробки». Многие пакеты (включая веб-серверы и системные демоны) поставляются с готовыми профилями.
Debian нередко ставят без явного упора на MAC, но и AppArmor, и SELinux доступны, и их можно включить осознанно. На практике выбор чаще упирается не в «что лучше», а в то, что команда сможет качественно сопровождать.
Важный организационный момент: не включайте одновременно оба механизма “в полный рост” без чёткого плана поддержки. Теоретически они могут сосуществовать, но на проде это почти всегда лишняя сложность в расследованиях.

Проверка статуса и быстрые sanity-check
Перед любыми изменениями убедитесь, что вы понимаете текущий режим и кто реально «рулит» ограничениями.
AppArmor: статус и активные профили
aa-status
Смотрите на число загруженных профилей и сколько из них в enforce/complain. Если сервис «вдруг» стал чудить после hardening, первый вопрос: есть ли профиль именно для нужного бинарника (и тот ли бинарник реально запускается systemd-юнитом).
Параллельно проверьте состояние сервисов (в проде банально экономит время):
systemctl status nginx
systemctl status ssh
systemctl status mysql
SELinux: режим и базовые признаки блокировок
getenforce
sestatus
Если Enforcing — политика реально блокирует. Если Permissive — блокировки не применяются, но события логируются (идеально для безопасной «примерки» перед включением в enforce).
Практика для продакшена: сначала докажите, что проблема именно в MAC (есть deny/avc в логах), и только потом расширяйте политики. Иначе легко «вылечить» не то, например ошибку в путях, правах или unit-файле.
Режимы работы: Enforce vs Complain/Permissive
У обоих подходов есть «мягкий режим», который позволяет собрать сигналы без простоя:
AppArmor: режим complain (нарушения логируются, но не блокируются).
SELinux: режим Permissive (аналогично — лог вместо запрета).
Совет по внедрению: начинайте с мягкого режима для одного конкретного сервиса, соберите события под реальной нагрузкой, затем переводите его в строгий режим. Резкое включение enforce/enforcing «для всего» почти гарантированно ломает что-то неочевидное: unix-сокеты, временные директории, кастомные пути логов, PID-файлы, cache.
Если вы как раз наводите порядок в веб-стеке, полезно заранее продумать изоляцию сервисов и путей. См. также: несколько пулов PHP-FPM под разные сайты и пользователей.
Отладка AppArmor: где искать причины и как править профиль
Самая частая боль AppArmor — сервис работает, пока вы не поменяли путь к файлам, логам или сокетам. Например: перенесли root сайта, добавили каталог под загрузки, изменили директорию логов, вынесли PHP-FPM сокет в нестандартное место.
Логи AppArmor и разбор нарушений
Ищите записи типа DENIED в журнале ядра:
journalctl -k -g apparmor --no-pager
На некоторых системах события попадаются и без -k:
journalctl -g apparmor --no-pager
Дальше обычно достаточно двух инструментов:
aa-logprof— интерактивно предлагает изменения в профиле на основе логов.aa-status— подтверждает, что профиль загружен и в каком режиме.
Практичный workflow AppArmor для сервиса
Проверьте, что профиль есть и применяется к нужному бинарнику (
aa-status).Переведите профиль сервиса в complain (временно), воспроизведите нагрузку или сценарий, который ломается.
Запустите
aa-logprofи добавьте минимально необходимые разрешения.Верните enforce и проверьте функциональность.
Ключевой принцип: не разрешайте «всё подряд». Если профилю выдать слишком широкие права, hardening превращается в галочку.
Отладка SELinux: audit, AVC и почему все советуют audit2allow
SELinux приучает к дисциплине: если что-то запрещено, вы должны понять, какому домену и какой тип объекта недоступен, и почему. Самая известная связка — анализ AVC и генерация подсказок/модулей через audit2allow.
Где смотреть события SELinux
Чаще всего события попадают в audit-лог. Для быстрого поиска по отказам:
ausearch -m avc -ts recent
Или по конкретному сервису (по имени процесса), если audit настроен:
ausearch -m avc -ts recent -c nginx
audit2allow: использовать осторожно
audit2allow часто воспринимают как «быстро починить». Он действительно умеет по логам предложить правила. Но в продакшене это палка о двух концах:
Он может разрешить лишнее, если вы кормили ему шумные логи или в момент сбора были подозрительные запросы.
Сгенерированный модуль может закрепить «ошибочную архитектуру», например когда сервис пишет не туда, куда должен (неправильные пути для логов/кэша/загрузок).
Нормальный порядок: сначала проверьте, не нужно ли просто исправить контексты (маркировку) под правильные директории и пути, и только затем думайте о расширении политики.

Типовые сценарии для веб-стека (Nginx/Apache, PHP-FPM, базы)
С точки зрения вебмастера и админа чаще всего страдают одни и те же места — и в AppArmor, и в SELinux:
Загрузки пользователей: веб-сервер или приложение должно писать в uploads, а политика запрещает запись.
Unix-сокеты: PHP-FPM, Redis, базы через сокет в нестандартной директории.
Логи: кастомный путь
access_log/error_logили логирование приложения в произвольный каталог.Cache/temporary: запись в
/var/cache,/tmp,/runв неожиданные места.Сторонние бинарники: приложение вызывает
convert,ffmpeg,pdftotext, а политика для основного процесса этого не ожидает.
Вывод простой: перед включением MAC полезно иметь список «реальных» путей и взаимодействий сервиса, а не пытаться навести порядок уже после того, как инфраструктура разрослась хаотично.
Что выбрать в Debian/Ubuntu: практическая рекомендация
Когда чаще выбирают AppArmor
Вы на Ubuntu и хотите быстрый, понятный hardening без глубокого погружения в SELinux-модель.
Нужна «разумная защита по умолчанию» для типовых демонов с готовыми профилями.
Команда небольшая, важно снизить стоимость сопровождения.
Когда чаще выбирают SELinux
Нужна строгая сегментация и единая модель контроля доступа на уровне контекстов.
Сложные окружения: множество сервисов, контейнеризация, требования аудита или комплаенса.
Есть опыт в команде и готовность инвестировать время в правильные политики и маркировку.
Мини-ранбук внедрения (без фанатизма)
Если цель — усилить безопасность и не убить стабильность, действуйте итеративно:
Инвентаризация: какие сервисы критичны, какие пути они используют, где запись, сокеты и кэш.
Мягкий режим для одного сервиса и сбор логов под реальной нагрузкой.
Минимальные правки политик: AppArmor через
aa-logprof, SELinux через анализ AVC и исправление контекстов (осторожно сaudit2allow).Строгий режим и контроль регрессий.
Регламент: обновления пакетов, изменения путей, новые юниты — всё это должно проходить через проверку MAC-логов.
Чек-лист диагностики «после включения всё сломалось»
Сервис вообще запустился?
systemctl status NAME.Есть ли блокировки на уровне MAC в ядровых или audit-логах?
Для AppArmor: профиль загружен и в каком режиме?
aa-status.Для SELinux: режим enforcing/permissive?
getenforce,sestatus.Связано ли падение с путями (логи, сокеты, uploads, cache) или с сетевыми правами?
Если в MAC-логах чисто, проблема, скорее всего, не в AppArmor/SELinux, а в unit-файле, правах файлов, зависимостях, лимитах systemd или сетевых настройках. Важно не «обвинять» MAC по умолчанию, а подтверждать факт блокировки.
Если вы параллельно подтягиваете «внешнюю» безопасность сайта (HTTPS, HSTS, переезды домена), держите под рукой план миграции и проверок: миграция домена: 301, HSTS и SSL без сюрпризов.
Итог
AppArmor в Debian/Ubuntu (особенно в Ubuntu) — быстрый путь к практичному hardening с понятной отладкой через aa-status и aa-logprof. SELinux — более универсальная и строгая система, но требует внимания к контекстам и аккуратности с инструментами вроде audit2allow.
Если вы внедряете MAC впервые, начните с одного сервиса, мягкого режима, логов и минимальных изменений. Такой подход даёт реальную защиту и не превращает безопасность в причину простоя.


