Информационная безопасность

Безопасность контейнеров и K8s

2020 год. TeamTNT - хакерская группа автоматически сканирует интернет в поисках незащищённых Kubernetes API и открытых Docker daemon сокетов. Найдено: тысячи кластеров. Тактика: получить дефолтный ServiceAccount -> cluster-admin через RBAC misconfiguration -> развернуть DaemonSet на все ноды -> майнить Monero. За 6 месяцев - миллионы долларов на чужих ресурсах. Kubernetes secure by default - миф. Каждый компонент требует явной настройки.

  • **TeamTNT 2020-2021:** автоматический захват тысяч K8s кластеров через открытый API и дефолтные ServiceAccount - crypto mining на чужих ресурсах
  • **Tesla 2018:** незащищённый Kubernetes dashboard без пароля -> AWS credentials в переменных -> майнинг на EC2 за счёт Tesla
  • **Shopify 2022:** bug bounty 25 000 долларов за нахождение container escape через неправильно настроенный securityContext в production K8s

Container Scanning: уязвимости в образах

Docker образ - это не чистый slate. `ubuntu:22.04` содержит 80+ установленных пакетов, каждый - потенциальная CVE. Образ `node:18` наследует все уязвимости Ubuntu плюс npm-зависимости Node.js. В 2023 году Snyk проанализировал Docker Hub: 80% официальных образов содержат хотя бы одну high-severity уязвимость.

**Distroless images** от Google содержат только runtime (Node.js, JVM, Python) без shell, пакетного менеджера, текстовых редакторов. Если атакующий получает RCE в контейнере, он не может запустить bash, установить инструменты, скачать файлы. Значительно усложняет post-exploitation.

Образ просканирован: 12 HIGH CVE, 0 CRITICAL. CI/CD configured с `--severity CRITICAL`. Pipeline прошёл. Безопасно ли?

Pod Security: изоляция на уровне K8s

Container runtime изолирует процессы, но по умолчанию Kubernetes Pod имеет опасные привилегии: root внутри контейнера, доступ к хостовым namespace, возможность монтировать хостовые директории. Один скомпрометированный Pod может захватить весь Node.

**hostPath mount - опасен.** Монтирование `/var/run/docker.sock` в контейнер даёт полный контроль над Docker daemon хоста - Docker-in-Docker escape, container breakout. В реальных инцидентах (TeamTNT, 2020) именно через docker.sock захватывались K8s-кластеры для майнинга.

Контейнер запускается как root (USER не указан в Dockerfile). Что это означает для безопасности?

RBAC в Kubernetes: кто что может делать с кластером

Kubernetes RBAC контролирует доступ к K8s API: кто может создавать Pod, читать Secret, удалять Deployment. Без RBAC любой Pod может получить токен ServiceAccount и вызвать kubernetes API для создания privileged Pod, чтения всех Secret, изменения конфигурации кластера.

**cluster-admin - nuclear option.** Не давать cluster-admin обычным ServiceAccount. Это эквивалент root на всех нодах кластера. Реальный инцидент: TeamTNT 2020 искал незащищённые K8s API server и получал cluster-admin через дефолтный ServiceAccount для майнинга Monero.

Pod нужно читать ConfigMap в том же namespace. Какой набор прав минимален?

Управление секретами в K8s и CI/CD

Kubernetes Secret хранит данные в base64. Base64 - не шифрование. `echo 'bXlwYXNzd29yZA==' | base64 -d` - и секрет прочитан. По умолчанию Secrets в etcd хранятся в открытом виде. Кто читает etcd - читает все секреты кластера.

**Sealed Secrets (Bitnami)** позволяют хранить зашифрованные секреты в git. Public key кластера шифрует секрет, только cluster-side controller может расшифровать. GitOps-дружелюбно: секреты в репозитории, но нечитаемы без доступа к кластеру.

Kubernetes Secret безопасен по умолчанию - он же называется Secret

K8s Secret - это base64, не шифрование. Безопасность секретов требует: etcd encryption at rest, RBAC restricting Secret access, внешние secret managers для production.

Base64 используется для хранения binary данных в YAML, не для безопасности. `kubectl get secret -o jsonpath='{.data.password}' | base64 -d` покажет значение любому с доступом к K8s API. Защита - в RBAC и шифровании etcd.

Команда хочет хранить K8s Secret в git для GitOps. Какой подход правильный?

Ключевые идеи

  • **Container Scanning:** Trivy в CI/CD с `--exit-code 1 --severity HIGH,CRITICAL`. Distroless images убирают shell и package manager - усложняют post-exploitation
  • **Pod Security:** runAsNonRoot, readOnlyRootFilesystem, capabilities drop ALL, seccomp RuntimeDefault. Никаких hostPath mount к docker.sock
  • **K8s RBAC:** Role (namespace-scoped) вместо ClusterRole, минимальные verbs, automountServiceAccountToken: false если API не нужен
  • **Secrets:** K8s Secret - base64, не шифрование. Production: etcd encryption + Vault/AWS Secrets Manager + External Secrets Operator. В CI: GitHub/GitLab protected secrets

Связанные темы

Container security строится на принципах наименьших привилегий и цепочки поставок:

  • Аутентификация и авторизация — K8s RBAC - прямое применение Role-Based Access Control
  • Supply Chain Security — Откуда берутся образы и как проверить их целостность
  • IAM и управление доступом — K8s ServiceAccount -> AWS IAM Role через IRSA

Вопросы для размышления

  • Запускаются ли контейнеры в production как root? Как проверить через kubectl get pods -o yaml | grep runAsUser?
  • Где хранятся секреты в K8s? Включено ли encryption at rest для etcd? Кто имеет RBAC права на чтение Secrets?
  • Есть ли Trivy или аналог в CI/CD pipeline? При каких severity он блокирует деплой?

Связанные уроки

  • sec-03 — RBAC в K8s - прямое применение Role-Based Access Control
  • sec-19 — Supply Chain Security - следующий уровень: откуда образы берутся
  • sec-26 — IAM políticas применяются к Kubernetes ServiceAccount
  • os-19-containers
Безопасность контейнеров и K8s

0

1

Войти