Информационная безопасность
Безопасность контейнеров и 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