Главная/Security/Обзор

Раздел 12. Security

Раздел начинается с утверждения, которое стоит запомнить дословно: изоляция container не является полноценной границей безопасности. Container — это процесс host-системы, ограниченный namespaces, cgroups и capabilities. Все эти механизмы реализованы в том же ядре, что и всё остальное. Уязвимость в ядре, ошибка в конфигурации или избыточная привилегия превращают изоляцию в формальность.

Из этого не следует, что containers небезопасны. Следует, что модель угроз должна быть явной. Раздел разбирает реальные векторы: доступ к Docker socket, root внутри container, privileged mode, монтирование каталогов host, секреты в образах, недоверенные базовые образы.

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

Цели обучения

После раздела учащийся сможет:

  • объяснить, почему изоляция container не равна security boundary, и назвать границы её применимости;
  • построить модель угроз для контейнеризованного сервиса;
  • объяснить, почему доступ к Docker socket эквивалентен правам root на host, и показать это;
  • обосновать выбор между группой docker, sudo и rootless mode;
  • объяснить разницу между root в container, user namespaces и rootless Docker;
  • применять принцип минимальных привилегий через --cap-drop и точечный --cap-add;
  • назвать конкретные последствия --privileged и предложить альтернативы;
  • объяснить роль seccomp, AppArmor и SELinux и что даёт профиль Docker по умолчанию;
  • доставлять secrets безопасно и обнаруживать их утечку в слои образа;
  • оценивать риски цепочки поставок: базовые образы, зависимости, подпись, provenance;
  • находить опасные настройки в чужой конфигурации и обосновывать исправления.

Предварительные знания

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

Материалы

  1. Модель угроз
    Что защищает контейнеризация, а что нет. Активы, границы доверия, векторы. Отличие изоляции containers от изоляции VM. Многопользовательские и однопользовательские сценарии. Практическая методика построения модели угроз для сервиса.

  2. Daemon и socket
    Привилегии Docker daemon. /var/run/docker.sock и что даёт доступ к нему. Демонстрация чтения произвольного файла host через socket. Почему монтирование socket в container опасно и какие есть альтернативы. Docker API по TCP и требование TLS.

  3. Пользователи и namespaces
    Root внутри container: что он может и чего не может. User namespaces и userns-remap: механизм, настройка, ограничения. Rootless Docker: модель безопасности и её цена. Сравнение трёх подходов таблицей.

  4. Capabilities и privileged
    Модель capabilities. Набор, оставляемый Docker по умолчанию, и что даёт каждая. --cap-drop=ALL как базовая практика. Опасные capabilities: SYS_ADMIN, SYS_PTRACE, NET_ADMIN, DAC_OVERRIDE. Что именно включает --privileged и почему это почти всегда избыточно. --device как точечная альтернатива.

  5. Seccomp, AppArmor, SELinux
    Профиль seccomp по умолчанию: какие системные вызовы блокирует и зачем. Создание собственного профиля. AppArmor в Ubuntu и профиль docker-default. SELinux в RHEL-подобных системах и контексты монтирования. --security-opt=no-new-privileges. Диагностика блокировок.

  6. Secrets
    Почему ENV и --build-arg непригодны для секретов. Демонстрация извлечения секрета из слоёв. BuildKit secret mounts. Файлы вместо переменных. Compose secrets. Ротация. Обнаружение утечек в существующих образах и что делать после утечки.

  7. Supply chain security
    Доверие к базовым образам: официальные образы, digest pinning, обновления. Уязвимости зависимостей и их приоритизация. Риски typosquatting в PyPI. Вредоносные образы в публичных registry. Подпись образов и attestations. Проверка происхождения артефакта.

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

Рекомендуемый порядок чтения

Последовательный: 01 → 02 → 03 → 04 → 05 → 06 → 07 → exercises.

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

Практические задания

ЗаданиеТип
1Показать на учебной машине, что доступ к Docker socket позволяет прочитать /etc/shadow hostобяз.
2Извлечь секрет, переданный через --build-arg, из готового образаобяз.
3Переделать сборку на secret mount и доказать отсутствие секрета в слояхобяз.
4Запустить приложение с --cap-drop=ALL и определить минимально необходимый наборобяз.
5Сравнить вывод capsh --print для обычного и --privileged containerобяз.
6Настроить userns-remap и показать, что root в container отображается на непривилегированный UIDдоп.
7Написать seccomp-профиль, блокирующий конкретный системный вызов, и проверить егодоп.
8Проверить образ сканером и обосновать приоритет каждой находкидоп.
9Дан compose.yaml с пятью нарушениями безопасности. Найти все и исправитьдиаг.
10Провести аудит безопасности собственного проекта из раздела 10 по security checklist

Полные формулировки — в exercises.md.

Критерии завершения раздела

Раздел пройден, когда учащийся может без подсказок:

  1. Объяснить за минуту, почему членство в группе docker эквивалентно root.
  2. Назвать три конкретных последствия запуска container с --privileged.
  3. Извлечь секрет из чужого образа и объяснить, как его туда не допустить.
  4. Определить минимальный набор capabilities для конкретного приложения.
  5. Объяснить разницу между rootless Docker и userns-remap.
  6. Провести аудит compose.yaml и обосновать каждое найденное нарушение сценарием риска.

Проверьте себя: Quiz 12 и security checklist.

Что дальше

Мы знаем, как построить безопасный и корректный сервис. Следующий раздел учит выяснять, что происходит, когда он всё-таки сломался.

Навигация

← Предыдущий раздел: Production-ready containers
Вернуться к главному оглавлению
Следующий раздел: Observability и диагностика →

Markdown на GitHub ↗