Главная / База знаний / SELinux и AppArmor: базовая настройка мандатного контроля доступа
инструкция · 30 октября 2026

SELinux и AppArmor: базовая настройка мандатного контроля доступа

Разбираем, что мандатный контроль доступа добавляет к обычным правам Unix, как переключать режимы SELinux и AppArmor, находить и чинить отказы, и когда на VPS это действительно нужно, а когда избыточно.

Зачем нужен ещё один слой контроля доступа поверх прав Unix

Обычные права доступа Unix — модель дискреционного контроля (DAC, discretionary access control): решение о том, кто может читать, писать или выполнять файл, принимает владелец файла или процесс, действующий от его имени, через chmod и chown. Эта модель прекрасно работает для повседневных задач, но у неё есть фундаментальное ограничение — суперпользователь root в этой модели всемогущ, а любой процесс, скомпрометированный через уязвимость в приложении, автоматически наследует все права своего пользователя без дополнительных барьеров.

Мандатный контроль доступа (MAC, mandatory access control) добавляет второй, независимый уровень проверки, который принудительно применяется ядром вне зависимости от намерений владельца файла или процесса. Политика описывает, какие действия разрешены конкретному домену процесса по отношению к конкретным типам объектов, и эта политика не может быть изменена самим процессом или даже пользователем root без явного административного действия по её модификации.

Практический смысл для веб-сервера на VPS: если процесс PHP-FPM или nginx скомпрометирован через уязвимость в приложении и злоумышленник получил возможность выполнять код от имени www-data, обычные права Unix ограничивают его лишь тем, что доступно этому пользователю — а на сервере с несколькими сайтами это часто означает доступ к файлам соседних проектов. Политика MAC дополнительно ограничивает процесс веб-сервера конкретным набором путей и действий, даже если формальные права Unix этого не запрещают.

Две основные реализации MAC в Linux — SELinux (Security-Enhanced Linux, изначально разработан NSA, используется по умолчанию в семействе RHEL) и AppArmor (используется по умолчанию в Debian, Ubuntu и SUSE). Они решают одну задачу разными способами: SELinux размечает метками (контекстами) и файлы, и процессы, а AppArmor привязывает профили напрямую к путям исполняемых файлов. Дальше в статье обе системы разбираются по отдельности, с реальными командами диагностики и исправления типичных отказов.

SELinux: контексты, домены и три режима работы

В основе SELinux лежит понятие security context — метки вида user:role:type:level, присвоенной каждому процессу и каждому объекту файловой системы. На практике для веб-администратора важнее всего третье поле, type — оно определяет так называемый type enforcement, основной механизм принятия решений: политика описывает, каким типам процессов (доменам) разрешено взаимодействовать с какими типами объектов и каким именно образом.

Например, процесс nginx работает в домене httpd_t, а файлы типового веб-каталога размечены типом httpd_sys_content_t — политика по умолчанию разрешает этому домену читать файлы этого типа, но не разрешает, скажем, писать в них или обращаться по сети к произвольным портам без отдельного разрешения. Именно эта детализация — не общий доступ по правам пользователя, а точное описание допустимых операций для конкретной пары «домен — тип объекта» — и составляет практическую ценность SELinux.

Проверка текущего режима и общего статуса SELinux
getenforce
# Enforcing

sestatus
# SELinux status:                enabled
# SELinuxfs mount:               /sys/fs/selinux
# Current mode:                  enforcing
# Mode from config file:         enforcing

SELinux работает в одном из трёх режимов. Enforcing — политика применяется в полной мере: запрещённые действия блокируются и записываются в журнал аудита. Permissive — все нарушения политики только логируются, но фактически разрешаются, что делает этот режим удобным инструментом диагностики перед включением полной защиты. Disabled — модуль SELinux в ядре вообще не загружается, метки не проверяются и не поддерживаются, что фактически означает полное отсутствие MAC на системе.

Переключение режима и файл конфигурации

Временное переключение режима без перезагрузки выполняется командой setenforce — это удобно для быстрой диагностики: временно перевести систему в permissive, воспроизвести проблему, посмотреть, какие обращения были бы заблокированы в enforcing, и вернуть строгий режим обратно.

Временное и постоянное переключение режима SELinux
# временно перейти в permissive (до перезагрузки)
setenforce 0

# вернуть enforcing
setenforce 1

# постоянная настройка — файл /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted

Важный нюанс: setenforce меняет режим только до перезагрузки, а постоянное значение задаётся в файле /etc/selinux/config параметром SELINUX. Если требуется перейти из disabled в enforcing или permissive (или наоборот из любого включённого режима в disabled), одной правки конфигурационного файла недостаточно — при следующей загрузке система должна выполнить полную релаблировку файловой системы, иначе метки файлов будут отсутствовать или не соответствовать текущей политике, что приводит к массовым отказам в доступе или неработающей системе целиком.

Запуск полной релаблировки файловой системы при следующей загрузке
touch /.autorelabel
reboot

Именно поэтому решение полностью отключать SELinux в момент, когда он «мешает», обходится дороже, чем кажется: вернуть его обратно спустя месяцы эксплуатации — это не правка одной строчки конфигурации, а полная релаблировка всей файловой системы с риском не загрузиться, если что-то в процессе пойдёт не так на продакшн-сервере.

Метки файлов: ls -Z, chcon, restorecon и semanage fcontext

Частый источник путаницы на практике — файлы, скопированные или перемещённые в веб-каталог из другого места (например, из домашней директории пользователя при развёртывании через git или rsync), сохраняют исходную метку типа и не получают автоматически тип, ожидаемый политикой для веб-контента. Права доступа Unix у файла при этом могут быть совершенно правильными, но SELinux в enforcing всё равно заблокирует к нему доступ, поскольку тип объекта не соответствует ожидаемому для домена httpd_t.

Просмотр контекстов безопасности файлов флагом -Z
ls -Z /var/www/html/
# unconfined_u:object_r:httpd_sys_content_t:s0 index.php
# unconfined_u:object_r:user_home_t:s0        uploaded.php

В примере выше файл uploaded.php сохранил тип user_home_t, характерный для домашних каталогов, а не httpd_sys_content_t, ожидаемый для веб-контента, — это ровно та ситуация, когда nginx или PHP-FPM получат отказ в доступе к файлу, несмотря на корректные права владельца и группы. Команда restorecon возвращает файлу тип, определённый политикой по умолчанию для его расположения, и обычно решает проблему без ручного подбора нужного типа.

Восстановление и назначение контекстов: временное и постоянное решение
# восстановить контекст по умолчанию для конкретного пути
restorecon -Rv /var/www/html/

# временно назначить конкретный тип вручную (не переживёт restorecon)
chcon -t httpd_sys_content_t /var/www/html/uploaded.php

# постоянное правило для нестандартного пути веб-контента
semanage fcontext -a -t httpd_sys_content_t '/data/mysite(/.*)?'
restorecon -Rv /data/mysite/

Разница между chcon и связкой semanage fcontext plus restorecon принципиальна: chcon меняет метку только у существующего файла и будет сброшена обратно к значению по умолчанию при следующем восстановлении контекста (например, после обновления пакета или ручного restorecon), тогда как semanage fcontext добавляет правило в саму политику для указанного пути, и оно сохраняется для всех новых файлов, создаваемых по этому пути в будущем. Отдельный инструмент точной настройки — булевы переключатели (booleans), например httpd_can_network_connect, разрешающий httpd-процессам исходящие сетевые соединения (нужен, если nginx или Apache работают как реверс-прокси к бэкенду на другом порту или хосте).

Просмотр и постоянное включение булева параметра политики
getsebool httpd_can_network_connect
setsebool -P httpd_can_network_connect on

Диагностика отказов через журнал аудита и audit2allow

Каждый заблокированный SELinux вызов записывается в журнал аудита как событие типа AVC (Access Vector Cache) с указанием домена процесса, типа объекта, запрошенного действия и результата. Именно этот журнал — первый и главный источник информации при любом непонятном отказе в доступе на системе с включённым SELinux, и полагаться на догадки вместо чтения журнала — частая ошибка, ведущая к необоснованному отключению защиты.

Поиск недавних отказов SELinux через ausearch
ausearch -m avc -ts recent
# type=AVC msg=audit(...): avc:  denied  { write } for  pid=1234 comm="nginx"
# name="uploaded.php" scontext=system_u:system_r:httpd_t:s0
# tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file

В выводе видно всё необходимое для диагностики: какой процесс (comm="nginx"), какое действие (write), к какому объекту (uploaded.php) с каким типом (tcontext, user_home_t) было запрошено, и в каком домене находится сам процесс (scontext, httpd_t). В большинстве случаев несоответствие типа объекта ожидаемому и есть причина отказа — и решается оно restorecon или semanage fcontext, как показано в предыдущем разделе, без создания какой-либо новой политики.

Если же отказ вызван не неправильной меткой файла, а действительно отсутствующим в политике разрешением для легитимной операции приложения, применяется audit2allow — утилита, которая читает записи AVC из журнала и генерирует минимальный модуль политики, разрешающий именно эти конкретные операции.

Генерация и установка точечного модуля политики на основе последних отказов
ausearch -m avc -ts recent | audit2allow -M mymodule
semodule -i mymodule.pp

Важная оговорка про audit2allow: инструмент буквально транслирует в разрешение всё, что было заблокировано в журнале за указанный период, включая записи, которые могли появиться из-за реальной атаки или ошибочной конфигурации приложения, а не из-за легитимной, но не описанной в политике операции. Сгенерированный модуль стоит просматривать перед установкой (audit2allow без -M просто выводит предполагаемое правило на экран) и устанавливать только те строки, которые действительно соответствуют ожидаемому поведению приложения, а не устанавливать модуль вслепую как быстрый способ заставить ошибку исчезнуть.

AppArmor: профили, привязанные к путям, а не к меткам

AppArmor решает ту же задачу — ограничение действий процесса сверх обычных прав Unix — принципиально иначе, чем SELinux: вместо разметки меток на файлах и процессах он привязывает текстовый профиль напрямую к пути исполняемого файла программы. Профиль перечисляет, к каким путям файловой системы программа может обращаться и в каком режиме (чтение, запись, выполнение), а также какие возможности ядра (capabilities) и сетевые операции ей разрешены.

Просмотр загруженных профилей AppArmor и их текущего режима
aa-status
# apparmor module is loaded.
# 12 profiles are loaded.
# 8 profiles are in enforce mode.
#    /usr/sbin/nginx
#    /usr/sbin/sshd
# 4 profiles are in complain mode.
#    /usr/bin/man

У AppArmor, как и у SELinux, два основных рабочих режима на уровне отдельного профиля — enforce, где нарушения профиля блокируются и логируются, и complain, где нарушения только логируются, но действие разрешается. Ключевое отличие от SELinux в подходе к охвату системы: AppArmor обычно поставляется с профилями лишь для отдельных, заранее выбранных дистрибутивом программ (в первую очередь сетевые демоны), а не пытается разметить политикой всю систему целиком — программы без профиля работают полностью неограниченно, как если бы AppArmor не был установлен вовсе.

Профили хранятся в каталоге /etc/apparmor.d/ и именуются по пути к бинарному файлу с точками вместо слэшей — например, профиль для /usr/sbin/nginx будет называться usr.sbin.nginx. Формат профиля читаем без специальной подготовки: строки вида /var/www/** r разрешают рекурсивное чтение каталога, /var/log/nginx/*.log w — запись в лог-файлы, и так далее, с явным перечислением разрешённых путей и режимов доступа к ним.

Управление профилями: enforce, complain и генерация нового профиля

Перевод конкретного профиля в permissive-подобный режим для диагностики выполняется командой aa-complain с указанием пути к профилю или к самому бинарному файлу — это позволяет временно разрешить все действия программы, продолжая при этом логировать всё, что было бы заблокировано в enforce, и затем на основе этого журнала точечно доработать профиль.

Переключение режима отдельного профиля AppArmor
# перевести профиль nginx в режим наблюдения без блокировок
aa-complain /etc/apparmor.d/usr.sbin.nginx

# вернуть строгий режим после проверки
aa-enforce /etc/apparmor.d/usr.sbin.nginx

# полностью выгрузить профиль из ядра (не рекомендуется на постоянной основе)
aa-disable /etc/apparmor.d/usr.sbin.nginx

Для программы, у которой профиля ещё нет вовсе, пакет apparmor-utils предоставляет интерактивный инструмент aa-genprof: он запускает наблюдение за работой указанной программы, и по мере того, как вы вручную выполняете типичные для неё операции (открываете сайт в браузере, загружаете файл, обращаетесь к базе данных), утилита фиксирует, какие пути и возможности программа реально использует, и в конце предлагает создать профиль на основе этих наблюдений.

Интерактивное построение нового профиля AppArmor на основе наблюдаемого поведения
aa-genprof /usr/local/bin/myapp
# ... выполните типичные операции приложения в другом терминале ...
# затем в aa-genprof нажмите S для сканирования журнала и просмотра предложений

Сгенерированный таким способом профиль обязательно нужно просмотреть вручную перед переводом в enforce: автоматически предложенные разрешения основаны только на том, что реально было замечено во время сессии наблюдения, и если какой-то редкий, но легитимный сценарий использования программы (например, ежемесячная задача по расписанию) не был выполнен во время записи, соответствующее разрешение просто не попадёт в профиль, и при первом же реальном срабатывании этого сценария программа получит отказ в enforce-режиме.

Какой дистрибутив что использует по умолчанию

Выбор конкретной реализации MAC — это в первую очередь решение конкретного дистрибутива, а не то, что стоит менять произвольно на отдельном сервере. RHEL и все его производные — CentOS Stream, AlmaLinux, Rocky Linux, а также Fedora — используют SELinux, включённый в режиме enforcing из коробки с политикой targeted (то есть замкнутый набор системных сервисов, для которых определены домены, тогда как остальные процессы работают в широком unconfined-домене).

Debian, Ubuntu и производные от них дистрибутивы используют AppArmor, но с более узким охватом по умолчанию: профили из коробки включены для ограниченного набора сетевых сервисов (в частности, для установленных через пакетный менеджер демонов вроде nginx, MySQL, некоторых почтовых серверов), тогда как для произвольных приложений, установленных вручную или через сторонние репозитории, профиль отсутствует и не создаётся автоматически. openSUSE и SUSE Linux Enterprise также используют AppArmor как штатный механизм, с более широким набором профилей по умолчанию, чем в Ubuntu.

Практический вывод для администратора VPS: не стоит пытаться перенести SELinux на Ubuntu-сервер или AppArmor на CentOS-сервер, копируя опыт с другого дистрибутива — оба механизма плотно завязаны на пакеты и политики, поставляемые конкретным дистрибутивом, и попытка использовать «не свою» систему MAC на дистрибутиве, для которого она не является штатной, обернётся значительным объёмом ручной работы без соответствующей поддержки со стороны пакетной базы дистрибутива.

Когда MAC на VPS действительно оправдан, а когда это лишняя нагрузка

Ценность мандатного контроля доступа сильнее всего проявляется на серверах, где на одной машине сосуществует несколько независимых зон ответственности — например, несколько сайтов разных клиентов на одном VPS, или веб-приложение вместе с другими сервисами, к данным которых оно в норме доступа иметь не должно. В такой конфигурации компрометация одного компонента через уязвимость в приложении при включённом и правильно настроенном MAC ограничивается доменом этого компонента и не даёт автоматического доступа к файлам соседних доменов, даже если обычные права Unix формально это не запрещают.

На VPS с единственным приложением и доверенным административным доступом предельная польза от тонкой настройки MAC ниже — но штатная настройка дистрибутива (SELinux enforcing на RHEL-семье, базовые AppArmor-профили на Debian-семье) всё равно стоит того, чтобы её оставить как есть: она не требует дополнительных усилий по умолчанию и обеспечивает хотя бы базовое ограничение на случай эксплуатации уязвимости именно в самом веб-сервере или интерпретаторе, а не в коде приложения.

Ситуация, где ручная тонкая настройка MAC реально требует заметных трудозатрат, — сложные многокомпонентные системы с нестандартными путями хранения данных, взаимодействием нескольких демонов через нетипичные Unix-сокеты или порты, и частыми изменениями конфигурации. Для типичного стека вида nginx плюс PHP-FPM плюс MySQL с данными в стандартных каталогах штатная политика дистрибутива в подавляющем большинстве случаев работает без вмешательства администратора вообще.

Практические рекомендации и типичные ошибки

Самая частая и вредная практика — воспринимать permissive (SELinux) или complain (AppArmor) как постоянное решение проблемы вместо диагностического шага. Оба режима задуманы как временный этап: воспроизвести проблему, увидеть в журнале, что было бы заблокировано, внести точечное исправление и вернуть строгий режим — оставлять систему навсегда в этом состоянии равносильно отключению защиты, только с сохранением видимости, что она формально «включена».

Любое изменение политики или профиля, затрагивающее продакшн-сервер, стоит сначала проверить на тестовом окружении с той же версией дистрибутива и тем же стеком приложений — особенно правила, сгенерированные автоматически через audit2allow или aa-genprof, поскольку они основаны на наблюдаемом поведении конкретного запуска и могут не покрывать редкие, но легитимные сценарии.

Стоит вести учёт всех отклонений от политики или профиля по умолчанию — какие булевы параметры SELinux включены, какие пользовательские модули политики установлены, какие профили AppArmor переведены в enforce вручную. При переустановке сервера, миграции на новый VPS или восстановлении из бэкапа эти изменения не восстанавливаются автоматически вместе с файлами приложения, и их отсутствие на новой машине легко принять за ту же самую «непонятную ошибку доступа», которую однажды уже решили и забыли задокументировать.

Наконец, важно помнить, что мандатный контроль доступа — это дополнительный слой обороны, а не замена базовой гигиены сервера: правильно настроенный firewall, ограничение доступа по SSH через ключи, регулярные обновления пакетов и минимально необходимый набор запущенных сервисов остаются такой же обязательной частью защиты VPS, как и правильно настроенный SELinux или AppArmor поверх них.

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

Зачем нужен SELinux или AppArmor, если уже настроен firewall и права доступа на файлы?

Firewall контролирует сетевые соединения, а права Unix — это модель, где владелец файла или процесс, запущенный от определённого пользователя, сам решает, что разрешить. Мандатный контроль доступа добавляет третий, независимый от воли владельца слой: даже если процесс технически имеет право на файл по обычным правам Unix, политика ядра может это действие запретить, если оно не описано явно для данного домена.

Правда ли, что многие администраторы просто отключают SELinux при первой ошибке?

Да, это распространённая и вредная практика — команда setenforce 0 или полное отключение в /etc/selinux/config действительно быстро убирает симптом, но вместе с этим убирает целый защитный слой навсегда, вместо того чтобы потратить пять минут на ausearch и audit2allow и найти точечное решение.

Можно ли использовать SELinux на Ubuntu, а AppArmor на CentOS?

Технически можно установить пакеты обеих систем на любой дистрибутив, но это нестандартная конфигурация: политики и профили, поставляемые с пакетами дистрибутива, рассчитаны именно на штатный механизм MAC этого дистрибутива, и совместная работа обеих систем на одном хосте не поддерживается и не имеет смысла.

Что делать, если после включения enforcing сайт перестал открываться?

Проверить /var/log/audit/audit.log на записи type=AVC с отказом для процесса веб-сервера, определить, какого правила не хватает, и добавить точечное разрешение через restorecon (если дело в метке файла) или через audit2allow и semanage boolean, а не откатываться в permissive или disabled.

Замедляет ли SELinux или AppArmor работу сервера?

Накладные расходы на проверку политики при каждом системном вызове измеримы, но на современном железе для типичной веб-нагрузки они пренебрежимо малы по сравнению с временем обработки запроса самим приложением и базой данных — снижение производительности не является практической причиной отключать MAC на VPS.

Как быстро понять, в каком режиме сейчас работает SELinux или AppArmor?

Для SELinux — команда getenforce выведет Enforcing, Permissive или Disabled одним словом. Для AppArmor — команда aa-status покажет список загруженных профилей с указанием режима enforce или complain для каждого.

Нужно ли настраивать SELinux или AppArmor на VPS с единственным личным сайтом?

Строгой необходимости нет, если сервер обслуживает один проект и админ-доступ ограничен только вами, но и вреда штатная настройка дистрибутива не приносит — разумная стратегия для такого случая: не трогать штатный режим и донастраивать точечно, только если он реально мешает конкретной задаче.

Что произойдёт, если включить SELinux обратно после долгого времени в отключённом состоянии?

Файловая система будет содержать неправильные или отсутствующие метки безопасности почти везде, и система с большой вероятностью не загрузится нормально или откажет в доступе почти всем процессам — включать нужно только через полную релаблировку файловой системы при следующей перезагрузке.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.