Веб‑сервисы живут на стыке множества компонентов: веб‑сервер, PHP‑FPM или приложение на Node.js/Python, база данных, кэш, очереди, файловые хранилища. Когда что‑то из этого компрометируют, обычные Unix‑права и systemd‑sandboxing уже не спасают: процессу нужны сетевые и файловые доступы, и он их имеет. Здесь включаются механизмы LSM (Linux Security Modules) — AppArmor и SELinux, которые принудительно ограничивают поведение сервисов правилами безопасности (политикой). Разберёмся, чем они отличаются, что выбрать для VDS с веб‑нагрузкой и как включить «минимум боли» без простоя.
Модель безопасности: в чём разница
Оба решения — части подсистемы LSM, но философия разная.
- SELinux — модель type enforcement: у субъектов и объектов есть контексты (типы), а политика описывает, кто что может делать с кем. Имеет мощные механизмы MLS/MCS, богатые политики для веб‑стека, детальный аудит.
- AppArmor — path‑based контроль: профили описывают, какие пути файлов доступны процессу и какие операции разрешены. Правила проще читать, быстрее начать, меньше рутины с метками.
Если нужна максимальная строгость в гетерогенной среде — чаще выигрывает SELinux. Если важно быстро включить базовый hardening без погружения в метки — AppArmor удобнее.
Где что «родное» и почему это важно для VDS
На RHEL/Alma/Rocky/Fedora SELinux — стандарт, политики поставляются и обкатаны в продакшене. На Ubuntu/Debian по умолчанию доступен AppArmor, профили есть в пакетах, интеграция с сервисами хорошая. Для VDS выбор дистрибутива фактически определяет, с чем стартовать. Смешивать «чужую» технологию можно, но это увеличивает трудозатраты и риск.
Если используете панель для управления сервером, оценивайте её совместимость с LSM и миграционные сценарии. Для выбора панелей смотрите наше сравнение панелей управления для VDS.
Что даёт «минимальный запуск» политики для веб
- Процесс веб‑сервера/приложения не сможет записать в произвольный путь (например, вместо
/var/www/app/uploads
— в/etc
). - Исходящий сетевой доступ ограничивается (например, запрет на произвольные коннекты из
nginx
илиphp-fpm
). - Эксплойт в плагине/библиотеке ломает меньше: политика «сдерживает» последствия.
- Понятный аудит: в логах видно, что было запрещено и почему.
Минимум по SELinux для веб‑сервисов
Проверка и режим
На RHEL‑семействе SELinux обычно уже установлен. Проверим состояние и переведём в безопасный режим для теста:
getenforce
sestatus
sudo setenforce 0 # permissive для «прогона» трафика и сбора AVC
# Постоянный режим в /etc/selinux/config, когда будете готовы:
# SELINUX=enforcing
Если пакеты не установлены, добавьте базовый набор для администрирования и диагностики:
sudo dnf install selinux-policy-targeted policycoreutils policycoreutils-python-utils setroubleshoot-server
Базовые boolean‑настройки для веб
SELinux даёт десятки готовых переключателей (booleans), которые включают строго дозированные разрешения без переписывания политики.
httpd_can_network_connect
— нужен, если веб‑сервер/скрипты ходят к внешним API, upstream’ам или в бэкенд на нестандартных портах.httpd_can_network_connect_db
— доступ из веб‑слоя к внешней БД.httpd_can_sendmail
— если почта отправляется напрямую (часто не нужно).
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect_db on
# Включайте только то, что реально используется — меньше поверхность атаки.
Метки файлов: RW только там, где нужно
Классическая ошибка — давать записи по всему /var/www
. В SELinux «правильная» запись для веб‑слоя — тип httpd_sys_rw_content_t
, а для чтения — httpd_sys_content_t
. Метки назначаются не вручную chcon
, а через постоянные правила:
# Разрешаем веб‑слою писать только в uploads/cache/tmp каталоги приложения
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/app/uploads(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/app/cache(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/app/tmp(/.*)?"
# Применяем метки на файловую систему
sudo restorecon -Rv /var/www/app/uploads /var/www/app/cache /var/www/app/tmp
Если nginx
слушает нестандартный порт (например, 8080), добавьте его в тип http_port_t
:
sudo semanage port -a -t http_port_t -p tcp 8080
Диагностика запретов (AVC) без паники
# Последние запреты
sudo ausearch -m AVC -ts recent
# Человекочитаемые рекомендации (анализатор)
sudo sealert -a /var/log/audit/audit.log
Совет: не поддавайтесь соблазну генерировать широкие allow‑модули из всего аудита. Сначала проверьте, решается ли кейс boolean’ом или корректной меткой файлов. Это и безопаснее, и поддерживаемее.
Минимум по AppArmor для веб‑сервисов
Установка и статус
На Ubuntu/Debian AppArmor обычно уже включён. Базовые пакеты и проверка:
sudo apt update
sudo apt install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra
sudo aa-status
Для распространённых демонов профили ставятся вместе с пакетами. Если профиль есть, переведите его в режим обучения (complain), прогоните типичный трафик и потом включите в enforce:
# Пример для nginx и php-fpm (имена профилей зависят от дистрибутива)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
sudo aa-complain /etc/apparmor.d/usr.sbin.php-fpm
# После прогона трафика и правок профиля
tail -f /var/log/syslog | grep DENIED
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
sudo aa-enforce /etc/apparmor.d/usr.sbin.php-fpm
Локальные донастройки: RW‑каталоги и сокеты
Обычно нужно запретить запись везде, кроме каталогов вроде uploads
, cache
, tmp
, и разрешить доступ к Unix‑сокетам PHP‑FPM. Выносите изменения в локальные include‑файлы, чтобы не конфликтовать с пакетными обновлениями.
# /etc/apparmor.d/local/usr.sbin.nginx
#include <tunables/global>
# Локальные дополнения для nginx
/var/www/** r,
/var/www/app/{uploads,tmp,cache}/** rwk,
/var/log/nginx/** rw,
/run/php/php*.sock rw,
После правок профиля выполните перезагрузку профилей или демона:
sudo systemctl reload apparmor
sudo systemctl reload nginx
Создание/обучение профиля по логам
AppArmor умеет «вести за руку» через aa-logprof
, предлагая правила на основе зафиксированных запретов. Запустите трафик, затем:
sudo aa-logprof
Проходите предложения, но не соглашайтесь на бездумные шаблоны вроде «разрешить /** rw
». Оставляйте минимум, необходимый для бизнес‑логики.
Поиск отказов
sudo journalctl -k -g 'apparmor="DENIED"'
sudo grep DENIED /var/log/syslog

Контейнеры, прокси и как они влияют на политику
Реальные веб‑развёртывания часто используют обратные прокси и контейнеры. Это влияет на минимальный набор разрешений.
- Nginx как прокси: для SELinux включите только
httpd_can_network_connect
(и, при необходимости, добавьте нестандартные порты). В AppArmor добавьте сетевые правила и upstream‑сокеты. - PHP‑FPM через Unix‑сокет: в AppArmor разрешите
/run/php/php*.sock
для веб‑процесса. В SELinux это покрывается штатной политикой (httpd_t
↔init_var_run_t
), обычно без ручных правок. - Docker/Podman: по умолчанию Docker включает профиль AppArmor docker-default. В SELinux контейнеры работают в домене
container_t
; для шаринга директорий используйте корректную маркировку (тома монтируйте с правильными контекстами). Не расширяйте привилегии контейнеру без необходимости.
Как выбирать между AppArmor и SELinux для веб‑нагрузки
- Ubuntu/Debian на VDS: AppArmor даёт быстрый выигрыш — включили профиль веб‑сервера, описали RW‑каталоги, проверили логи, перевели в enforce.
- RHEL‑семейство на VDS: SELinux «из коробки» с годами накопленной практики. Держите targeted‑политику, не отключайте, работайте через booleans и метки.
- Сложные многокомпонентные инсталляции и мульти‑тенант: склоняйтесь к SELinux ради строгих доменов, хорошей изоляции и детального аудита.
- Малые LEMP‑развёртывания и быстрый старт hardening: AppArmor проще внедрить без глубокого погружения.
Пошагово: включаем минимум без простоя
SELinux (RHEL/Alma/Rocky/Fedora)
- Переведите в permissive:
setenforce 0
. Прогоните типичный прод‑трафик несколько часов. - Посмотрите AVC‑запреты, сопоставьте их с задачами сервиса. Включите нужные booleans вместо генерации своих модулей.
- Маркируйте только необходимые для записи каталоги приложения. Не используйте
chcon
вместоsemanage fcontext
— иначе метки собьются при restorecon и обновлениях. - Добавьте нестандартные http‑порты в
http_port_t
, если нужно. - Переключите в enforcing, наблюдайте логи. Держите план отката: вернуться в permissive одной командой.
AppArmor (Ubuntu/Debian)
- Убедитесь, что профили загружены и сервисы видны в
aa-status
. - Переведите веб‑демоны в complain, прогоните трафик, соберите «DENIED» из журналов.
- Откорректируйте локальные include‑файлы: чтение для кода и статики, запись только в
uploads/cache/tmp
, сокеты бэкенда по необходимости. - Запустите
aa-logprof
и точечно примите нужные правила. Избегайте широких масок. - Переведите в enforce, наблюдайте журналы и донастраивайте минимальными шагами.
Частые ошибки и как их избежать
- «Широкие» разрешения из лога: не принимайте автогенерированные правила «всё можно». Разбирайтесь в причинах запретов.
chcon
вместо постоянных правил в SELinux: метки потеряются. Используйтеsemanage fcontext
+restorecon
.- Разрешение опасных boolean’ов без нужды: например,
httpd_execmem
. Держите их выключенными, если не уверены, что они действительно нужны. - Забытый нестандартный порт:
nginx
на 8080, приложение на 3000 — добавьте их в допустимые типы/правила. - Смешивание политик и ручных правок: поддерживайте изменения в одном месте (локальные include’ы AppArmor,
semanage
в SELinux).
Совместный hardening
AppArmor/SELinux — не панацея. Дополняйте их базовым hardening уровня ОС и сервисов: изолированные Unix‑пользователи для демонов, корректные права POSIX/ACL, системные лимиты, бережная настройка systemd‑юнитов (ограничение каталогов, окружения, пространств имён), актуальные обновления и строгие политики брандмауэра. Для Nginx пригодятся и прикладные техники — например, Secure Link и TTL для защиты ресурсов.
Итоги
Для веб‑сервисов на VDS верная стратегия — не выключать LSM, а включить минимальную, но осмысленную политику. На системах RHEL‑семейства SELinux даёт мощный набор «из коробки»: включайте booleans, корректно маркируйте RW‑каталоги и держите enforcing. На Ubuntu/Debian AppArmor позволяет быстро получить заметный прирост безопасности: профили читаемы, локальные доработки просты, а режим complain помогает безопасно пройти этап обучения. Начните с малого — и поверхность атаки сузится без побочных эффектов и простоев.