Что AppArmor проверяет помимо прав Linux
AppArmor — реализация мандатного контроля доступа через каркас Linux Security Modules. Он работает вместе с обычным дискреционным контролем доступа, а не вместо него: процесс должен пройти обе проверки. Поэтому корректные владельцы файла, ACL и режим chmod не гарантируют доступ, если профиль AppArmor его не разрешает.
Профиль AppArmor обычно привязан к пути исполняемого файла и задаёт, что процесс вправе читать, записывать, отображать в память и выполнять, какие capabilities использовать и какие сетевые операции совершать. Детализация сетевых ограничений зависит от версии AppArmor, ABI политики и типа сокета: базовые правила могут различать только семейство, тип и протокол, а не конкретный удалённый адрес или порт. Это путевой контроль доступа: при изменении пути бинарного файла, запуске через другую программу-обёртку или появлении дочерней программы профиль может перестать соответствовать фактическому поведению.
Правила строят по принципу наименьших привилегий: не «разрешить /var/**», а разрешить конкретному сервису его каталог данных, конфигурацию, сокет и требуемые исполняемые файлы. AppArmor — один слой hardening; место MAC в общей базовой конфигурации разобрано в статье «Базовая защита сервера: как составить security baseline».
Проверьте AppArmor status и режим нужного профиля
В типичных Ubuntu и Debian пакет apparmor предоставляет загрузчик политики apparmor_parser и утилиту проверки состояния aa-status, а пакет apparmor-utils — aa-complain, aa-enforce, aa-disable, aa-genprof и aa-logprof. Состав пакетов, имя systemd-службы, расположение журналов и доступные ключи зависят от выпуска ОС и версии AppArmor userspace. Перед изменениями сверяйте синтаксис с руководством AppArmor и документацией своего дистрибутива; ниже приведён обычный сценарий для Ubuntu и Debian.
sudo aa-statusОжидаемый результат — сообщение о том, что AppArmor загружен, и списки профилей в enforce и complain. Если команда не найдена, проверьте пакет `apparmor` и документацию своего выпуска; если AppArmor не загружен, выясните состояние пакета, ядра, параметров загрузки и политики ОС.sudo systemctl status apparmorНа systemd-системе ожидается активная служба без ошибок разбора профилей. Отсутствие этого unit не всегда означает отсутствие AppArmor: ориентируйтесь прежде всего на `aa-status` и документацию конкретного выпуска.sudo aa-status | lessЕсли профиль есть в списке enforce — не создавайте второй профиль с тем же attachment. Сначала изучите существующий файл и способ его локального расширения.Режим профиля, а не режим сервера
Поведение отдельных возможностей зависит от версии ядра, AppArmor userspace и политики дистрибутива.
| Состояние | Поведение неразрешённой операции | Практическое назначение |
|---|---|---|
enforce | Операция запрещается и обычно фиксируется в журнале как отказ. | Штатная защита работающего сервиса. |
complain | Операция, не разрешённая обычными разрешающими правилами, обычно журналируется, но не блокируется; явные правила deny продолжают применяться. | Сбор фактических потребностей приложения перед включением enforce. |
unconfined | Процесс не ограничен профилем AppArmor. | Обычное состояние процесса, для которого профиль не прикреплён. Если ранее действовавший профиль снят ради диагностики, процесс временно теряет этот слой защиты. |
Complain не означает «ничего не блокируется»
deny продолжают применяться и в complain. Также отказ может исходить от обычных прав Linux, ACL, файловой системы, seccomp или другого механизма. Поэтому complain не гарантирует работоспособность приложения и не отменяет проверку после изменения.Найдите исполняемый файл и существующую политику
Инвентаризация сервиса перед созданием профиля
Сквозной пример использует условное приложение reportd с бинарным файлом /opt/acme/bin/reportd. Это не готовый профиль для Nginx, СУБД или другого реального продукта.
- 1Зафиксируйте команду запуска службыПросмотрите unit и drop-in-файлы:
systemctl cat reportd. НайдитеExecStart=, аргументы, пользователя, рабочий каталог, файлы конфигурации, каталоги данных, сокеты и дочерние команды. Если сервис запускается не через systemd, найдите его командную строку и механизм запуска. - 2Подтвердите фактический бинарный файл запущенного процессаПолучите PID через
systemctl show -p MainPID --value reportd, затем выполнитеreadlink -f /proc/<PID>/exe. Этот путь важнее предположений по имени службы: profile attachment обычно соответствует исполняемому файлу после разрешения символьных ссылок. - 3Проверьте профиль от пакета или поставщикаИщите путь и имя приложения в
/etc/apparmor.d:sudo grep -R --line-number --fixed-strings '/opt/acme/bin/reportd' /etc/apparmor.d. Для пакетного бинарного файла проверьте владельца черезdpkg -S /путь/к/файлу. Найденный профиль сначала прочитайте вместе с его#include: пакет мог предусмотреть локальный файл для дополнений. - 4Соберите ожидаемое поведениеДо генерации правил составьте короткий список: какие конфигурации сервис читает, куда пишет данные и временные файлы, какие Unix-сокеты или TCP/UDP-соединения открывает, какие helper-программы запускает, нужны ли capabilities. Отдельно отметьте действия, которых сервис делать не должен.
sudo grep -R --line-number --fixed-strings '/opt/acme/bin/reportd' /etc/apparmor.dНет вывода — возможный признак отсутствия готового профиля, но не доказательство: attachment может быть задан иначе или профиль может быть сгенерирован и загружен из другого места. Сопоставьте результат с `aa-status`.В Ubuntu и Debian поставляемые профили обычно размещаются в /etc/apparmor.d, а отключённые профили отмечаются механизмом disable в этом дереве. Пакетное обновление может заменить основной файл профиля. Если поставляемый профиль поддерживает локальное включение, сохраняйте свои дополнения в предусмотренном локальном include-файле, часто в /etc/apparmor.d/local/…; это снижает риск перезаписи. Не создавайте второй независимый файл с тем же attachment: конфликтующие определения затрудняют сопровождение.
Создайте начальный профиль AppArmor
Есть два безопасных старта: создать минимальный профиль вручную на основе инвентаризации или использовать интерактивный aa-genprof для сбора событий. Утилита не понимает назначение приложения и не может сама отличить необходимый доступ от опасного, поэтому её предложения всегда проверяют.
sudo aa-genprof /opt/acme/bin/reportdПосле завершения проверьте созданный файл политики и фактический режим через `aa-status`: некоторые версии и сце нарии завершения `aa-genprof` загружают готовый профиль в enforce. Если сбор и функциональная проверка ещё не закончены, до продолжения работы явно переведите этот профиль в complain и снова проверьте режим. Если `aa-genprof` отсутствует, найдите пакет `apparmor-utils` для своего выпуска либо создайте профиль вручную.#include <tunables/global>
/opt/acme/bin/reportd flags=(complain) {
#include <abstractions/base>
/opt/acme/bin/reportd mr,
/etc/reportd/config.yaml r,
/var/lib/reportd/ r,
/var/lib/reportd/** rw,
/run/reportd/ r,
/run/reportd/reportd.sock rw,
capability net_bind_service,
network inet stream,
}Это учебный каркас, а не универсальная политика. Правило r разрешает чтение, w — запись, а m — исполняемое отображение файла в память, например через mmap с PROT_EXEC; завершающая запятая обязательна. /** охватывает дерево каталогов и допустим здесь только как осознанная граница каталога данных конкретного приложения. Правила capability и network добавляйте лишь после подтверждения необходимости. Абстракция AppArmor abstractions/base содержит общий базовый набор доступа к системным ресурсам, но не обязательно минимальный для конкретного сервиса. Перед включением abstractions прочитайте их содержимое и проверьте, какие разрешения они добавляют.
sudo apparmor_parser -r /etc/apparmor.d/opt.acme.bin.reportdПри успехе команда обычно не печатает сообщений. При ошибке не перезапускайте критичную службу: исправьте строку и номер, выданные parser, затем повторите загрузку. После успешной загрузки проверьте профиль через `aa-status`.Как сохранить изменение после перезагрузки
apparmor_parser меняет активную политику ядра, но не заменяет файл политики. Сохраните профиль в каталоге, который обрабатывает AppArmor при запуске ОС, и проверьте это после плановой перезагрузки или в тестовой среде. Правила размещения, локальных include и отключённых файлов различаются между выпусками и пакетами; для пакетного приложения предпочтительнее документированная схема поставщика.Соберите события в complain и переведите профиль в enforce
Безопасный переход одного профиля в enforce
Работы выполняйте в окне изменений. Для удалённого сервера оставьте вторую административную сессию и проверенный путь аварийного доступа; особенно если профиль относится к SSH, сетевому агенту или критичному приложению.
- 1Переведите только нужный профиль в complainВ типичной установке используйте
sudo aa-complain /opt/acme/bin/reportd, затем подтвердите режим черезsudo aa-status. Передавайте путь attachment либо имя профиля в форме, которую принимает ваша версия утилиты. Остальные профили эта команда не меняет. - 2Воспроизведите штатные сценарииПерезапустите
reportd, выполните его обычные запросы, фоновые задания, ротацию, работу с данными и штатное завершение. Не ограничивайтесь запуском процесса: многие зависимости проявляются только при обработке трафика, таймере или обновлении конфигурации. - 3Разберите журнал и уточните правилаДля каждого события установите профиль,
comm, PID, операцию, запрошенный путь или иной ресурс. Разрешайте действие только если оно ожидаемо для назначения сервиса. После изменения файла перезагрузите егоapparmor_parser -rи повторите сценарий. - 4Включите enforce для одного профиляВыполните
sudo aa-enforce /opt/acme/bin/reportdи сн ова проверьтеaa-status. После этого перезапустите или штатно переподключите сервис, если это требуется для применения profile attachment при новом exec, и пройдите функциональную проверку. - 5Проверьте сервис и откатПроверьте статус службы, её health-check и журнал AppArmor. Если новый enforce-отказ влияет на критичную функцию, временно верните только этот профиль в complain командой
aa-complain, зафиксируйте событие и продолжите разбор. Не выключайте AppArmor для всего хоста.
sudo aa-enforce /opt/acme/bin/reportdОжидаемый результат — нужный профиль отображается в секции enforce вывода `aa-status`. Если путь не распознан, найдите точное имя профиля в `aa-status` и сверьте форму аргумента с `aa-enforce --help` и документацией установленной версии.Где искать AppArmor denied и как читать событие
AppArmor формирует сообщения ядра, которые в зависимости от конфигурации могут попадать в systemd-journald, журнал ядра, /var/log/kern.log, /var/log/syslog или в подсистему аудита. При включённом auditd часть записей доступна в audit-журнале. Не предполагайте один источник: начните с journal, затем проверьте файловые и audit-журналы, принятые на конкретном сервере.
sudo journalctl -k --since '30 min ago' | grep 'apparmor="DENIED"'Если записи найдены, сохраните полную строку, а не только путь. Если вывода нет, проверьте `/var/log/kern.log`, `/var/log/syslog` и при наличии auditd — `sudo ausearch -m AVC -ts recent`.apparmor="DENIED" operation="open" profile="/opt/acme/bin/reportd" name="/etc/reportd/secret.key" pid=2418 comm="reportd" requested_mask="r" denied_mask="r"Состав полей зависит от типа операции, ядра и настроек аудита.
| Поле | Что установить |
|---|---|
profile | Какой профиль ограничил процесс. Это ключ к нужному файлу политики. |
comm, pid | Имя процесса и его идентификатор; помогают связать событие с unit, дочерним процессом или конкретным запуском. |
operation | Тип операции: например open, exec, file_mmap, capability или операция с сетью. |
name | Путь к объекту там, где он применим. Для capability и части сетевых операций пути может не быть. |
requested_mask и denied_mask | Какой доступ запрашивался и какая часть была отклонена: чтение, запись, выполнение и другие права. |
sudo aa-logprofИспользуйте предложения как черновик. До подтверждения проверьте профиль, операцию, путь и назначение действия; не принимайте автоматически широкие шаблоны или разрешения на запуск программ.Как исправлять denied без широких разрешений
- Сопоставьте
profile,commи PID с конкретной службой. Отказ отreportd-helperможет относиться к дочернему процессу, а не к основному бинарному файлу. - Определите запрошенную операцию и объект. Для файлового доступа проверьте реальный путь, символьные ссылки, владельца и обычные права Linux; для capability или сети — реальную функцию приложения.
- Решите, ожидаемо ли действие. Чтение конфигурации из предусмотренного каталога обычно может быть легитимным; попытка читать чужой закрытый ключ, выполнять shell или писать в неожиданный каталог — повод менять приложение либо считать действие нежелательным.
- Выберите самое узкое исправление: конкретное файловое правило, уже проверенную abstraction, отдельное правило выполнения или исправление конфигурации приложения, чтобы оно использовало собственный каталог.
- Перезагрузите изменённый профиль, воспроизведите сценарий и убедитесь, что разрешена только нужная операция. Зафиксируйте причину правила и зависимость, которая его требует.
Проблема
После включения enforce сервис не запускается или теряет функцию
Возможные причины
- В профиле нет узкого правила для ожидаемого файла, каталога, выполнения helper-программы, capability или сетевой о перации.
- Сервис использует другой путь после обновления, символьной ссылки, смены рабочего каталога или запуска дочернего процесса.
- Отказ связан не с AppArmor, а с DAC-правами, ACL или другой политикой.
Решение
Сначала извлеките полную запись denied и свяжите её с процессом. Если действие нужно, добавьте минимальное правило либо исправьте конфигурацию сервиса. Если функция критична и время разбора ограничено, временно переведите только этот профиль в complain, а затем повторите проверку и верните enforce.
Как избежать
Проверяйте профиль в complain на реальных сценариях: запуск, обработка запросов, запись данных, ротация, фоновые задания и штатное завершение.
Не лечите каждый denied строкой allow
aa-logprof, разрешения вида /** rw,, ux для произвольного запуска и массовые abstractions могут превратить профиль в формальность. Если приложению нужен доступ к неожиданному пути, сначала проверьте ошибку конфигурации, утечку пути из окружения или неучтённую зависимость.Временное отключение одного профиля и возврат защиты
Для диагностики допустимо кратко отключить конкретный профиль, но это снимает с процесса слой MAC-защиты. В типичных apparmor-utils команда aa-disable одновременно выгружает профиль из ядра и создаёт отметку отключения, чтобы штатная загрузка профилей не включила его снова при следующем запуске службы AppArmor или перезагрузке. Простая выгрузка через apparmor_parser -R удаляет активный профиль, но сама по себе не обязана предотвращать его последующую загрузку из файла политики.
sudo aa-disable /etc/apparmor.d/opt.acme.bin.reportdСразу проверьте результат через `aa-status`: профиль не должен оставаться среди загруженных. После выгрузки уже работающие процессы, которые были ограничены этим профилем, теряют его защиту. Когда профиль будет включён снова, одной загрузки политики недостаточно для повторного прикрепления к такому процессу: выполните контролируемый перезапуск приложения или другой новый exec. Расположение disable-маркера и принимаемую форму аргумента сверяйте с документацией установленной версии.sudo aa-enforce /etc/apparmor.d/opt.acme.bin.reportdПодтвердите возвращение профиля через `aa-status`, затем перезапустите приложение в контролируемом окне и повторите функциональную проверку. Перезапуск важен для надёжной проверки нового запуска под profile attachment; не полагайтесь только на статус загрузки политики.Не отключайте AppArmor на всём сервере ради одного сбоя
Выбор между AppArmor и SELinux, а не настройка конкретного профиля, рассмотрен в статье «SELinux или AppArmor: какую систему мандатного контроля доступа выбрать». Общую последовательность усиления Ubuntu и Debian смотрите в чек-листе hardening Linux; сбор и хранение событий вне одного хоста — отдельная задача из статьи «Централизованный сбор журналов безопасности».
Термины в статье
- AppArmor
- AppArmor — система мандатного контроля доступа Linux, ограничивающая программы профилями; профиль обычно выбирается по пути исполняемого файла, а файловые правила сопоставляются с путями.
- Hardening
- Hardening — процесс усиления защищённости системы через отключение лишних функций, ограничение доступа и настройку безопасных параметров д ля снижения доступной поверхности атаки.
- Linux Security Modules
- Linux Security Modules — каркас ядра Linux для подключения модулей контроля доступа, перехватывающих операции с объектами системы по заданным политикам.
- Абстракция AppArmor
- Абстракция AppArmor — подключаемый набор повторно используемых правил профиля, описывающий типовой доступ приложения к файлам и системным ресурсам.
- Дискреционный контроль доступа
- Дискреционный контроль доступа — модель авторизации, в которой владелец объекта назначает права пользователям и группам через разрешения или списки ACL.
- Мандатный контроль доступа
- Мандатный контроль доступа — модель разграничения доступа, в которой операции разрешаются обязательной системной политикой, не изменяемой владельцем ресурса.
- Принцип наименьших привилегий
- Принцип наименьших привилегий — правило предоставления пользователю, службе или процессу только тех прав и на тот срок, которые необходимы для выполнения конкретной задачи.
- Профиль AppArmor
- Профиль AppArmor — набор правил мандатного контроля доступа, определяющий допустимые для конкретной программы операции с файлами, Linux capabilities и другими ресурсами.
- Путевой контроль доступа
- Путевой контроль доступа — способ задания правил авторизации, при котором защищаемый ресурс выбирается по пути, например по пути URI или имени в файловой системе.
- Режим AppArmor
- Режим AppArmor — состояние профиля контроля доступа в Linux: enforce блокирует нарушения, а complain регистрирует их, кроме действий, явно запрещённых правилами deny.
- Режим complain
- Режим complain — режим профиля AppArmor, в котором потенциальные нарушения регистрируются, но обычно не блокируются; исключение составляют явные правила deny.
- Режим enforce AppArmor
- Режим enforce AppArmor — режим принудительного применения профиля контроля доступа, в котором действия процесса, запрещённые профилем, блокируются и фиксируются в журнале.
