Безопасность контейнеров: capabilities, seccomp, read-only, rootless

↑ Этап 2 · Контейнеры: Docker, docker-compose, Makefile

Обязательно~5 мин чтенияУровень: junior

Зачем это на собесе

Контейнер не является границей безопасности «по умолчанию». Спрашивают конкретные настройки хардeнинга.

Модель угроз

Общее ядро хоста → уязвимость ядра или неверная конфигурация контейнера (privileged, docker.sock, hostPath) = компрометация хоста. Поэтому: минимум привилегий, минимум поверхности, изоляция.

Capabilities

docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp        # только нужное
docker run --privileged ...                                        # НЕТ: все capabilities, доступ к устройствам

Опасные: SYS_ADMIN, NET_ADMIN, SYS_PTRACE, SYS_MODULE, DAC_READ_SEARCH. По умолчанию у контейнера ~14 capabilities (CHOWN, NET_BIND_SERVICE, SETUID, KILL, …): большинству приложений хватает пустого набора + NET_BIND_SERVICE.

seccomp, AppArmor, SELinux

  • seccomp: фильтр системных вызовов; профиль Docker по умолчанию блокирует опасные (mount, reboot, kexec_load, bpf…); свой профиль: --security-opt seccomp=profile.json; seccomp=unconfined — не использовать;
  • AppArmor/SELinux: профили MAC (--security-opt apparmor=..., label=...); в Kubernetes seccompProfile: RuntimeDefault.

Запуск без root

USER 10001:10001
  • в Kubernetes: runAsNonRoot: true, runAsUser, allowPrivilegeEscalation: false;
  • rootless Docker/Podman: демон и контейнеры работают без root на хосте (user namespaces): компрометация контейнера ≠ root на хосте;
  • userns-remap в Docker: root в контейнере сопоставлен с непривилегированным UID хоста.

Read-only и ограничение записи

docker run --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m -v data:/app/data myapp
services:
  api:
    read_only: true
    tmpfs: ["/tmp"]
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]
    user: "10001:10001"

no-new-privileges запрещает получать дополнительные привилегии (setuid). Монтирование файлов конфигурации :ro.

Ресурсы (защита от DoS)

--memory, --cpus, --pids-limit (защита от fork-бомб), --ulimit nofile, --restart on-failure:3, ограничение логов.

Чего избегать

ОпасностьПочему
--privilegedфактически root на хосте
Монтирование /var/run/docker.sockполный контроль над Docker = root на хосте
--pid=host, --net=host, --ipc=hostнарушают изоляцию
Монтирование /, /etc, /proc, /sys с записьюизменение хоста
-v /:/hostто же
Секреты в ENV/ARG/образевидны в docker inspect, history, слоях
latest и неподписанные образы из недоверенных источниковцепочка поставок
Открытый Docker API (tcp://0.0.0.0:2375)удалённый root
Контейнеры БД с публикацией портов на 0.0.0.0доступ из интернета

Если нужен доступ к Docker API из сервиса (CI-раннер, Traefik): docker-socket-proxy с урезанными правами, rootless-раннер, Kaniko/BuildKit без демона.

Образы и цепочка поставок

  • минимальные базовые образы (distroless/chiseled), обновляемые;
  • сканирование: Trivy/Grype/Scout в CI и в реестре; политика по серьёзности, игнор-лист с обоснованием и сроком;
  • SBOM (Syft, CycloneDX/SPDX), подпись и проверка (cosign, Notary), provenance (SLSA);
  • фиксация версий и digest, проверяемые источники (доверенные реестры, зеркала);
  • секреты: BuildKit --mount=type=secret, хранилища секретов (Vault, Docker/K8s secrets), не ENV;
  • линтеры: hadolint (Dockerfile), Dockle (CIS-проверки образа), docker-bench-security (CIS Docker Benchmark) для хоста и демона.

Сеть

  • внутренние сети для БД (internal: true), минимум публикуемых портов;
  • TLS между сервисами там, где нужно (mTLS в service mesh);
  • ограничение исходящего трафика (egress) для чувствительных контейнеров;
  • фильтрация через DOCKER-USER, сетевые политики в Kubernetes.

Kubernetes: Pod Security

Pod Security Standards: privileged / baseline / restricted; securityContext (non-root, read-only rootfs, drop ALL, seccomp RuntimeDefault); admission-политики (Kyverno, OPA Gatekeeper): запрет privileged, hostPath, тегов latest, требование подписей; NetworkPolicy; RBAC.

Мониторинг и реагирование

Runtime-защита: Falco (подозрительные системные вызовы), Tetragon, аудит Docker-демона (auditd), логи доступа к реестру, алерты на запуск shell в продовых контейнерах, регулярные обновления ядра и Docker, управление уязвимостями.

Чек-лист

  • non-root, no-new-privileges, cap_drop: ALL;
  • read-only rootfs + tmpfs;
  • нет privileged, docker.sock, host-namespaces;
  • лимиты ресурсов;
  • образы минимальные, просканированы, зафиксированы по версии/digest;
  • секреты вне образа и ENV;
  • БД и внутренние сервисы не опубликованы наружу;
  • Docker API не открыт, хост обновляется.

Вопросы с ответами