Урок по треку Docker и Kubernetes 7 мин

Безопасность контейнеров за 7 минут

Не-root пользователь, capabilities, read-only ФС, секреты, сканирование образов и минимальные базы.

Контейнер изолирует процесс, но ядро у него общее с хостом. Поэтому безопасность контейнеров это набор слоёв: что внутри образа, с какими правами процесс запущен и что ему позволено делать с ядром.

Не запускать от root

По умолчанию процесс в контейнере работает от root (UID 0). Без user namespaces это тот же UID 0, что и на хосте, просто ограниченный capabilities и namespaces. При побеге из контейнера (уязвимость рантайма или ядра, неудачный mount) атакующий окажется root на хосте.

RUN useradd --system --uid 10001 app
USER 10001

Числовой UID лучше имени: Kubernetes с runAsNonRoot: true может проверить его, не заглядывая в /etc/passwd. Порт ниже 1024 без root не открыть: слушай 8080 и публикуй как нужно, или дай одну capability.

Capabilities

Права root в Linux разбиты на ~40 capabilities. Docker по умолчанию оставляет контейнеру урезанный набор (например CHOWN, NET_BIND_SERVICE, SETUID, KILL), а опасные вроде SYS_ADMIN убирает.

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

Правило: убрать всё и добавить только нужное.

--privileged и docker.sock

  • --privileged выдаёт все capabilities, доступ ко всем устройствам хоста и отключает часть защит (seccomp, AppArmor). Из такого контейнера выйти на хост тривиально. Использовать только когда без этого никак (некоторые системные агенты) и понимать цену.
  • Монтирование /var/run/docker.sock в контейнер даёт ему полный контроль над Docker, а значит над хостом: можно запустить привилегированный контейнер с корнем хоста. Это фактически root на сервере.
  • Аналогично опасны --pid=host, --network=host, bind mount / или /etc.

Файловая система только для чтения

docker run --read-only --tmpfs /tmp app

Атакующий не сможет дописать бинарник или изменить код. Каталоги, куда приложению действительно нужно писать, монтируются как tmpfs или тома.

Seccomp, AppArmor, SELinux, no-new-privileges

  • seccomp: фильтр системных вызовов. Профиль Docker по умолчанию блокирует несколько десятков опасных вызовов.
  • AppArmor/SELinux: мандатный контроль доступа к файлам и ресурсам.
  • --security-opt no-new-privileges: процесс и его потомки не смогут получить больше прав через SUID-бинарники.

Rootless и user namespaces

User namespaces сопоставляют root в контейнере обычному непривилегированному UID на хосте. Rootless Docker (и Podman по умолчанию) запускает сам демон без root. Даже при побеге атакующий получает права обычного пользователя.

Минимальный образ

Чем меньше в образе, тем меньше уязвимостей и инструментов для атакующего: distroless или slim вместо полного дистрибутива, multi-stage без компиляторов, без curl, wget, shell, если они не нужны. Обновлять базовые образы регулярно: патчи безопасности приходят в новых сборках того же тега.

Секреты

Секреты нельзя:

  • класть в образ (COPY .env, ENV TOKEN=..., ARG): они остаются в слоях и истории, а образ уходит в реестр;
  • коммитить в репозиторий с compose-файлом.

Правильно: при сборке RUN --mount=type=secret, в рантайме секреты оркестратора (Docker secrets, Kubernetes Secret, внешнее хранилище вроде Vault), файл с правами 600 вне репозитория. Переменные окружения удобны, но видны в docker inspect и /proc/<pid>/environ, поэтому файлы предпочтительнее.

Сканирование и цепочка поставки

  • Сканеры уязвимостей образов: Trivy, Grype, встроенный Docker Scout. Запускаются в CI, сборка падает на критичных CVE с исправлением.
  • Подпись образов (cosign, Sigstore) и проверка подписи при деплое.
  • SBOM: список компонентов образа для аудита.
  • Свой реестр и закрепление базовых образов по digest.

Ресурсы

Лимиты памяти, CPU и числа процессов (--memory, --cpus, --pids-limit) защищают хост от контейнера, который съест всё, будь то утечка или атака. fork-бомба без --pids-limit положит весь сервер.

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

  • Процесс от root «потому что так работает».
  • docker.sock в контейнере CI или мониторинга без понимания последствий.
  • --privileged для решения проблем с правами.
  • Секреты в ENV или в слоях образа.
  • Образы годами без пересборки.

Что спросят на собесе

  • Почему root в контейнере опасен, если есть изоляция.
  • Что даёт --privileged и монтирование docker.sock.
  • Как уменьшить поверхность атаки образа.
  • Где хранить секреты и почему не в образе.
  • Какие механизмы ядра ограничивают контейнер: capabilities, seccomp, AppArmor, user namespaces.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.