Перейти к содержанию
Innovialabs

Безопасность Docker-контейнеров: лучшие практики для продакшена

Практика4 мин

Коротко

Безопасный контейнер работает не от root, собран из минимального проверенного образа, не хранит секретов в слоях, лишён лишних capabilities, ограничен по ресурсам, а к Docker-сокету нет доступа извне.

Что важнее всего

Контейнер — не виртуальная машина: он делит ядро с хостом. Взломанный контейнер с лишними правами легко превращается во взломанный сервер. Базовые правила для продакшена:

  • Запускайте процессы не от root.
  • Собирайте из минимальных базовых образов и фиксируйте их версии.
  • Сканируйте образы на CVE в CI до деплоя.
  • Никогда не зашивайте секреты в слои образа.
  • Урезайте capabilities, используйте read-only файловую систему и лимиты ресурсов.
  • Защищайте Docker-сокет и registry.

1. Запуск не от root

По умолчанию процесс в контейнере работает от root. Если злоумышленник выйдет за пределы приложения, root внутри контейнера сильно упростит следующий шаг.

FROM node:20-alpine
WORKDIR /app
COPY --chown=node:node . .
RUN npm ci --omit=dev
USER node
CMD ["node", "server.js"]
  • Создайте отдельного пользователя или используйте того, что есть в базовом образе.
  • Слушайте порты выше 1024, чтобы root не требовался.
  • Рассмотрите rootless Docker или user namespace remapping на хосте.

2. Минимальные базовые образы

Каждый лишний пакет — это лишняя поверхность атаки и лишние CVE.

ВариантКогда подходит
alpine / -slimОбычные сервисы, малый размер
DistrolessСкомпилированные приложения и рантаймы, без shell
scratchСтатические бинарники (Go, Rust)
  • Используйте multi-stage сборку: компиляторы и dev-зависимости остаются на этапе сборки.
  • Фиксируйте базовый образ по тегу, а для критичных сервисов — по digest (image@sha256:...).
  • Регулярно пересобирайте образы, чтобы патчи безопасности базового образа доходили до продакшена.

3. Сканирование образов на CVE

  • Добавьте в CI сканер: Trivy, Grype или Docker Scout.
  • Останавливайте сборку при критических уязвимостях, для которых есть исправление.
  • Сканируйте не только при сборке, но и уже работающие образы: новые CVE появляются каждый день.
  • Ведите короткий задокументированный список исключений для неприменимых находок.
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:1.4.0

4. Секреты не должны попадать в слои

Всё, что записано в слой, остаётся в истории образа, даже если следующий RUN rm удалил файл. ENV API_KEY=... и COPY .env видны любому, кто может скачать образ.

  • Добавьте .env, ключи и учётные данные в .dockerignore.
  • Для секретов на этапе сборки используйте BuildKit secret mounts:
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
  • Секреты для работы передавайте через оркестратор: Docker/Swarm secrets, Kubernetes Secrets или менеджер секретов вроде Vault или облачного KMS.
  • Если секрет хоть раз попал в опубликованный образ — смените его: удалить тег недостаточно.

5. Ограничение capabilities и ресурсов

docker run -d \
  --user 1000:1000 \
  --read-only --tmpfs /tmp \
  --cap-drop ALL --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges \
  --memory 512m --cpus 1 --pids-limit 200 \
  myapp:1.4.0
  • --cap-drop ALL, затем возвращайте только нужное.
  • Никогда не используйте --privileged в продакшене.
  • Корневая ФС --read-only, запись — только в явно заданные тома или tmpfs.
  • Лимиты памяти, CPU и PID не дадут одному контейнеру положить весь хост.
  • Оставляйте включёнными профили seccomp и AppArmor/SELinux по умолчанию.
  • Не публикуйте порты баз данных и внутренних сервисов на 0.0.0.0 — используйте внутренние сети.

6. Защита Docker-сокета и registry

Доступ к /var/run/docker.sock равен root на хосте. Кто может к нему обращаться, тот может запустить привилегированный контейнер и смонтировать файловую систему хоста.

  • Не монтируйте сокет в контейнеры приложений. Если инструменту он действительно нужен, используйте ограничивающий socket proxy.
  • Никогда не открывайте Docker API по TCP без TLS с клиентской аутентификацией.
  • Ограничьте членство в группе docker на хосте.

Для registry:

  • Используйте приватный registry с аутентификацией и доступами по проектам.
  • CI получает токен на push, серверы — токен только на pull.
  • Подписывайте образы (например, cosign) и проверяйте подписи перед деплоем.
  • Включите автоматическое сканирование в registry, если оно доступно.

Частые ошибки

  • Тег latest в продакшене: непонятно, что на самом деле запущено.
  • Секреты в ENV или скопированные .env-файлы.
  • Сокет, смонтированный «только для мониторинга».
  • Нет лимитов ресурсов, и одна утечка памяти роняет все сервисы на хосте.

Частые вопросы

Не всегда. Он маленький, но использует musl вместо glibc, что может вызывать проблемы совместимости у некоторых языков и нативных библиотек. Slim или distroless часто подходят лучше.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.