Обновить

Выбор инструментов для доставки секретов в Kubernetes. Наш путь delivery of secrets

Уровень сложностиСложный
Время на прочтение6 мин
Охват и читатели7.4K
Всего голосов 8: ↑7 и ↓1+8
Комментарии26

Комментарии 26

Наконец-то отличная тема! Вы уверены, что правильно понимаете зачем нужен Vault?

  1. Допустим, мы используем Базу Данных.

  2. Для соединения с БД нам нужен пароль. Т.к. без пароля злоумышленник получит все наши данные.

  3. Мы не кладем пароль в конфиги, т.к. злоумышленник прочитает конфиги и получит пароль БД...

  4. Мы храним пароль в Vault.

Отлично! Теперь вопрос: у вас есть пароль для самого Vault?

  1. Если нет, то злоумышленник прочитает Vault и получит пароль БД...

  2. Если да, то вам нужен Vault2 чтобы хранить пароль Vault...

Итак: вы уверены, что правильно понимаете зачем нужен Vault?

Здравствуйте!
Отвечая на ваши вопросы:

  1. Что значит пароль для самого Vault? И каким образом злоумышленник прочитает Vault, если:


    а) root token глубоко спрятан и доступен только лицам, которые отвечают за Vault кластер


    б) Те, кто имеют доступ к Vault авторизуются в нем исключительно по LDAP (если мы говорим про UI)


    в) Для того, чтобы микросервисы могли авторизоваться и забирать нужные секреты Vault настроена kubernetes авторизация на основе SA токенов по определенным политикам исключительно на чтение нужных секретов сервиса. (Собственно во второй части об этом будет информация)


    г) Root-токен вообще не используется для авторизации пользователями

  2. "то вам нужен Vault2 чтобы хранить пароль Vault" - мне очень интересно, как вы пришли к такому выводу о паролях Vault? Если изначальная из коробки аутентификация и авторизация происходит по root токену, если не настроено иное. Использование которого, как уже оговаривалось выше, является совсем не безопасным, так как есть риск утечки.

    Что же касается хранения тогда уж НЕ пароля а Root-токена, то об этом как раз будет вторая часть статьи)

    На основе двух вышеописанных пунктов, смею задать вам встречный вопрос : а вы уверены, что правильно понимаете зачем нужен Vault и как его использовать? =)

Для того, чтобы микросервисы могли авторизоваться и забирать нужные секреты Vault настроена kubernetes авторизация на основе SA токенов по определенным политикам исключительно на чтение нужных секретов сервиса.

это называется Security through obscurity. а мы смотрим по сути! и видим два утверждения:

  1. с БД небезопасно соединяться без пароля.

  2. но с Vault безопасно соединяться без пароля.

гмм... тогда:

  1. если в Vault реализован "волшебный способ" соединения, то тот же самый способ мы можем СРАЗУ же использовать и для БД => Vault не нужен!

  2. а если сказок не существует, то Vault мы используем небезопасно => Vault нам не нужен тем более!!

как-то так :)

У меня встречный вопрос к вам: вы я так понимаю кроме метода авторизации по паролю, других не пробовали?

1) по JWT

2) по SSL

3) по access токенам

Ну и тогда лее (то что сразу в голову пришло)

Пароль, точно также, как и токен, точно также, как сертификаты для авторизации, может быть скомпрометирован. Мы с вами говорим о совершенно разных вещах, вы скажем так, прицепились к тому, что в Vault авторизация без парольная, это действительно из коробки так. Но там авторизация идёт по токену, который точно также может быть утерян, скомпрометирован. Но в отличие от пароля никаким брутфорсом или иным методом НЕ подобран.

Как итог: мнение в том числе и разработчиков Vault( раз уж они из коробки авторизацию по root токену вшили) что аутентификация и авторизация по паролю менее безопасная, чем по токену, который, вновь повторюсь, в отличие от пароля НЕ может быть подобран простым перебором, брутфорсом и т.д.

P.S: почитайте про методы авторизации в Vault, про JWT токены, про access и refresh токены. А то у меня создалось ощущение, что вы даже не стали вчитываться в мой ответ =)

У меня встречный вопрос к вам: вы я так понимаю кроме метода авторизации по паролю, других не пробовали?

вообще-то я Lead Solutions Architect и задаю этот вопрос на собеседованиях :) и как правило, 80% "архитектров" в ответ сыпят buzzword-ами не понимая СУТИ.

так давайте мы здесь сейчас разберемся и тем самым им всем поможем. итак, еще раз.

дано:

  1. нам не дают соединиться с БД без пароля, т.к. это небезопасно.

  2. но! нам дают без пароля соединиться с Vault и взять там пароль БД.

вопрос: нет ли здесь противоречия? :)

Я не могу ответить на поставленный вами вопрос, так как природа возникновения вашего утверждения "но! нам дают без пароля соединиться с Vault и взять там пароль БД" - мне не ясна.

И я в очередной раз буду утверждать, что беспарольная авторизация != отсутствие авторизации. Так как в Vault есть авторизация (из коробки по токену) из типов и методов в том числе, можно создать локальную УЗ с паролем.

Позтому, если это возможно, изложите свой тезис немного иначе. Так как со вторым пунктом я в корне не согласен, так как это не корелируется с Vault по ранее указанным мною пунктам :)

"нам дают без пароля соединиться с Vault и взять там пароль БД" - вам не дают соединиться с Vault без какого-либо типа авторизации, она все равно есть. Будь то UI для обычного пользователя. Будь то токены, пароли, LDAP и т.д для админов, либо сервисов =)

вам не дают соединиться с Vault без какого-либо типа авторизации, она все равно есть

именно это и хотелось бы уточнить. давайте рассмотрим сферический Vault в вакууме:

  1. мы ставим на Linux сервер нативное Приложение.

  2. у Приложения есть конфиг и ему нужно работать с Базой.

а дальше уже интересно:

  1. все дети знают, что пароль к Базе нельзя хранить в конфиге!

  2. все дети знают, что пароль к Базе нужно хранить в Vault.

вы, как представитель частного капитала, не можете остаться глухи к стонам родины! одни лишь маленькие дети, беспризорные, находятся без призора. и мы, господа присяжные заседатели, им поможем :)

объясните pls детям как В ЭТОМ СЛУЧАЕ безопасно добыть пароль из Vault.

а Kubernetes мы разберем потом, т.к. детям не нужно buzzwords и obscurity, окай? :)

Окей :)

6. Раз все дети знают, что пароль к Базе нужно хранить в Vault, то делаем вывод, что все дети знают что такое Vault, хотя бы просто знают =), таким образом:
все дети, зная что такое Vault, могут пойти и узнать или мы им можем поведать, что у чудного, неведомого Vault, есть инструмент (Database Secret Engine - не вдаваясь в тех. подробности сейчас).
7. все дети ТЕПЕРЬ знают, что есть инструмент для безопасной добычи пароля из Vault (абстрагируясь от абстракций Kubernetes, VM и т.д. будь то железка)
8. все дети, ТЕПЕРЬ знают, что в принципе есть различные инструменты безопасного извлечения секретов из Vault.

P.S: дети же когда-то, от кого-то узнали, что такое База и почему нельзя хранить пароль в конфиге, дети же когда-то узнали, от кого-то узнали, что пароль к Базе нужно хранить в Vault - соответственно именно дети задались вопросом: "А как соединить эти две сущности, чтобы безопасно получить пароль?" и пришли с ним ко взрослым =)

вопрос: нет ли здесь противоречия? :)

поначалу кажется, что есть, но на самом деле его нет )

в отличие от пароля НЕ может быть подобран простым перебором, брутфорсом и т.д.

это пока

  • не нашли фатальный недостаток в алгоритме генерации токенов (дело времени)

  • или пока не изобрели квантовые компьютеры, которые все шифры прошлого и современности, ломают на раз два

"но с Vault безопасно соединяться без пароля" - данным своим утверждением, вы полностью подтверждаете, что даже не вчитывались в весь мой ответ вам, в котором я не раз подчеркнул про root-токен и другие типы авторизаций в Vault

Кстати, что касается вашего конкретного примера с БД, отвечу и на это, для авторизации микросервисами в БД есть специальный тип для этого "Database Secret Engine" https://developer.hashicorp.com/vault/docs/secrets/databases

Как я это прочитал:

  1. Разработчики кубернетес придумали хранить конфигурации в объектах ConfigMaps, а секретные/не публичные значения в объектах Secrets, для доступа к которым можно настроить отдельные rbaс

  2. Это выглядит не безопасным, ведь секреты могут утекать, если неправильно настроены rbac, или у вас выполняются, а потом утекают, дампы etcd

  3. Поэтому нужно использовать Vault, там можно гранулярнее задавать доступы к секретам и вести аудит доступа

  4. А чтобы было удобно, используем оператор Vault Secrets Operator, который поместит секретные значения в кубернетес объекты Secrets

  5. После чего в аудите Vault не будет никакой информации о доступе приложений к секретам (потому что они получают доступ к секретам через Secrets Kubernetes), а сами секреты продолжат утекать аналогично п. 2

Итого: мы не хотели хранить секреты в secrets kubernetes, и вместо этого использовали 2 других инструмента, чтобы ... в итоге хранить секреты в secrets kubernetes

Все время вспоминаю мультфильм Золотые ворота

Здравствуйте.


Да, с вашими тезисами соглашусь отчасти. Но конечная цель была в удобстве, отсутствии лишних рабочих нагрузок (в отличие от того же Vault Agent Injector, где у нас есть sidecar и init контейнеры) и в быстрой доставке:


"поэтому нам нужно было ускорить и оптимизировать доставку секретов в контейнеры с микросервисом, избежать дополнительных рабочих нагрузок в kubernetes, гарантировать безопасность при доставке секретов и исключить внешние зависимости" - вот главные причины, по которым мы пришли к инструментам, о которым говориться в самом конце. И тут сделан акцент на "гарантировать безопасность при доставке секретов" - доставка секретов безопасная, а вот ее итоговое хранение в Opaque Secrets почти в открытом виде (так как все мы знаем, на сколько безопасен base64 энкодинг =) ) - действительно нет.

Что же касается безопасности хранения секретов:
1) Vault здесь используется как единый источник хранения секретов, таким образом нам не нужны секреты хранить в репозиториях (пусть даже с шифрованием в виде инструментов SOPS, helm secrets, etc...) - ведь если мы говорим о подходе IaC, что для нас немаловажно, то хранить даже секреты где-то нужно и чтобы это "где-то" - было единственным источником правды.

2) Что касается secrets и rbac - тут вы правы про гранулярность и аудит доступов к Opaque Secrets. Поэтому вторая часть статьи будет именно про то, какие решения есть для шифрования этих Opaque Secrets уже непосредственно в etcd или обхода Opaque Secrets в процессе доставки секретов в микросервисы

3) Ну и третье (из разряда "паранойи" =)) - если у злоумышленника есть доступ к Kubernetes кластеру, где он может даже с учетом настроенных rbac просмотреть Opaque Secrets, то он уже может "веселиться" с кластером, как он хочет. И говорить тут о чем-то более важном не имеет уже особого смысла.

Безусловно с точки зрения ИБ стоит вопрос о том, что есть также проблема, что в конечном счете секреты хранятся в переменных окружения, а не где-нибудь в RAM, shared memory и т.д. Собственно во второй части статьи будут предложены решения в том числе и по данной проблеме.

. И тут сделан акцент на "гарантировать безопасность при доставке секретов" - доставка секретов безопасная, а вот ее итоговое хранение в Opaque Secrets почти в открытом виде (так как все мы знаем, на сколько безопасен base64 энкодинг =) ) - действительно нет.

с этим нет проблемы. Потому что в etcd секреты пошифрованы. А если вы не верите в RBAC кубера, то у меня для вас очень плохие новости, потому что любые меры поиграть в прятки с секретами обеспечены на провал. Тупо имеем кластер админа - значит, либо мы уже легко можем переконфигурировать средства доставки секретов, либо запустить паразитные нагрузки, которые прикидываются легитимными...

1) Vault здесь используется как единый источник хранения секретов, таким образом нам не нужны секреты хранить в репозиториях (пусть даже с шифрованием в виде инструментов SOPS, helm secrets, etc...) - ведь если мы говорим о подходе IaC, что для нас немаловажно, то хранить даже секреты где-то нужно и чтобы это "где-то" - было единственным источником правды.

а это проблема, потому что автоматически влетаем в следующие вопросы

  1. как мы будем вольт бекапить? Если нет другого золотого источника правды - ну, вольт им становится, значит нам нужно подходить к нему как к питомцу. Лелеять, лечить.

  2. Vault автоматом становится критическим узлом на пути всего - деплоя, запуска и прочего. Вольт играет в поваляшки - инфраструктура начинает напоминать дорогущий чемодан без ручки. Следовательно, автоматом требования к HA, возможности обслуживать Highload etc. При чем на ровном месте. Оно надо?

  3. все процессы доставки секретов асинхронные. То есть это означает определенный порядок при релизе (сначала добавляем секрет, потом проверяем, что он доехал, потом уже обновляем приложение), что уже гемор. Как же просто было с sops! Тупо закидал манифестов и подождал. А еще означает, что нужно все покрывать мониторингом. А это уже веселее - потому что весь опенсурс, откровенно скажу, сделан из пофигизма, говна и палок. Даже в таких известных и давно используемых компонентах вроде cert-manager есть куча проблем, которые че-то авторы не торопятся исправлять. И шанс налететь на корнес кейсы тем увеличивается, чем больше разнородных компонентов в инфре. Вот - уже из статьи ясно - одним вольтом мы не обойдемся, нам еще ESO надо зашлифовать, потом kyverno какую-нибудь еще и так далее по перечню. Получается, как лего. Только в отличии от лего - тут кубики разномастные и не очень подходят друг к другу ))) Как там договорится - доработать напильником

Разработчики кубернетес придумали хранить конфигурации в объектах ConfigMaps, а секретные/не публичные значения в объектах Secrets

я вам даже больше скажу, разработчики кубернетес такие забавники:

Kubernetes 1.7 introduced encryption of Secrets but doesn’t enable it by default. Even when this becomes default, the data encryption key (DEK) is stored on the same node as the Secret! This means gaining access to a node lets you to bypass encryption. This is especially worrying on nodes that host the cluster store (etcd nodes).

Да, увы. Складывается ощущение, что безопасность из коробки до сегодняшних версий Kubernetes (вплоть до 1.30/1.31) совсем НЕ является приоритетом ни в каком виде.

Итого: мы не хотели хранить секреты в secrets kubernetes, и вместо этого использовали 2 других инструмента, чтобы ... в итоге хранить секреты в secrets kubernetes

тут сознательно упускается момент, что

  1. абсолютно безопасную систему не построить

  2. следствие - надо идти на компромиссы

  3. аудит вольта - уже явно лучше аудита секретов в кубере

  4. и если секрет утечет - его можно будет, условно, поменять "одной кнопкой" везде, а не бегать по 100500 секретов в 100500 кластеров, лихорадочно пытаясь понять - а что надо менять-то!

  5. ну, и я ниже писал - надо от статических секретов уходить. Те же сертификаты с коротким сроком жизни (а vault умеет быть pki) или секреты одноразки - уже сильно сокращают поверхность атаки для злоумышленника. И тут сильно могут помочь средства раннего обнаружения атак. Очевидно, что если кто-то лазит по ФС контейнера с запросами вида `cat /proc/<pid>/environ` - это уже аномалия и нас уже ломают. А если секрет лежит в файле - ну, пойди отличи - легитимная ли это деятельность или нет.

В следующем посте я расскажу об использовании данного решения, о его плюсах и минусах, а также о задачах, которые остались открытыми. На этом у меня все, готов ответить на ваши вопросы.

очень ждем, потому что из всего вышеописанного - я попробовал все. И везде какие-то корнер кейсы и неприятные эксплуатационные особенности. Касательно переменных окружения - на мой вкус, это еще менее безопасно, чем (временный) файл. `cat /proc/<pid>/environ` и ХАТОВА. А vault-env - мы ловили приключения с недоступностью вольта, тогда приложение просто играет в поваляшки. Даже не знаю что лучше - иметь не очень актуальную версию секрета, но хоть как-то работать. Либо сразу падать. Тема мониторинга тоже не раскрыта. Тот же инжектор - ну, звучит круто, пока ты действительно не считаешь расходы на сайдкары и не думаешь, что произойдет, когда он завалится по любой причине. А это обязательно случится. Лишиться радости запуска подов в кластере? В статье подсвечен очень верный тезис - надо делать так, чтобы доступность системы не страдала. Не безопасность любой ценой, а взвешенный разумный компромисс. Но пока у меня складывается ощущение, что эти ИБ штуки скорее мешают, чем помогают и тем более создают скорее иллюзию ложной безопасности. Ну, что толку от того, что секреты спрятаны, если можно утащить сервисный токен с доступом к апи кластера, а дальше все понятно? Ну, и, конечно, вольт может прямо сиять и сверкать - в случае, например, паролек одноразок (динамические секреты), но будем честны - сколько пользователей вольта реально их использует, а не надувает щеки? Какой-то прям resume driven adoption технологий вовсю, а не практическая необходимость.

  • Для монтирования секретов в файловую систему pod используется Pod Security Policies. Он был объявлен как deprecated в Kubernetes v1.21, и окончательно удален в 1.25.

это требует расшифровки, потому что я честно не очень понимаю, как связаны монтирование секретов и PSP.

Любимая тема про поваляшки волта. Я например не очень улавливаю, в чем разница в поваляшках, когда

  1. CSI не может подключить диск и приложение не стартует

  2. Секрет из волта не может извлечься

  3. Кубконтроллер лежит и не создаёт поды

  4. Кубапи лежит и кубконтроллер не знает, что нужно создавать поды

  5. Etcd лежит и непонятно, апиха не работает, поды не создаются

  6. Ингресс лежит, и внешний трафик никуда не роутится

  7. CNI лежит и кубосервисы не работают

  8. Кубднс лежит сервисы не резолвятся

Почему волт лежит какой-то по особенному, не как kubeapi или etcd? Etcd вообще максимально похожий на волт с точки зрения HA - работает только один узел.

Если мы говорим про неправильную конфигурацию vault, так давайте тогда делать неправильную конфигурацию etcd. Что? Не конфигурите etcd по 5 раз на дню? А волт конфигурите? А почему?

Если мы говорим, что волт это ещё одна дополнительная точка отказа, то тут соглашусь. Но тогда давайте будем последовательны в наших опасениях и не будем ходить в сервисы по именам (вдруг днс лежит), не подключать диски (вдруг csi лежит), и хранить конфигурации в oci образе (вдруг кубапи лежит и конфигмапу не забрать). И лучше создавать статик поды через файлы, а то вдруг заклинит API и поды из деплоймента не создадутся. Это максимально надёжно.

Кстати, у инжектора есть режим "не смог извлечь секрет - все равно запусти под". Довольно спорный вариант, но закрывает вопрос "пусть приложение хоть как-то запустится без секрета и может быть оно будет работать"

Ну и про /proc/pid/environment Так запретите доступ к этому интерфейсу ОС. Это же не настоящие файлы. Придется правда ядро немного патчнуть, но что нас остановит?

Любимая тема про поваляшки волта. Я например не очень улавливаю, в чем разница в поваляшках, когда

а если все таки подумать, а не передергивать ?

Почему волт лежит какой-то по особенному, не как kubeapi или etcd? Etcd вообще максимально похожий на волт с точки зрения HA - работает только один узел.

Как минимум тем, что отказ етсд не ведет к немедленной недоступности приложений, хоть и критично. А еще тем, что етсд проще в разы. И, конечно, разработчики кубера подумали десять раз, когда проектировали систему. Отказ одной части не блокирует работы остальных - кроме отказа етсд/всех апи серверов. А волт - монолит, который еще и бекапить надо. Развивать тему можно долго. Но разница есть.

Если мы говорим, что волт это ещё одна дополнительная точка отказа, то тут соглашусь

Скучное передергивание без позитивного заряда (что делать-то?)

Ну и про /proc/pid/environment Так запретите доступ к этому интерфейсу ОС. Это же не настоящие файлы. Придется правда ядро немного патчнуть, но что нас остановит?

Еще скучнее…

Если не передёргивать, то никакого веселья. Я думаю, мы тут все немного передёргиваем, чтобы не было скучнее, а было веселее.

А по сути:

отказ етсд не ведет к немедленной недоступности приложений

Все верно. И отказ волта тоже не ведёт

Отказ одной части не блокирует работы остальных

Отказ волта не блокирует работы csi cni dns kubeapi

который еще и бекапить надо

Это же не проблема. Так или иначе все бэкапить надо, в каком-то виде. Ну кроме наверное аппенд-онли блокчейна, который одновременно неизменяемый и распределенный. Например etcd тоже надо бэкапить. Если не хочешь собирать исчезнувший по какой-то причине кластер из сотен и тысяч репозиториев, а хочешь собрать (хотя бы бОльшую часть) из одного места.

а если все таки подумать

Я не считаю что волт сложный и ненадежный, и это повод от него отказаться, или опасаться использовать. С моей точки зрения волт и etcd - идентичныес точки зрения HA по архитектуре штуки. И может быть даже лучше (если вспомнить энтерпрайзные фичи вроде perfomance replica / dr replica). Только в волте больше возможностей по управлению доступом к ключам, больше способов аутентификации , и шифрованная хранила по умолчанию. По производительности конечно волт в сравнении с etcd проигрывает, но это и понятно - там на порядок больше логики накручено по валилации запроса. Но 10к rps на чтение - вполне держит. И для секретов этого как правило более чем достаточно.

В конце концов, если мы верим, что apiserver + etcd - это надёжная связка, то замените apiserver на vault, и получится такая же надёжная vault + etcd. Просто с другим функционалом. Если кому-то этот функционал не нужен, ну чтож, так бывает. Это как пользоваться postgresql и говорить, что kafka сложная и ещё она ломается, поэтому никаких кафок в проекте быть не должно, и для можно/нужно использовать надёжный проверенный Postgres, он простой и не ломается (хаха, нет)

Например etcd тоже надо бэкапить. Если не хочешь собирать исчезнувший по какой-то причине кластер из сотен и тысяч репозиториев, а хочешь собрать (хотя бы бОльшую часть) из одного места.

Это омерзительная идея. Бекап етсд не решает ничего, вот прям решительно. Зато есть проблемы бекапов всех распределенных систем. Я помню как мы на сссссерьезных щах на конференции редхат с представителями компаний вроде veeam обсуждали реальную необходимость бекапов Кафки, эластика и прочего. Ну, да, возможность восстановиться необходима, но она далеко не всегда реализуется именно тупым бекапом. Скажем, для Кафки вероятнее всего будет продуктивнее использование mirrormaker, для базы типа постгреса - механизма архивации WAL’ов и прочее. Касательно етсд - почему я не верю, потому что

  1. Надежнее использовать GitOps подход, когда ты можешь налить кластер с нуля и получить рабочую систему (ну, мож кроме персистентных данных)

  2. В таких решительно динамических системах как кубернетес, состояние етсд протухает буквально за минуту. Те же pvc. Заказали, оно подвязалось в етсд. Если восстановились - у нас появятся вольюмы, которые ничейные (не в кластере, а в облаке). Удачи разбираться. Или тот же серт менеджер - сертификаты получил, в етсд положил. А пять минут назад их там не было. Все это требует рационального подхода и точно не создания дополнительной ненужной работы.

Я практически уверен, что тезис

В конце концов, если мы верим, что apiserver + etcd - это надёжная связка, то замените apiserver на vault, и получится такая же надёжная vault + etcd

Не выдерживает критики. Хотя бы размер кодовой базы и функционал. Если в апи сервере там условно тупо клиент етсд + пара доп валидаций, кэш, то в вольт в полный рост куча разных модулей, алгоритмов шифрования и прочего.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
www.mts.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия