Защита Docker-контейнеров с AppArmor

Защита Docker-контейнеров с AppArmor

Стандартная изоляция Docker обеспечивает лишь базовый уровень безопасности. Рассказываем, как использовать встроенный в ядро Linux механизм AppArmor для защиты контейнеров, хостовой системы и VPS.

Введение

Стандартная изоляция Docker-контейнеров, основанная на пространствах имён (namespaces) и группах управления (cgroups), обеспечивает лишь базовый уровень безопасности. Она не предотвращает попытки процессов внутри контейнера получить несанкционированный доступ к ресурсам хостовой системы: файлам, сетевым интерфейсам или системным вызовам. Злоумышленник, эксплуатируя уязвимость в приложении или неправильно настроенном образе, может инициировать атаку на хост-машину, например, чтение чувствительных файлов (таких как /etc/shadow), несанкционированный доступ к Docker-сокету или попытку выполнения привилегированных операций.

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

Рассказываем, как создавать, настраивать и применять кастомные профили AppArmor для Docker-контейнеров, все инструкции приведены для Ubuntu 24.04.

Аренда VPS/VDS — от ₽219/месяц

Почему выбирают VPS от AdminVPS:

✓ Дешевле физического сервера

✓ Более гибкий и мощный, чем обычный хостинг

✓ Бесплатная защита от DDoS и техподдержка 24/7

✓ Масштабируется под любые задачи

Виртуальный сервер VPS/VDS — ваш личный сервер для сайтов, магазинов, ботов и других проектов.

Принципы работы AppArmor

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

  • доступ к файловой системе — указываются конкретные пути с указанием прав доступа (чтение, запись, выполнение, создание ссылок);
  • сетевые операции — регулируются по протоколам (tcp, udp, raw) и типам операций (bind, listen, accept);
  • системные вызовы и возможности — ограничивают использование опасных привилегий.

Процесс работы AppArmor состоит из нескольких этапов. При запуске приложения загружается соответствующий профиль; ядро перехватывает системные вызовы процесса и сверяет их с правилами профиля; при нарушении правил действие блокируется, а запись о нарушении попадает в системные логи.

Основные команды для работы с AppArm.

  • Проверка статуса службы:
sudo systemctl status apparmor

И статуса профилей:

sudo aa-status
  • Принудительная перезагрузка конкретного профиля после внесения изменений:
sudo apparmor_parser -r /etc/apparmor.d/имя_профиля
  • Просмотр логов нарушений:
sudo journalctl -k -f -g apparmor

Стандартный профиль Docker в AppArmor

AppArmor предустановлен в Ubuntu 24.04 и активен по умолчанию. При запуске контейнера Docker автоматически генерирует профиль docker-default в tmpfs и загружает его в ядро. Стандартный профиль применяется для всех запущенных контейнеров, если его не переопределить при запуске параметром --security-opt apparmor=имя_профиля:

docker run --security-opt apparmor=my-app app

Ключевые правила стандартного профиля Docker:

  • блокировка записи в критичные системные директории: deny /etc/** wl,
  • ограничение доступа к ядерным структурам: deny /proc/sysrq-trigger rwklx,
  • контроль монтирования файловых систем: deny mount,
  • ограничение сетевых возможностей: network bridge.

Регулярно просматривайте логи, чтобы проверять эффективность работы профиля:

sudo tail -f /var/log/syslog | grep apparmor

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

Создание кастомного профиля для контейнера

Для создания специализированных профилей AppArmor, обеспечивающих точечный контроль доступа для конкретного контейнера, используется утилита aa-genprof. Этот инструмент анализирует деятельность процесса и генерирует базовый профиль на основе его поведения. Однако aa-genprof предназначена для профилирования процессов, запущенных напрямую на хосте. Она не может корректно отследить действия процесса, изолированного внутри контейнера (с его собственной файловой системой, пространством имён и т. д.). Её использование для контейнеров даст неполный и скорее всего бесполезный профиль. Новый профиль для контейнеров можно создать на основе шаблона docker-default, его нужно разместить в /etc/apparmor.d или вложенном каталоге.

Пример кастомного профиля:

#include <tunables/global>

# Профиль для контейнера my-app
# flags: attach_disconnected, mediate_deleted — рекомендуемые опции
profile my-app flags=(attach_disconnected,mediate_deleted) {

  #
  # Базовые правила и абстракции
  #
  # abstractions/base — минимальный набор разрешений для системных вызовов
  # abstractions/nameservice — доступ к DNS и базовым сетевым функциям
  #
  # Эти include-файлы идут в стандартной поставке AppArmor (Ubuntu/Debian).
  #
  # См. каталог /etc/apparmor.d/abstractions/
  #
  # Их можно подрезать, если нужно ещё жестче ограничить контейнер
  #
  # -----------------------------------------------------------
  # Базовые include'ы
  # -----------------------------------------------------------
  # Подключение общих правил
  # -----------------------------------------------------------
  #include <abstractions/base>
  #include <abstractions/nameservice>


  #
  # Ограничение возможностей ядра (capabilities)
  #
  # sys_admin — самая опасная возможность, фактически root
  # sys_module — загрузка/выгрузка модулей ядра
  # sys_ptrace — отладка/трассировка чужих процессов
  #
  deny capability sys_admin,
  deny capability sys_module,
  deny capability sys_ptrace,


  #
  # Запрет доступа к критическим файлам и системным структурам
  #
  deny /etc/shadow rw,
  deny /etc/sudoers rw,
  deny /proc/*/mem r,
  deny /sys/kernel/security/** rw,
  deny mount,


  #
  # Сетевые правила
  #
  # inet stream — разрешаем TCP (IPv4)
  # inet dgram  — разрешаем UDP (IPv4)
  # raw         — запрет на низкоуровневый доступ к пакетам
  # inet6       — полный запрет IPv6 (можно убрать, если нужен)
  #
  network inet stream,
  network inet dgram,
  deny network raw,
  deny network inet6,


  #
  # Работа с временными каталогами
  #
  # Разрешаем запись в /tmp и /var/tmp
  # Но запрещаем запуск исполняемых файлов из /tmp — частый вектор атак
  #
  /tmp/** rw,
  deny /tmp/** x,
  /var/tmp/** rw,
  /run/** rw,


  #
  # Доступ к базовым устройствам
  #
  /dev/null rw,
  /dev/zero r,
  /dev/urandom r,


  #
  # Доступ к бинарям
  #
  # mr = m(emap) + r(read) — достаточно для исполнения
  # ix можно использовать для жёсткой изоляции исполнения только под этим профилем
  #
  /usr/bin/** mr,
  /bin/** mr,


  #
  # Межпроцессные взаимодействия
  #
  # ptrace — блокируем трассировку процессов
  # signal — блокируем отправку сигналов другим процессам
  #
  deny ptrace,
  deny signal,
}

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

sudo apparmor_parser -r /etc/apparmor.d/my-app

Переведите профиль в режим обучения (complain) и начните отладку:

sudo aa-complain /etc/apparmor.d/my-app

Запустите контейнер с новым профилем и отработайте все его типичные сценарии.

docker run --security-opt apparmor=my-app --rm -it your-application

Проанализируйте логи и добавьте недостающие правила с помощью aa-logprof:

sudo aa-logprof

Эта утилита проанализирует логи AppArmor и предложит добавить правила для разрешённых, но незадекларированных действий.

Переведите профиль в режим ограничений:

sudo aa-enforce /etc/apparmor.d/my-app

Валидация работы профиля через проверку логов:

sudo journalctl -k -f | grep apparmor

Обязательно обновляйте профили при изменении функционала контейнеров.

Продвинутая настройка AppArmor

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

Ограничение системных вызовов

Профиль может ограничивать использование конкретных возможностей ядра Linux:

deny capability sys_module,    # запрет загрузки модулей ядра
deny capability sys_ptrace,    # блокировка отладки других процессов
deny capability sys_time,      # запрет изменения системного времени
deny capability sys_nice,      # запрет изменения приоритета процессов
deny capability sys_rawio,     # запрет низкоуровневого доступа к устройствам

Детальный контроль сетевого доступа

Сетевые правила позволяют фильтровать трафик по протоколам и типам операций:

network inet stream,           # разрешить только IPv4 TCP
network inet dgram,            # разрешить IPv4 UDP
deny network inet6,            # полный запрет IPv6
deny network netlink,          # блокировка Netlink сокетов
deny network packet,           # запрет raw packet access

Расширенное управление файловыми системами

Настройка доступа к файлам и директориям:

# Блокировка доступа к устройствам

deny /dev/sd* rw,              # запрет доступа к блочным устройствам
deny /dev/ttyS* rw,            # блокировка последовательных портов
deny /dev/mem rw,              # запрет прямого доступа к памяти
# Контроль временных файлов
/tmp/** rw,                    # разрешить запись в /tmp
/var/tmp/** rw,                # разрешить запись в /var/tmp
deny /tmp/**x,                 # запрет выполнения из /tmp
# Системные файлы
deny /etc/passwd w,            # запрет записи в passwd
deny /etc/ssh/** rw,           # блокировка доступа к SSH-ключам

Управление процессами и сигналами

Контроль взаимодействия между процессами:

deny signal,                   # запрет отправки сигналов другим процессам
deny ptrace,                   # блокировка трассировки процессов

Использование условных правил

Динамические правила на основе атрибутов процесса:

# Разрешение записи только для определенных владельцев
owner /var/log/nginx/* rw,
owner /var/cache/nginx/** rw,
# Ограничение на основе пути исполняемого файла
/usr/bin/nginx {
    /var/lib/nginx/** rw,
    network inet stream,
}

Аудит и мониторинг

Включение детального логирования для анализа:

audit /etc/** r,               # логирование всех чтений из /etc
audit deny /root/** r,         # логирование попыток доступа к /root

Пример комбинации правил

Профиль для веб-сервера nginx:

#include <tunables/global>
profile nginx-container {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    deny capability sys_module,
    deny capability dac_override,   
    network inet stream,
    network inet dgram,
    deny network inet6,   
    /usr/sbin/nginx mr,
    /var/log/nginx/** rw,
    /var/cache/nginx/** rw,
    /run/nginx.pid rw,   
    deny /etc/shadow r,
    deny /root/** r,
}

Для применения изменений в профиле используйте команду:

sudo apparmor_parser -r /etc/apparmor.d/containers/nginx-container

Проверка работы правил:

sudo journalctl -k -f -g apparmor | grep -E "(DENIED|ALLOWED)"

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

Интеграция AppArmor с Docker

Применение профиля через аргументы запуска контейнера

Чтобы использовать кастомный профиль AppArmor, при запуске контейнера укажите его имя в параметре --security-opt:

docker run -d --name nginx-container \

  --security-opt "apparmor=my-app" \

  -p 80:80 \

  nginx:latest

Применённый профиль проверяйте командой inspect:

docker inspect nginx-container --format '{{ .HostConfig.SecurityOpt }}'

Использование профилей в Docker Compose

Для применения профилей AppArmor в docker-compose добавьте соответствующие параметры в определение сервиса:

version: '3.8'
services:
  web:
    image: nginx:latest
    security_opt:
      - apparmor=my-app
    ports:
      - "80:80"

Управление профилями через скрипты

Создайте скрипт обслуживания, чтобы автоматизировать обновление профилей:

#!/bin/bash
# /usr/local/bin/reload-apparmor-profiles.sh
PROFILES_DIR="/etc/apparmor.d/containers/"
for profile in "$PROFILES_DIR"*; do
    if [ -f "$profile" ]; then
        sudo apparmor_parser -r "$profile"
        echo "Reloaded profile: $(basename "$profile")"
    fi
done

Сделайте скрипт исполняемым и добавьте в crontab для регулярного обновления:

sudo chmod +x /usr/local/bin/reload-apparmor-profiles.sh
sudo crontab -l | { cat; echo "0 3 * * * /usr/local/bin/reload-apparmor-profiles.sh"; } | sudo crontab -

Заключение

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

Для продакшн-среды оптимальным решением будет комбинация: использование стандартного профиля docker-default для обычных сервисов и кастомных профилей для критичных приложений. Регулярный аудит логов, обновление правил и автоматизация загрузки профилей через скрипты помогут поддерживать защиту на актуальном уровне.

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

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Нужен VPS сервер?

Арендуйте мощный VPS сервер для ваших проектов! Быстрая настройка, высокая производительность и надежная поддержка 24/7. Начните прямо сейчас!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях