Docker революционизировал процесс разработки и поставки приложений, но вместе с удобством принес и новые векторы атак. Образ контейнера, по умолчанию запущенный с root-привилегиями, уязвимая базовая картинка или небезопасная конфигурация сети могут превратить ваш контейнер в точку входа для злоумышленника. Безопасность Docker — это не единовременное действие, а комплексный подход, охватывающий весь жизненный цикл: от создания образа до запуска в продакшене. Это руководство проведет вас по всем критическим аспектам.
**1. Безопасность образов (Image Security).** Все начинается с образа.
* **Использование минимальных базовых образов (Minimal Base Images)**. Избегайте тяжелых образов вроде `ubuntu:latest` или `centos:latest`. Используйте минималистичные (`alpine`, `distroless` от Google, `scratch`), которые содержат только необходимые для работы приложения библиотеки. Это резко сокращает поверхность атаки.
* **Сканирование образов на уязвимости (Vulnerability Scanning)**. Интегрируйте сканирование (с помощью Trivy, Grype, Clair, Snyk) в CI/CD-конвейер. Каждый образ должен проверяться на наличие известных уязвимостей (CVE) в его слоях перед отправкой в реестр. Критические уязвимости должны блокировать сборку.
* **Подписывание образов (Image Signing)**. Используйте Docker Content Trust (DCT) или Notary для цифровой подписи образов. Это гарантирует, что в продакшен будет развернут именно тот образ, который вы создали и протестировали, а не подмененный.
* **Многоэтапная сборка (Multi-stage Builds)**. Позволяет отделить среду сборки (со всеми компиляторами и dev-зависимостями) от финального образа. В итоговый образ попадают только скомпилированный бинарник и необходимые для его запуска файлы.
**2. Безопасность во время выполнения (Runtime Security).** Как запущен контейнер — не менее важно.
* **Запуск от непривилегированного пользователя (Non-root User)**. Никогда не запускайте контейнеры от root по умолчанию. Создавайте в Dockerfile отдельного пользователя (`USER 1000`) и переключайтесь на него перед запуском приложения. Это ограничивает ущерб в случае компрометации.
* **Ограничение возможностей (Capabilities Drop)**. Ядро Linux предоставляет контейнерам набор привилегий (capabilities). Удаляйте все ненужные: `--cap-drop=ALL --cap-add=NET_BIND_SERVICE`. Например, контейнеру веб-сервера редко нужна возможность `CAP_SYS_ADMIN`.
* **Read-only корневая файловая система (Read-only Root Filesystem)**. Запускайте контейнер с флагом `--read-only`. Это предотвращает модификацию злоумышленником бинарников или скриптов внутри контейнера. Если приложению нужно писать, смонтируйте отдельные тома (`tmpfs` или named volumes) только в конкретные директории (`/tmp`, `/logs`).
* **Применение Security Profiles (AppArmor, Seccomp)**. Используйте AppArmor или Seccomp-профили для ограничения системных вызовов, которые может выполнять контейнер. Docker предоставляет дефолтный `seccomp` профиль, который является хорошей отправной точкой.
**3. Сетевая безопасность (Network Security).** Изоляция — ключевой принцип.
* **Избегание сети `--network=host`**. Запуск контейнера в сетевом пространстве хоста стирает границы изоляции. Всегда создавайте пользовательские сети (user-defined bridge networks) для изоляции групп контейнеров.
* **Контроль сетевой политики**. Используйте встроенные механизмы (`--icc=false` для отключения межконтейнерной коммуникации по умолчанию) или более продвинутые оркестраторы, такие как Kubernetes с Network Policies, для явного указания, каким контейнерам разрешено общаться друг с другом и на каких портах.
* **Защита Docker Daemon Socket**. Сокет `/var/run/docker.sock` — это, по сути, root-доступ к хосту. Никогда не монтируйте его внутрь контейнеров, если в этом нет абсолютной необходимости (как в случае с системами мониторинга типа cAdvisor). Если доступ необходим, используйте дополнительные меры контроля.
**4. Управление секретами (Secrets Management).** Никаких паролей в Dockerfile или переменных окружения в plain text.
* **Использование Docker Secrets** (в Swarm Mode) или внешних систем: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault. Приложение в контейнере должно динамически запрашивать секреты при старте. Секреты никогда не должны попадать в итоговый образ.
* **Ограничение использования `--env-file`** с чувствительными данными. Файлы с переменными окружения часто попадают в системы контроля версий по ошибке.
**5. Мониторинг, логирование и обновления.**
* **Централизованный сбор логов**. Настройте драйвер логирования Docker (например, `json-file`, `syslog`, `fluentd`) для отправки логов всех контейнеров в центральную систему (ELK Stack, Loki). Это критично для расследования инцидентов.
* **Мониторинг аномалий**. Используйте инструменты вроде Falco (от Sysdig) для обнаружения подозрительного поведения контейнеров в реальном времени (например, запуск shell внутри продакшен-контейнера, неожиданные сетевые соединения).
* **Регулярное обновление Docker Engine и базовых образов**. Уязвимости находят как в самом Docker, так и в базовых дистрибутивах. Внедрите процесс регулярного обновления и пересборки образов с последними security-патчами.
Безопасность Docker — это постоянный процесс балансировки между удобством, производительностью и защищенностью. Применение этих практик, начиная с этапа разработки образа и заканчивая мониторингом работающих контейнеров, позволяет значительно снизить риски и построить надежную, контейнеризированную инфраструктуру, способную противостоять современным угрозам.
Полное руководство по безопасности Docker: от основ до продвинутых практик харденинга
Исчерпывающее руководство по обеспечению безопасности на всех этапах работы с Docker: создание безопасных образов, настройка runtime-безопасности контейнеров, сетевая изоляция, управление секретами, мониторинг и поддержание актуальности.
22
3
Комментарии (13)