Kubernetes Security#
Link: https://habr.com/ru/companies/vk/articles/730158/
Корректная конфигурация кластера k8s#
- K8s CIS Benchmark => kube-bench, проверка конфигов узлов кластера;
- Ограничить сетевой доступ к k8s API (white lists, VPN);
- Каждый пользователь имеет уникальный ID при доступе к k8s API; после развертывания кластера никто не должен в нем аутентифицироваться как system:masters:
- если кто-то украдет у меня этот kubeconfig, придется перевыпускать все сертификаты в кластере, потому что отозвать доступ у группы system:masters без этого невозможно.
- Настроить RBAC. Например, некий оператор в кластере получает список всех подов. В этом случае не нужно выдавать ему возможность видеть все секреты и тем более редактировать их.
Сканирование образов#
- Разбор уязвимостей: не каждая из них ведёт к эксплуатации;
- Использовать общие базовые образы - при нахождении в таких уязов, их моно заменить и перезапустить CI/CD;
- Уменьшение числа зависимостей; Инструменты debug не должны оказываться в образах для prod;
- Собираем артефакт отдельно и копируем в итоговый контейнер, который будет использоваться в кластере.
Сетевая безопасность#
- CNI с сетевыми политиками; Если stage + prod в 1 кластере, разрабы попадают в stage, а из него - в prod, если нет сетевой изоляции; “политики как код” - развёртываются вместе с приложениями из Git-репозитория; Внедрять политики со старта, пока всё просто;
- Ingress + egress политики настроены для всех компонентов кластера;
- Все соединения должны быть явно разрешены.
Контроль над запускаемыми приложениями#
- Pod Security Admisson закрывает базовые потребности
- Pod Security Standards запрещают пускать поды от root, использовать host network и т.д.
- Если этого недостаточно, тогда:
- Точки контроля:
- Запрет на использование образов с DockerHub;
- Обязательно указывать priorityClass;
Аудит и регистрация событий#
- Самый простой из коробки - аудит Kubernetes API;
- Логирование в файл или stdout, отправка в SIEM и анализ.
- Часть команд (пример: crictl exec) не отобразятся в логе Kubernetes API. Нужен сквозной аудит хостовая ОС + k8s узел. Например, с помощью Falco:
- системные вызовы на хосте;
- аудит-лог от Kubernetes API с помощтю Webhook backend;
- проверка потока событий с помощю сконфигурированных правил;
- отправка алертов в случае нарушений правил.
- Технология eBPF в ядре - для событий хоста + контейнеров одновременно.
Расширение защиты#
- Аутентификация и авторизация
- Аудит RBAC
- Управление секретами
- Защита цепочек поставок:
- Запрет запуска образов с уязами;
- Запуск только подписанных образов (cosign).
- Режим обучения для создания политик;
- Авто-реагирование на события аудита.
История ИБ K8s#
- 2016 - на kubelet не было механизма аутентификации. Надо было через SSH-Tunneling защищать. 120 вариаций k8s в 2024. В 1 до сих пор осталась эта проблема;
--insecure-port=8080- даёт cluster-admin без авторизации. Можно нацелить kubectl на него и получить все права. Убрали только в 1.20; Облачный пров повесил этот порт на container network, клиенты не могли его выключить;- Irrevocable credentials. Нет поддержки по удалению клиентских сертификатов; Заказчик даёт аудитору k8s файл такого серта, из группы system:masters, и далее в течение года он действителен; irrevocable secrets - вплоть до 1.25, никогда не протухают, убиваются только вместе с service account. Они рано или поздно утекают - в git repo, в тикете к поддержке и т.д. Взамен пришли expiring token requests;
- RBAC появился не сразу. Было
--authorization-mode=AlwaysAllow. В 1 вариации k8s до сих пор так осталось. - Helm 2 + служба Tiller (у которой по gRPC TCP44134 нет аутентфикации, и он обычно cluster-admin), которую можно найти по DNS и компрометировать кластер.
- Июль 2024 SAP Ai Core - взлом SAP через Tiller
Что сегодня#
- До сих пор можно выдавать client certs, а также long-lived tokens - до 1 года; По-умолчанию нигде (кроме OpenShift) вот это всё не включено сразу:
- Pod Security Admission GA 1.25
- Validating Admission Policy GA 1.30
- Внешние опции (Kyverno, OPA и т.д.)
“Unpatchable 4”#
CVE-2020-8554#
Перехват трафика в multi-tenant кластерах. Кроме тех, где Cillium работает БЕЗ kube-proxy (потому что этот баг зависит от kube-proxy); Либо с помощью Kyverno и т.д. заблокировать создание clusterIP на внешних service with external ip.
CVE-2020-8561#
Server-Side-Forgery (SSRF). ValidatingAdmissionWebhook + Remote Debug Level = Debug (MAX)
CVE-2020-8562#
SSRF + Time-of-Check-Time-of-Use (TOCTOU) K8s API = HTTP-Proxy по сути своей. Но в нём есть hardcoded список адресов IP, куда он не проксирует (например, localhost). При наличии подконтрольного DNS, можно кидать к нему запрос на подключение на случайный IP, а DNS транслирует его в сторону API-сервера как localhost.
Лечится с помощью службы konnectivity, защищающей k8s Control Plane от запросов от Pod Network. https://kubernetes.io/docs/tasks/extend-kubernetes/setup-konnectivity/ https://stackoverflow.com/questions/61706923/what-is-the-konnectivity-service-for-kubernetes
CVE-2021-25740#
Multi-tenant environment. Load-balancer allows requests from endpoint and passes commands to other namespace.
Deckhouse Kubernetes Platform (DKP)#
Pod Security Standards
- Privileged - системные задачи
- Baseline - политика по-умолчанию в DKP
- Запрет на доступ к хосту hostProcess=true
- Запрет на host namespaces PID
- Запрет на запуск привилегированного пода
- Запрет на Host Storage Values
- Не допускает открытие всех сетевых портов
- Настройки SELinux ограничены
- Только допустимые capabilities
- sysctls только из списка
- уменьшенное число значений seccomp profile
- уменьшенное число capabilities
- Restricted - значительные ограничения
- Все ограничения Baseline
- Volume types только из списка
- В явном виде Privilege escalation = false
- runAsNonRoot=true
- уменьшенное (относительно Baseline) число значений seccomp profile
- уменьшенное (относительно Baseline) число capabilities
Seccomp#
Seccomp Profile - список разрешённых системных вызовов ядра Linux (whitelist/blacklist)
Capabilities#
Привилегии при запуске процессов. Рекомендуется сначала drop=all, а потом разрешить только нужные.
securityContext#
На уровне контейнера или пода. Вставляет поля в манифест пода с параметрами и ограничениями выше. Если описан контекст для контейнера, то он перетирает контекст для пода.
Для отработки securityContext в манифесте пода, он должен быть запущен в namespace с security label, например, security.deckhouse.io/pod-policy=restricted
Admission Controllers#
Mutating controllers - изменяют манифесты из запроса:
- Перехватывает с помощью webhook и меняет манифест пода. Validating controllers - проверяют манифесты из запроса на правила:
- Проверяет манифест на соответствие параметров безопасности и другие параметры.
DKP использует модуль admission-policy-engine (OPA Gatekeeper) для расширения Pod Security Standards. Если под по политике не проходит, то будет Deny/Dryrun/Warn (различаются уровнями verbosity).