k8s (in)security – Telegram
k8s (in)security
12.1K subscribers
1.01K photos
38 files
1.56K links
Канал о (не)безопасности Kubernetes + микросервисных, контейнеризированных приложений.

Ведет команда www.luntry.ru

Вопросы, идеи, предложения => @Qu3b3c

https://knd.gov.ru/license?id=673ddbc21039886b1d03b7ce&registryType=bloggersPermission
Download Telegram
Сегодня рассмотрим сервис AWS IAM, как основной инструмент для аутентификации и авторизации AWS EKS.
Для аутентификации EKS использует Webhook Authentication Token, API-серверу передаётся специально сформированный токен, в котором передаётся идентификатор ARN (Amazon Resource Name) IAM-пользователя/роли.

Далее API-сервер, с помощью AWS IAM Authenticator обращается к сервису AWS IAM, который проверяет имеет ли данный пользователь права обращаться к кластеру AWS EKS, сравнивая ARN запроса с ARN mapRoles в aws-auth ConfigMap.

После того, как пользователь прошёл аутентификацию, Kubernetes должен c помощью Role Based Access Control проверить сам запрос — есть ли у данного клиента право на выполнение запрошенных действий, например — выполнение вызова kubectl get pods. Так же для аутентификации AWS EKS в качестве альтернативы может использоваться OpenID Connect (OIDC).
Таким образом, при условии грамотной конфигурации, AWS IAM представляет собой мощный инструмент для обеспечения безопасности AWS EKS.
На этой неделе будет небольшой цикл постов про sensor-based решения по безопасности для Kubernetes. Мне с командой довелось посмотреть, покопаться во внутренностях во всех широко известных решения на сегодняшний день (знаю, как там работает любая функциональность). Ну и плюс мы сами занимаемся разработкой решения для observability и visibility происходящего в Kubernetes кластере, также в sensor-based архитектуре и знаем разные тонкие и не очевидные моменты, которыми можем поделиться. Рассказывать я буду без упоминаний брендов, при этом считаю, что у каждого из них есть как свои слабые, так и сильные стороны, так что у каждого найдется своя аудитория. При этом имея обширный опыт работы с сенсорами от Antivirus, EDR (Endpoint Detection and Response) решений позволит мне провести параллели и с ними.

Sensor-based решения раскатываются на все Node (обычно как DaemonSet) и затрагивают все приложения на них, поэтому очень важно знать и понимать, что и как они делают, чтобы не пострадала ни надежность, ни производительность, ни безопасность.

В комментариях к этому посту вы можете написать вопросы, и я постараюсь на все ответить либо сразу, либо в постах цикла.
Пару недель назад, AWS анонсировал релиз дополнения policy validation для IAM Access Analyzer - инструмент, позволяющий провести проверку конфигурации IAM политик на соответствие требованиям безопасности (более 100 проверок на основе AWS AIM best practices) и детальные рекомендации по настройке IAM в соответствии с принципами least privilege.

Пользоваться можно прямо из веб-интерфейса IAM Console при создании IAM политик, а та же CLI/API aws accessanalyzer validate-policy для интеграции с пользовательскими CI/CD workflows, без необходимости использования сторонних инструментов.

С точки зрения безопасника, это очень полезный и востребованный функционал, который призван хотя бы частично решить проблему мисконфигов связанных с излишними привилегиями при конфигурации IAM политик.
Первая часть из цикла про sensor-based решения по безопасности для Kubernetes.

Основная их задача, чтобы происходящее внутри контейнеров не было "черной коробкой" - видны процессы, их взаимодействие с файловой системой и сетью.

Сбор этой информации может происходить как ИЗ контейнера, так и ВНЕ его. Для первого случая решения используют sidecar- контейнеры, подмену системного компонента runc и встраивание (injection) собственных библиотек в процессы, пользовательских приложений. Для второго случая используются модули ядра и eBPF пробы.

1) Самым надежным и правильным решением на сегодняшний день считаются eBPF пробы - просто, быстро, стабильно.
2) Модули ядра предлагают, как вариант, когда ядро младше 4.19. При этом нужно понимать, что при ошибке в модуле и его падении - упадет и вся Node.
3) Sidecar- контейнеры могут помочь видеть только сеть и при этом дают значительные ресурсные издержки на каждый Pod.
4) Подмена runc обычно идет в связке со встраиванием собственных библиотек через LD_PRELOAD, dlopen, патчинг GOT таблиц и т.д. Все для того, чтобы подготовить окружение для запускаемого контейнера для его мониторинга - то есть происходит модификация окружения (контейнеры под таким решением и без него могут вести себя по-разному). Данная библиотека производит перехват нужных функций на user-space уровне. Получаем такой классический антивирус из нулевых. При этом накладные расходы по ресурсам размываются с расходами самого приложения и сложно сказать на сколько они в итоге повышаются, но точно падает скорость работы.

Для окружений с MicroVM (типа AWS Fargate) или serverless-функциями (типа AWS Lambda) работает только 4 вариант со встраиванием собственной библиотеки для перехвата ряда функций.
Вторая часть из цикла [1] про sensor-based решения по безопасности для Kubernetes.

Prevention - желание многих security-команд и страшный сон SRE-команд, так как это может как сломать что-то, так и просто внести неясность в работу из-за того, что изменения/правила известны только тем, кто их внес и могут быть видны только в инструменте, где были применены.

Sensor'ы могут это обеспечить по-разному (со своими плюсами и минусами): через системные механизмы, CRI и собственными силами.

1) Системные механизмы значит, что сам sensor этим не занимается, а занимается ОС с помощью seccomp, AppArmor, SeLinux в режиме prevention, а в случаи сети это вообще NetworkPolicy самого Kubernetes. В таком случаи sensor может помочь подготовить политики для данных механизмов, но применять их будет ОС. Обеспечивает высокий уровень надежности и контроля с высокой наглядностью для всех команд (так как можно прописать прям в YAML).
2) Сценарий с CRI (Container Runtime Interface) означает контроль на уровне работы всего контейнера - запуск, пауза, остановка. Реализации бывают разные и некоторые способны только на response, никакого реального prevention.
3) Категория собственными силами самая обширная и полностью зависит от способа работы (рассматривали в прошлом посте) самого sensor. В случае встраивания библиотек, тут классический антивирус - подгружающий в себя все что нельзя и на каждый системный вызов проверяющий можно это или нет. В случае eBPF все может быть очень красиво на базе KRSI (Kernel Runtime Security Instrumentation), но требует ядро > 5.8. Явным плюсом тут является возможность на лету менять сами политики/правила.

Важно понимать, что sensor как и ContainerRuntime достаточно опосредованно понимает, что такое сущности Kubernetes и мыслит в терминах контейнеров и происходящего в нем. Также sensor заранее не знает где и какой workload будет запущен и ряд проверок будет делать там, где это и не надо, замедляя работу даже тех сущностей, к которым prevention и не относится.
Третья часть из цикла [1,2] про sensor-based решения по безопасности для Kubernetes.

Согласитесь исполняемый файл bash запущенный в контейнере от entrypoint (runc) и bash запущенный вашим, например, java и python приложениями это 3 разных действия с точки зрения поведения bash. Или еще пример: Обращение к файлам в директории /var/run/secrets/kubernetes.io/serviceaccount/ двумя разными процессами в контейнере это 2 разных действия. К чему это все? А к тому, что разные sensor-based решения на происходящее внутри контейнеров смотрят с разным уровнем гранулярности (точности), которая потом ложиться в основу модели поведения или политики.

Я для себя выделил 3 типа гранулярности политик: слабое/низкое (1), среднее/гибридное (2) и сильное/высокое (3):
1) Все происходящее в контейнере относительно процессов, файлов и сетевого взаимодействия отражается в виде списков. То есть список процессов, что там был запущен, список файлов к которым было обращение и список сетевых endpoint'ов к которым было обращение. При этом эти списки не связана. Таким образом, если процесс bash есть, то непонятно от кого и он всегда разрешен, если есть обращение к /var/run/secrets/kubernetes.io/serviceaccount то это можно всем, соединение на определенный IP возможет от любого процесса в контейнере.
2) Это что-то среднее между низким и высоким уровнем гранулярности политик, относительно тех или иных связей между процессами, файлами и сетевыми операциями. Может быть много вариаций, в плоть до полного отказа от контроля от файловых операций. В основном, оставляют связи на уровни родитель-потомок.
3) Все происходящее в контейнере относительно процессов, файлов и сетевого взаимодействия отражается в виде графа. Это означает наличие иерархии взаимодействия между процессами и для каждого из них собственная иерархия взаимодействия с файловой системой и сетью. При этом каждый процесс в такой иерархии может иметь свои права доступа к файлам (r,w,rw).

Для решения той или иной задачи в определенных условиях, окружении может быть достаточно и слабой гранулярности, но понять это можно для начала имея полную картину происходящего.
Новое исследование "Who Contains the Containers?" от исследователя из Google Project Zero с результатом в 4 LPE уязвимости в Windows Server Containers.

Данное исследование началось из-за того, что в Google сообщили об уязвимости, которая позволяет сделать побег из контейнера в GKE, работающем на подсистеме Windows Server Containers. При этом данная подсистема не является по мнению Microsoft никаким security boundary, то есть и проблемы тут не являются уязвимостями и не будут закрываться в рамках security bulletin, а только в следующих major версиях Windows или вообще не будут ...

Помимо того, как происходило данное исследование и были найдены эти уязвимости вы можете узнать о том, как вообще работает контейнеризация в Windows, которая позволяет запускать Kubernetes.

Как итог GKE не рекомендует использовать Windows Server Containers для multi-tenancy сценариев, а другой более безопасный вариант запуска контейнеров через Hyper-V Isolated Containers не поддерживает.
Четвертая часть из цикла [1,2,3] про sensor-based решения по безопасности для Kubernetes.

Что это за контейнеры, за которыми идет наблюдение разные решения могут видеть на разном уровне детализации. Тут нужно вспомнить как работает Kubernetes с Container Runtime через CRI. Вся цепочка создания Pod сокращенно выглядит так: создаётся ресурс Pod, далее Container Runtime создает контейнер и происходит обновление статуса ресурса через добавление информации о контейнере, который работает в данном Pod'е. Kubernetes только уже после фактического запуска контейнера связывает информацию с ресурсом Pod.

В связи с этой не очень простой схемой разные решения к контейнеру присоединяют (enrichment стадия) разное количество информации. Самый полный комплект выглядит таким образом:
- Image : k8s.gcr.io/etcd
- Digest : sha256:303ce5db0e90dab1c5728ec70d21091201a23cdf8aeca70ab54943bbaaf0833f
- Tags : k8s.gcr.io/etcd:3.4.3-0
- Container ID : eaadea8d867e2833b1fee449a993ec96c2708bbec37e9349369a6541f796d9ae
- Container Name : etcd
- Cluster : PROD
- Node : flex-f94c4afe-1
- Namespace : kube-system
- Pod : etcd-flex-f94c4afe-1
- Kubernetes Resource : StaticPod:etcd
- UID : 816f47b8-02bd-456d-8b1e-3b1a3f1fa318

Чем больше решение присоединяет информации к контейнеру или событию в нем, тем проще расследовать сбои и инциденты.
Пятая и заключительная (на данный момент) часть из цикла [1,2,3,4] про sensor-based решения по безопасности для Kubernetes.

Важный момент — это потребления сенсорами ресурсов: CPU (millicore) и Memory RAM (Gb).

Чаще всего разработчики явно задают Request это в итоге:
- Для CPU от 20 до 1000, тоесть от 2% от ядра до 1 ядра.
- Для Memory RAM от 0,5 до 1 Gb

С Limits все сложнее и не все даже это указывают. Но у некоторых в документации можно найти:
- Для CPU до 2 ядер
- Для Memory RAM до 4 Gb

Стоит понимать, что нагрузка на sensor и необходимые для его работы ресурсы зависят от:
- Размеров/храктеристик Node - Node с 80 ядрами это не тоже самое что и с 8 ядрами.
- Активности приложений на Node - Сколько их всего работает на Node. Приложение, что устанавливает соединение и обрабатывает все в памяти генерирует во много раз меньше нагрузки (системных вызовов), тем то, что еще попутно что-то перекладывает на файловой системе

P.S. 24 марта этого года данному каналу исполнился 1 год. Большое спасибо всем, кто читает, комментирует, делится постами, помогает увеличению сообщества! Я совсем забыл об этом так как в это же день в этом году у меня родился сын =)
В продолжении темы про конфигурацию AWS IAM, в традициях лучших практик, сегодня рассмотрим инструмент CloudQuery, который позволяет проводить проверку настроек IAM политик с использованием синтаксиса SQL запросов и обеспечивает возможность визуального мониторинга изменений с помощью Neo4j базы данных. CloudQuery содержит встроенный набор IAM политик, созданный на основе AWS CIS Benchmark. Помимо AWS, CloudQuery поддерживает работу с следующими провайдерами: Azure, GCP, Okkta.

Для того чтобы начать пользоваться, необходимо просто скачать и запустить pre-compiled binaries, либо развернуть готовый образ контейнера в Docker, создать файл конфигурации, описывающий сервисы, которых необходимо проверить, выбрать предпочтительную базу данных postgresql/neo4j, авторизоваться и использовать знакомый и понятный синтаксис SQL запросов, например чтобы показать все образы EC2 инстансов: SELECT * FROM aws_ec2_images;

Таким образом, мы имеем еще один инструмент для конфигурации IAM-политик и мониторинга использования облачных сервисов с поддержкой SQL и удобной графовой визуализацией Neo4j, который точно не будет лишним для решения проблем избыточных привилегий IAM.
Инструмент KICS (Keeping Infrastructure as Code Secure) - Find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle of your infrastructure-as-code.

Так как движение infrastructure as code не стоит на месте и набирает обороты/популярность, то известные решения в области статического анализа исходного кода не могли остаться в стороне. Данное решение как раз от одного из таких вендоров. На текущий момент инструмент уже умеет анализировать:
- Terraform
- Kubernetes
- Docker
- CloudFormation
- Ansible
- Helm

По заверению авторов есть более 1000 запросов/правил/проверок - под капотом которых Open Policy Agent (тоесть язык Rego). Все проверки (80 штук) связанные с Kubernetes можно посмотреть тут в очень хорошей документации. Естественно, встраивается в CI, есть инструкции для Github Actions, GitLab CI, Azure Pipelines, Bitbucket Pipelines. А отчеты можно получать в форматах JSON, SARIF, HTML.
Статья "PodSecurityPolicy Deprecation: Past, Present, and Future".

Под таким недвусмысленным и широким названием вышла статья в официальном блоге Kubernetes. Данную статью можно считать, как официальную позицию по ситуации с PodSecurityPolicy, вокруг которой последнее время много разной движухи.

Краткая выжимка:
- PodSecurityPolicy (PSP) перейдет в статус deprecated в версии 1.21
- Alpha релиз замены должен состояться в версии 1.22
-Старая версия будет удалена скорее всего в версии 1.25
- Разрабатывается замена для покрытия ключевых потребностей
- Изменения связанные с PSP никаким образом не повлияют на PodSecurityContext
- Основная причина отказа от текущей реализации – не удобство в использовании
- K-Rail, Kyverno и OPA/Gatekeeper это хорошо, но надо иметь простую, гибкую и встроенную реализацию
- За разработкой замены можно следить в Kubernetes Enhancement Proposal (KEP 2579)
Для тех, кто занимается обеспечением надежности (reliability) работы своих сервисов следующие метрики точно знакомы:
- MTTF - mean time to failure (среднего времени до отказа)
- MTBF - mean time between failures (среднего времени между отказами)
- MTTD - mean time to detect (когда проблема уже присутствовала, но о ней еще не было известно)
- MTTR - mean time to repair/recover/resolve/response (среднее время, необходимое на восстановление работоспособности системы после получения сигнала о сбое.)

Возвращаясь к тому, что reliability и security вещи не разделимы, то эти же метрики можно совершенно успешно использовать и в security для работы с инцидентами безопасности. Так, на пример, MTTD + MTTR = это общая продолжительность инцидента информационной безопасности.

В контейнерных инфраструктурах (Kubernetes не исключение) очень важно фиксировать инциденты ведь контейнеры/поды сущности эфемерные и часто завершаются, все унося с собой ...
Сегодня поговорим про Workload Identity в GKE
Очень часто в managed Kubernetes нам приходится работать с managed базами и другими облачными ресурсами. Для аутентификации в них у каждого облака есть IAM и ServiceAccount'ы, которые позволяют гибко настроить доступы. В общем случае чтобы получить токен от ServiceAccount'а нужно обратится в Metadata API c инстанса, ServiceAccount задается для каждого Compute instance.

Минусы такого подхода для Kubernetes:
- из-за того, что на одной ноде могут быть разные поды и нагрузки, приходится выдавать больше привилегий ServiceAccount
- из-за миграций нагрузок по нодам, приходится выдавать всем нодам одинаковый ServiceAccount
В итоге данное решение не очень гибко и противоречит least privilege principle.
Альтернативно, можно хранить ключи от ServiceAccount'ов в Kubernetes Secrets, но тогда необходимо самому задумываться о ротации ключей.

Тут нам на помощь приходит Workload Identity
Эта фича позволяет Kubernetes ServiceAccount'ам аутентифицироваться за Cloud ServiceAccount. Таким образом, пропадает зависимость от Compute ServiceAccount, и решаются вышеописанные проблемы.
В GKE Autopilot (о котором мы писали ранее) эта опция включена по дефолту. Технически это реализовано через перехват запросов к Metadata API, в кластер добавляется DaemonSet с соответствующим функционалом.

Вердикт - must have для тех, кто работает с облаком из GKE. Более того, данный инструмент может оказаться удобнее, чем альтернативные методы.
Некоторое время назад наткнулся на упоминание документа (о котором раньше никогда не слышал) "A Master’s Guide To Container Securing" по безопасности контейнеров. Если вы себя считаете настоящим контейнероводом или специалистом по их безопасности, то обязательно к изучению. После вы сможете поддержать обсуждение о любых контейнерах.
CDK - container penetration toolkit, offering stable exploitation in cloud-native docker/k8s/serverless deployments.

Инструмент будет презентован:
- 6 мая на BlackHat Asia 2021 на докладе "CDK: Zero Dependency Container Penetration Toolkit"
- 27 мая на HITB Amsterdam на докладе "Attacking Cloud Native Kubernetes with CDK"

Это набор сетевых тулов, PoC'ов и эксплоитов для побега из контейнеров и захвата Kubernetes кластера. Есть 3 основных модуля:
- Сбор информации - 12 тактик по Information Gathering (9) и Discovery (3)
- Запуск эксплоитов - 21 тактика по Escaping (11), Remote Control (1), Credential Access (3), Privilege Escalation (1), Persistence (5)
- Запуск дополнительных инструментов (8)

+ режим auto-escape для автоматического побега из контейнеров.

При этом также есть несколько версий: all, normal, thin, upx. Так thin оптимизирована для работы в контейнерах с коротким жизненном циклом (на пример в Serverless), upx помогает обходить сигнатурные средства защиты.
Сегодня рассмотрим opensource boilerplate для создания базовой инфраструктуры EKS-кластера и вспомогательных сервисов в облаке AWS от MadDevs. С точки зрения архитектуры, решение представляет собой VPC из 3-eх публичных подсетей для ресурсов k8s, которые должны быть доступны из интернета, 3 приватные подсети с доступом к интернету через Nat Gateway и 3 приватные подсети для RDS развернутые в 3-ех availability zones для обеспечения redandency.

В качестве точки входа в k8s используется сервис Elastic load balancing (ELB) за VPC Internet gateway. В шаблоне также используется: сервис Route53 для управления DNS, Cloudwatch - для мониторинга работы ресурсов, AWS Certificate manager - для управления сертификатами, ECR - для хранения docker образов и SSM Parameter Store - для хранения секретов и конфигураций. Для развертывания инфраструктуры и сервисов используется terraform. Стоимость ресурсов, которые разворачиваются в облаке AWS при дефолтной конфигурации этого шаблона составляет $217/мес. без учета стоимости трафика. Решение актуально, для тех кто хочет развернуть k8s на Amazon по-быстрому, например для тестов, без необходимости вникать в детали и тонкости настройки сопутствующих сервисов этого облачного провайдера. Если же хочется потестить бесплатно, то рекомендуем обратить внимание на EKS distro на собственной инфраструктуре.

С точки зрения безопасности все относительно неплохо, при условии что IAM-политики и правила Security groups сервисов грамотно настроены самостоятельно. И в качестве пожелания для разработчиков решения, добавить в дефолтную конфигурацию использование AWS Secret Manager вместо SSM Parameter Store для хранения секретов в зашифрованном виде.
Аудит Helm 3. В начале 2021 года под эгидой CNCF опубликовали результаты второго 3rd party security audit, но уже для Helm 3.3.0-rc.1. В рамках данной работы был проверен анализ исходного кода клиентской части и составлена модель угроз (Threat Model) при использовании Helm. Про прошлый можно почитать здесь.

Команда: 2 консультанта, 3 человеко-недели.

Найдено проблем: 3 Medium, 7 Low, 3 Info. Проблемы исправлены в версии 3.3.2.

Модель угроз вы можете наблюдать на скриншоте.
Интересное виденье одной из компаний о том, как должен выглядеть процесс работы с NetworkPolicy, даже с какой-то стороны их жизненный цикл. На схеме видно как разные команды (Sec, Ops, Dev) для разных уровней/задач в определенной последовательности вводят сетевые политики.

Определенно это некий идеальный пример, но в нем можно найти некоторую систематизацию и что-то перенять на свою компанию и попробовать наложить на собственные процессы.
CVE-2021-25735: Validating Admission Webhook does not observe some previous fields

Уровень критичности Medium (CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H)

Уязвимость находится в kube-apiserver и позволяет при обновлении Node атакующему обойти Validating Admission Webhook

Под влиянием только сторонние validating admission plugins, встроенный NodeRestriction работает как полагается.