AppArmor в Linux: профили безопасности для сервисов

Что такое AppArmor и зачем он нужен

AppArmor (Application Armor) — система мандатного контроля доступа (MAC) для Linux, которая ограничивает возможности отдельных программ. В отличие от традиционной модели прав Linux (DAC), где процесс наследует все права пользователя, AppArmor позволяет задать для каждого приложения точный набор разрешённых действий: какие файлы читать, куда писать, к каким сетевым портам обращаться.

AppArmor включён по умолчанию в Ubuntu, Debian и SUSE. Его основное преимущество перед SELinux — простота настройки: профили описываются в понятном текстовом формате с поддержкой glob-шаблонов путей. Для администратора, который поддерживает веб-серверы, базы данных и контейнеры, AppArmor — эффективный инструмент глубинной защиты (defense in depth).

Типичные применения AppArmor:

  • Ограничение nginx/Apache — доступ только к конкретным директориям
  • Изоляция PHP-FPM — запрет на выполнение произвольных команд
  • Защита MySQL/PostgreSQL — запрет на чтение файлов вне datadir
  • Контейнерная изоляция — дополнительный слой безопасности для Docker

Проверка статуса и управление AppArmor

Прежде чем создавать профили, убедитесь, что AppArmor установлен и активен.

Основные команды управления

Проверка и управление состоянием AppArmor:

# Статус AppArmor и загруженных профилей
sudo aa-status
# apparmor module is loaded.
# 42 profiles are loaded.
# 28 profiles are in enforce mode.
# 14 profiles are in complain mode.

# Установка утилит (если отсутствуют)
sudo apt install apparmor-utils apparmor-profiles apparmor-profiles-extra

# Перевод профиля в режим enforce (блокировка нарушений)
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

# Перевод профиля в режим complain (логирование без блокировки)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

# Отключение профиля
sudo aa-disable /etc/apparmor.d/usr.sbin.nginx

# Перезагрузка всех профилей
sudo systemctl reload apparmor

Режим enforce блокирует запрещённые действия. Режим complain только логирует нарушения в syslog — используйте его при разработке и тестировании профилей.

Структура профиля AppArmor

Профили AppArmor хранятся в /etc/apparmor.d/ и описывают разрешения для конкретного бинарного файла. Имя файла профиля соответствует пути к бинарнику с заменой / на ..

Синтаксис профиля

Рассмотрим базовую структуру профиля:

# /etc/apparmor.d/usr.local.bin.myapp
#include <tunables/global>

/usr/local/bin/myapp {
  # Подключение базовых абстракций
  #include <abstractions/base>
  #include <abstractions/nameservice>

  # Права на файлы
  /usr/local/bin/myapp          mr,    # чтение + mmap самого бинарника
  /etc/myapp/config.yml         r,     # чтение конфигурации
  /var/log/myapp/*.log          w,     # запись логов
  /var/lib/myapp/**             rw,    # чтение-запись данных
  /tmp/myapp-*                  rw,    # временные файлы

  # Сетевые разрешения
  network inet stream,                 # TCP IPv4
  network inet6 stream,                # TCP IPv6

  # Capability
  capability net_bind_service,          # привязка к порту <1024

  # Запрет всего остального (implicit deny)
}

Основные модификаторы доступа к файлам:

ФлагОписание
rЧтение
wЗапись
aAppend (дозапись)
mmmap с PROT_EXEC
kБлокировка файла (flock)
ixНаследование профиля при exec
pxПереход к профилю целевого файла
uxЗапуск без ограничений (unconfined)

Создание профиля для nginx

Создадим профиль AppArmor для nginx, ограничивающий его доступ к файловой системе.

Автоматическая генерация профиля

Утилита aa-genprof запускает интерактивный процесс создания профиля на основе реальной активности приложения:

# Запуск генерации профиля
sudo aa-genprof /usr/sbin/nginx

# В другом терминале — выполните типичные операции:
# перезапустите nginx, откройте сайт, загрузите файлы
sudo systemctl restart nginx
curl http://localhost/

# Вернитесь в первый терминал и нажмите S (scan)
# Для каждого обнаруженного доступа выберите действие:
# (A)llow — разрешить
# (D)eny — запретить
# (G)lob — использовать шаблон пути
# После завершения нажмите S (save)

Генератор создаст базовый профиль, который нужно будет дополнить и подправить вручную.

Ручная настройка профиля nginx

Полный профиль для nginx с учётом типичной конфигурации:

# /etc/apparmor.d/usr.sbin.nginx
#include <tunables/global>

/usr/sbin/nginx {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>
  #include <abstractions/ssl_certs>

  # Бинарник и модули
  /usr/sbin/nginx                    mr,
  /usr/lib/nginx/modules/*.so        mr,

  # Конфигурация
  /etc/nginx/**                      r,
  /etc/ssl/private/**                r,
  /etc/letsencrypt/live/**           r,
  /etc/letsencrypt/archive/**        r,

  # Контент сайтов (только чтение)
  /var/www/**                        r,
  /usr/share/nginx/**                r,

  # Загрузка файлов (чтение-запись)
  /var/www/uploads/**                rw,

  # Логи
  /var/log/nginx/*.log               w,

  # PID и временные файлы
  /run/nginx.pid                     rw,
  /var/lib/nginx/**                  rw,
  /tmp/nginx*                        rw,

  # Сеть
  network inet stream,
  network inet6 stream,
  capability net_bind_service,
  capability setuid,
  capability setgid,
  capability dac_override,

  # Сигналы для worker-процессов
  signal send set=(hup term quit usr1 usr2) peer=/usr/sbin/nginx,
  signal receive set=(hup term quit usr1 usr2) peer=/usr/sbin/nginx,
}

После создания профиля загрузите его:

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

Профиль для PHP-FPM

PHP-FPM — частая цель атак через уязвимости в веб-приложениях. Профиль AppArmor ограничивает последствия эксплуатации.

Профиль с минимальными правами

Ограничим PHP-FPM доступом только к нужным директориям:

# /etc/apparmor.d/usr.sbin.php-fpm8.3
#include <tunables/global>

/usr/sbin/php-fpm8.3 {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/php>

  # Бинарник
  /usr/sbin/php-fpm8.3              mr,

  # Конфигурация PHP
  /etc/php/8.3/**                   r,

  # Код приложения (только чтение!)
  /var/www/mysite/**                r,

  # Директории записи (кэш, сессии, загрузки)
  /var/www/mysite/storage/**        rw,
  /var/www/mysite/bootstrap/cache/** rw,
  /tmp/php*                         rw,
  /var/lib/php/sessions/**          rw,

  # Логи
  /var/log/php*                     w,

  # Сокет
  /run/php/php8.3-fpm.sock          rw,
  /run/php/php8.3-fpm.pid           rw,

  # Сеть (для подключения к БД и API)
  network inet stream,
  network inet6 stream,
  network unix stream,

  # DENY: выполнение произвольных программ
  deny /usr/bin/bash                x,
  deny /usr/bin/sh                  x,
  deny /usr/bin/dash                x,
  deny /usr/bin/python*             x,
  deny /usr/bin/perl                x,
  deny /usr/bin/wget                x,
  deny /usr/bin/curl                x,

  capability setuid,
  capability setgid,
  capability kill,
}

Явный deny на интерпретаторы и утилиты загрузки предотвращает типичные атаки reverse shell. Даже если злоумышленник загрузит PHP-шелл, AppArmor заблокирует выполнение системных команд.

Отладка и анализ нарушений

При разработке профилей неизбежно возникают ложные срабатывания. AppArmor логирует все нарушения в syslog, что позволяет точно определить, какие права нужно добавить.

Анализ логов

Нарушения AppArmor записываются в syslog с меткой DENIED:

# Просмотр нарушений в реальном времени
sudo journalctl -f | grep -i apparmor

# Поиск нарушений конкретного профиля
sudo journalctl --since "1 hour ago" | grep 'apparmor="DENIED"' | grep nginx

# Типичная запись нарушения:
# apparmor="DENIED" operation="open" profile="/usr/sbin/nginx"
#   name="/etc/ssl/dhparam.pem" pid=1234 comm="nginx"
#   requested_mask="r" denied_mask="r" fsuid=0

# Утилита для парсинга логов и генерации правил
sudo aa-logprof
# Интерактивно предложит добавить разрешения на основе логов

Утилита aa-logprof — самый удобный способ дополнить профиль. Она парсит лог, группирует нарушения и предлагает правила для каждого.

AppArmor для Docker-контейнеров

Docker по умолчанию использует профиль docker-default для всех контейнеров. Для критичных контейнеров рекомендуется создать индивидуальные профили.

Пользовательский профиль для контейнера

Создайте профиль и укажите его при запуске контейнера:

# /etc/apparmor.d/docker-myapp
#include <tunables/global>

profile docker-myapp flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>

  # Файловая система контейнера
  /** r,
  /app/** r,
  /app/storage/** rw,
  /tmp/** rw,

  # Сеть
  network inet stream,
  network inet6 stream,

  # Запрет монтирования
  deny mount,

  # Запрет изменения сетевых интерфейсов
  deny network raw,

  # Запрет ptrace (защита от container escape)
  deny ptrace,

  # Минимальные capability
  capability net_bind_service,
  deny capability sys_admin,
  deny capability sys_ptrace,
}

# Загрузка профиля
sudo apparmor_parser -r /etc/apparmor.d/docker-myapp

# Запуск контейнера с профилем
docker run --security-opt apparmor=docker-myapp -d myapp:latest

В Docker Compose:

services:
  myapp:
    image: myapp:latest
    security_opt:
      - apparmor:docker-myapp

Автоматизация и управление профилями

При большом количестве серверов управление профилями AppArmor нужно автоматизировать через системы управления конфигурацией.

Деплой через Ansible

Пример Ansible-playbook для развёртывания профилей:

---
- name: Deploy AppArmor profiles
  hosts: webservers
  become: true
  tasks:
    - name: Install apparmor-utils
      apt:
        name: apparmor-utils
        state: present

    - name: Copy AppArmor profiles
      copy:
        src: "apparmor.d/{{ item }}"
        dest: "/etc/apparmor.d/{{ item }}"
        owner: root
        group: root
        mode: '0644'
      loop:
        - usr.sbin.nginx
        - usr.sbin.php-fpm8.3
      notify: Reload AppArmor

    - name: Enforce profiles
      command: "aa-enforce /etc/apparmor.d/{{ item }}"
      loop:
        - usr.sbin.nginx
        - usr.sbin.php-fpm8.3

  handlers:
    - name: Reload AppArmor
      systemd:
        name: apparmor
        state: reloaded

Часто задаваемые вопросы

AppArmor использует путевые профили (path-based) — правила привязаны к путям файлов. SELinux использует метки (label-based) — каждому файлу назначается контекст безопасности. AppArmor проще в настройке и отладке, SELinux более гибок, но значительно сложнее. На Ubuntu/Debian по умолчанию AppArmor, на RHEL/CentOS — SELinux. Одновременно использовать оба нельзя.

Влияние минимально — порядка 1-2% overhead на файловые операции. AppArmor работает на уровне ядра через LSM (Linux Security Modules) и проверяет права при каждом системном вызове. В типичных веб-сценариях (nginx, PHP-FPM) разница в производительности практически не заметна. Для высоконагруженных баз данных с интенсивным I/O рекомендуется тестировать перед применением.

Для отключения конкретного профиля: sudo aa-complain /etc/apparmor.d/профиль (режим логирования без блокировки) или sudo aa-disable /etc/apparmor.d/профиль (полное отключение). Для отключения всего AppArmor: sudo systemctl stop apparmor. Не рекомендуется отключать AppArmor в production — лучше перевести проблемный профиль в complain mode и проанализировать логи.

Да, snap использует AppArmor как основной механизм изоляции. Каждый snap-пакет автоматически получает профиль AppArmor, ограничивающий его доступ к системе. Профили snap находятся в /var/lib/snapd/apparmor/profiles/. Модификация этих профилей не рекомендуется — они перезаписываются при обновлении snap.

Используйте переменные tunables и glob-шаблоны. Например, для приложения с конфигурируемым datadir создайте tunable: @{myapp_data}=/var/lib/myapp в /etc/apparmor.d/tunables/myapp, затем используйте @{myapp_data}/** rw, в профиле. При изменении пути достаточно обновить tunable. Шаблоны ** (рекурсивный) и * (один уровень) позволяют описать динамические пути.

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#AppArmor#Linux безопасность#MAC Linux#профили безопасности#AppArmor профиль#mandatory access control#aa-genprof#hardening Linux
Комментарии 0

Оставить комментарий

загрузка...