Как стать автором
Обновить
Флант
Специалисты по DevOps и Kubernetes

Новые возможности менеджера секретов Deckhouse Stronghold: пространства имён, резервные копии и репликация данных

Уровень сложностиСредний
Время на прочтение11 мин
Количество просмотров694

Уже больше двух лет мы развиваем Deckhouse Stronghold — решение для безопасного управления жизненным циклом секретов. С начала 2025 года мы реализовали в продукте привычный пользователям HashiCorp Vault функционал: пространства имён, автоматические бэкапы данных и репликацию для хранилищ KV1/KV2. 

После ухода HashiCorp с российского рынка многие компании стоят перед выбором: переехать на Community-редакцию Vault и дорабатывать её под свои потребности или купить готовый продукт, где многие фичи доступны «из коробки» и есть поддержка от разработчиков. В статье мы сравним, как похожие возможности реализованы в Vault CE (а иногда и EE) и Deckhouse Stronghold, плюс поделимся ближайшими планами по развитию своего продукта.

Содержание

Пространства имён

Как можно сделать в HashiCorp Vault CE

В Vault можно очень детализировано выдавать доступы к секретам: по имени и по типу операции (чтение, создание, изменение, удаление, листинг). Но управлять политиками или пользователями и ролями может только администратор. 

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

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

Решение в примере с отделами А и В может быть простым — для каждого отдела создаётся свой экземпляр или кластер Vault и руководителю отдела выдаются в нём административные права. Однако при кажущейся изящности подхода возникают и свои проблемы. И они не связаны с оркестрацией большого количества экземпляров Vault — с этим может помочь Kubernetes. Зато вам придётся безопасно хранить recovery-ключи для каждого экземпляра Vault (или unseal-ключи, если используется Shamir's unseal), делать резервные копии каждого экземпляра и управлять безопасностью каждого экземпляра отдельно. А если на каком-то этапе вы захотите создать роль, которая имеет доступ к секретам обоих отделов, это будет невозможно, поскольку физические экземпляры Vault — разные. 

Другим решением проблемы может быть вынос управления конфигурацией в CI-пайплайны, когда политиками и ролями управляют через коммиты в GitLab или GitHub. Но это решение половинчатое. Хотя токен для управления ролями и не находится у конкретного человека, доступ к управлению ролями и политиками в Vault сможет получить тот, кто имеет доступ либо к Git-репозиторию, либо к раннерам. 

Ещё один возможный способ — использовать менеджер конфигурации через операторы Vault в Kubernetes, например bank-vaults operator. Но с точки зрения безопасности этот вариант тоже спорный, ведь доступ к секретам может получить администратор Kubernetes-кластера, изменив конфигурацию, к которой у него может быть доступ.

В Enterprise Vault эту проблему решают с помощью пространств имён, или namespaces. При этом в каждом пространстве имён может быть свой локальный администратор.

Как сделано в Stronghold

Очевидно, что как только возникает необходимость делегировать права на выдачу прав (а это происходит в командах от 10 человек), функционал пространств имён просто незаменим. И недавно мы реализовали его в Stronghold. Теперь наши пользователи могут создавать дочерние рабочие пространства и выдавать права на управление ими, при этом поддерживаются вложенные рабочие пространства. Новый функционал максимально совместим с Vault Enterprise по возможностям и методам API, так что если вы использовали Enterprise-решение от HashiCorp, особой разницы не ощутите.

Вот какие возможности пространства имён дают нашим пользователям:

  • Использование одной инсталляции Stronghold для работы нескольких изолированных и независимых сред.

  • Изоляция секретов в пространствах имён одного тенанта, недоступных для других тенантов.

  • Настройка политик контроля доступа, при которых администратор каждого тенанта имеет определённые права, независимые от администраторов других тенантов.

Представим такую цепочку рабочих пространств: ns2 является дочерним рабочим пространством ns1, а ns3 является дочерним к ns2. При этом в каждом пространстве имён — свои политики и методы аутентификации.

Управление политиками, методами аутентификации и identity внутри каждого рабочего пространства происходит точно так же, как в каждом отдельно взятом экземпляре Vault CE. Но при этом появляется возможность управлять доступом к дочерним рабочим пространствам. 

Давайте рассмотрим на примерах из схемы выше:

  • Политика А даёт доступ к secret1, созданному внутри ns1, и не даёт никаких доступов к ns2 и ns3.

  • Политика B позволяет пользователю из ns1 получить полный доступ к ns2 и всем его дочерним пространствам имён, то есть в том числе и к ns3.

  • Политика С позволяет пользователю из ns1 читать secret3, созданный в ns2, при этом не давая никакого доступа к ns1 и ns3.

  • Политика D для пользователей из ns2 даёт полный доступ как к пространству имён ns2, так и к дочернему ns3.

  • Политика E для пользователей из ns2 даёт права читать и изменять secret3, созданный в ns2.

  • Политика F действует только на пользователей ns3 и даёт им возможность взаимодействовать с secret3 пространства имён ns3.

Резервное копирование данных

Как можно сделать в HashiCorp Vault CE

Для пользователя Vault CE с интегрированным хранилищем Raft очевидным и относительно несложным вариантом настройки автоматического создания снапшота данных может быть классическая комбинация cronjob с bash script. В самой основе создания снапшота пользователем лежит команда vault operator raft snapshot. 

Стоит обязательно прочитать рекомендации самой HashiСorp о том, как бэкапить Vault. В большинстве случаев для выполнения бэкапа Vault нужно выполнить резервное копирование данных из бэкенда хранения. При этом, для некоторых бэкендов хранения для создания консистентной резервной копии может потребоваться остановка Vault и offline-backup. Здесь нужно руководствоваться требованиями и собственными пожеланиями к архитектуре системы. Кстати, у нас в блоге есть статья о том, как вообще бэкапить Vault.

Если говорить про бэкап с помощью raft snapshot, то для начала вам понадобится токен с политикой read на /sys/storage/raft/snapshot. Соответственно, надо подумать, где вы будете хранить этот токен, будете ли его перевыпускать или он будет статичным. Ещё нужно будет решить вопрос с метриками и мониторингом: например, может понадобиться проверка на нулевой размер бэкапа после выполнения команды или алертинг на код выполнения команды бэкапа, который не соответствует ожидаемому.

Кроме того, снапшот стоит сохранять с понятным названием и временной меткой, ведь вам вряд ли хватит только одного снапшота. Вероятнее всего, вы реализуете какой-то стандартный Grandfather-Father-Son (GFS) алгоритм хранения.

Ну и хранить снапшот там, где запущен Vault, не имеет большого смысла. Наверное стоит перемещать эти файлы куда-то в имеющееся распределённое хранилище, например S3-совместимое. Для этого опять понадобится подумать над несколькими вещами: 

  • Мониторинг — как убедиться в том, что снапшот скопирован?

  • Где хранить ключи к хранилищу?

  • Как удалять старые снапшоты?

Как сделано в Stronghold

Мы всегда используем Integrated Raft Storage в качестве бэкенда хранения, поэтому описанный выше вариант с raft snapshot работает и в Stronghold. Помимо этого в Stronghold реализовано автоматическое создание резервных копий по настроенному расписанию, которое администратор задаёт через командную консоль, API или UI. Данные при этом можно сохранять как в файлы, так и в S3-совместимое объектное хранилище. 

Аналогичный функционал есть в HashiСorp Vault EE, и мы постарались использовать те же методы API для настройки. Это даёт возможность пользователями Stronghold использовать уже работающий Terraform или готовые автоматизации, если они были написаны при работе с Enterprise-версией Vault. Единственное исключение — два storage type, которые не реализованы в Stronghold: google-gcs и azure-blob

Чтобы делать бэкапы, например, раз в один час и сохранять их за один день в надёжном S3 внутри нашего облака с кастомным TLS-сертификатом, нужно выполнить команду:

stronghold write sys/storage/raft/snapshot-auto/config/my_s3_hourly \
  interval=1h path_prefix=backups file_prefix=hourly retain=24 \
  aws_storage_type=aws-s3 aws_s3_bucket=vedro aws_s3_region=ru-1 \
  aws_s3_endpoint=s3.ru-1.makes3.greatagain.ru \
  aws_access_key_id=very_secret_id \
  aws_secret_access_key=very_secret_key \
  aws_s3_ca_certificate=@/opt/stronghold/tls/my_s3_ca.crt

Кстати, тут мы тоже немного расширили функционал Vault EE. Ребята из HashiСorp, похоже, считают, что у S3 не может быть кастомных сертификатов, и максимум, что можно сделать для работы с S3 с внутренним Certificate Authority, — это использовать ключ aws_s3_disable_tls. В Stronghold же можно указать свой CA.

Функционал бэкапов даёт возможность посмотреть статус каждого конкретного инстанса расписания:

stronghold read sys/storage/raft/snapshot-auto/status/my_s3_hourly

…или список всех установленных расписаний:

stronghold list sys/storage/raft/snapshot-auto/config

Управлять бэкапами из консоли захочется не всем, поэтому в части UI мы тоже пошли чуть дальше Vault EE и добавили возможность управления расписанием бэкапов и мониторинга их статуса в веб-интерфейсе Stronghold:

Что даёт нашим пользователям автоматическое резервное копирования данных:

  • Отсутствие необходимости писать отдельные скрипты для создания снапшотов.

  • Сохранение файлов конфигурации внутри резервных копий при переносе настроек.

  • Возможность восстановления из резервной копии путём загрузки снапшота или развёртывания новой инфраструктуры и восстановления снапшота в случае полного выхода из строя.

Репликация хранилища секретов типа KV1/KV2

Как можно сделать в HashiCorp Vault CE

Обычная ситуация: у вас есть приложения, запущенные в двух дата-центрах, и вы хотите, чтобы приложения работали с хранилищем секретов в своём дата-центре, и не хотите зависеть от наличия связи между ДЦ. Но секретами хотелось бы управлять из одного места. А значит, секреты нужно как-то синхронизировать.

Для копирования секретов между инстансами Vault можно использовать Medusa — CLI-инструмент для безопасного экспорта и импорта данных. Почему безопасного? Данные можно не только экспортировать и импортировать в текстовом виде, а существует возможность шифрования передаваемых данных собственными ключами с последующей расшифровкой перед импортом.

Давайте представим, что нам надо сделать репликацию по расписанию. К примеру, можно использовать вот такой CronJob:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: vault-sync
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: medusa
            image: medusa-cli:latest
            command: ["/bin/sh", "-c"]
            args:
              - medusa export secret/ --encrypt=true --public-key=public-key.pem \
--address="http://vault-source:8200" --output=encrypted-data.yaml &&
                kubectl cp encrypted-data.yaml target-pod:/data &&
                medusa import secret/ encrypted-data.yaml --decrypt=true \
--private-key=private-key.pem --address="http://vault-destination:8200"
          restartPolicy: OnFailure

Чтобы наш файл с экспортированными данными было безопасно хранить и передавать, его желательно зашифровать. Для шифрования понадобятся сгенерированные RSA-ключи:

openssl genrsa -out private-key.pem 4096
openssl rsa -in private-key.pem -pubout -out public-key.pem

Приватный ключ нужно сохранить в виде секрета в целевой кластер, а публичный — в исходный кластер:

# medusa-secret.yaml в исходном кластере.
apiVersion: v1
kind: Secret
metadata:
  name: medusa-config
data:
  VAULT_TOKEN: <base64-закодированный-токен>
  public-key.pem: <base64-закодированный-публичный-ключ>

Результат можно сохранять в Persistent Volume или S3-совместимое хранилище, например MinIO.

При этом придётся обязательно думать о безопасности. Надо будет использовать TLS для подключения к Vault, соответственно нужно и поддерживать эти сертификаты. Понадобится ограничивать права ServiceAccount только необходимыми секретами, так что, скорее всего, потребуется какой-то репо с IaC-описанием этих политик. А ещё нужно будет регулярно обновлять RSA-ключи для шифрования/дешифрования, при этом ответ на вопрос о том, где именно хранить эти самые секретные RSA-ключи, открыт.

Одной из особенностей такого подхода к «репликации» данных будет то, что в случае синхронизации хранилища типа kv-v2 в целевом кластере при каждой синхронизации будут создаваться новые версии секретов. Фактически medusa import выполняет операцию write и каждый раз создаёт новую версию секрета, даже если он не изменился. В итоге вы получаете совсем не идентичные данные в исходном и целевом кластерах: совпадают только последние версии секрета.

С одной стороны, использование Medusa или аналогов даёт гибкость в настройке и прозрачность решения. С другой — поддержка множества репликаций в разных местах и мониторинг безопасности и самих репликация являются очень нетривиальными задачами. 

Как сделано в Stronghold

Первым этапом большой работы по расширению функционала Stronghold мы реализовали возможность репликации хранилищ секретов типа KV1/KV2. Зачем нам это понадобилось?

  1. Мы хотели, чтобы доступ к реплицируемым секретам был только у самого защищённого хранилища.

  2. Нас не устраивало «дублирование» версий KV, а API Vault просто не позволяет создать секрет желаемой версии.

  3. В нашей практике часто встречались конфигурации, когда хотелось бы реплицировать только часть секретов, и репликация KV через API казалась неплохим выходом.

  4. Клиенты часто задавали вопрос: «Если сделать кластер из 5 реплик Vault, то получим ли мы увеличение производительности в 5 раз?». Ответ на него — нет. А репликация данных в отдельные кластеры — один из способов увеличить производительность чтения.

  5. Ну и такой подход прекрасно работает для миграции данных из Vault CE в Stronghold.

Репликация KV построена на архитектуре master-slave с применением pull-модели получения данных, где подчинённые slave-узлы сами опрашивают master-узел. Подробности о технической реализации этой фичи мы уже рассказывали в отдельной статье

Верхнеуровневая архитектурная схема механизма репликации между распределёнными системами хранения секретов
Верхнеуровневая архитектурная схема механизма репликации между распределёнными системами хранения секретов

Вот что получают от репликации хранилищ секретов типа KV1/KV2 пользователи Stronghold:

  • Более безопасный и удобный доступ к секретам в больших компаниях с геораспределённой структурой.

  • Параметры репликации задаются дополнительными настройками при монтировании нового KV-хранилища. После завершения настройки локальное хранилище автоматически переводится в режим «только чтение», что гарантирует проведение всех изменений только в исходном хранилище.

  • Секреты в исходном и целевом хранилищах совпадают с точностью до версии, реплицируются в том числе и deleted-статусы промежуточных версий.

  • Если планируется высокая нагрузка на чтение из KV, то репликацию можно использовать для создания Performance-реплик KV.

Ближайшие планы по развитию Stronghold

В течение года мы планируем:

  • пройти сертификацию ФСТЭК России;

  • реализовать в Stronghold поддержку криптоалгоритмов ГОСТ;

  • выпустить версии с поддержкой производительной репликации и репликации для аварийного восстановления. 

Сертификация ФСТЭК России. Нужна, чтобы компании могли использовать наш менеджер секретов в контурах с дополнительными требованиями к безопасности. Мы уже запустили процесс сертификации на соответствие Deckhouse Stronghold требованиям технический условий и приказа ФСТЭК России от 2 июня 2020 г. № 76 по 4-му уровню доверия. Кстати, Stronghold уже вошёл в состав новой сертифицированной ФСТЭК России версии Deckhouse Kubernetes Platform CSE 1.67 как функциональный модуль, реализующий базовые функции хранилища секретов.

Подробнее о том, зачем нужны лицензии ФСТЭК России, мы уже рассказывали в своём блоге

Поддержка криптоалгоритмов ГОСТ. Как и в случае с сертифицированными ФСТЭК России продуктами, реализация этого функционала позволит использовать Stronghold компаниям, которым необходимо соответствовать более высоким требованиям по безопасности, в частности российским криптографическим стандартам ГОСТ 34.12-2018. В этом году мы добавим поддержку стандартов в Stronghold:

  • В продукте будет использоваться сертифицированная библиотека, которая предоставляет возможность шифрования с использованием алгоритмов «Магма» и «Кузнечик».

  • Исполняемый файл Stronghold будет использовать статическую или динамическую линковку библиотеки с импортом C-функций внутрь кода на Golang.

Производительная репликация (Performance Replication) поможет увеличить скорость чтения.

Репликация для аварийного восстановления (Disaster Recovery Replication) позволит повысить надёжность систем с помощью горизонтального масштабирования.

Performance-реплики нужны для создания дополнительных экземпляров Stronghold. Такую реплику можно использовать для разных сценариев:  

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

  • Устойчивость к сбоям: повышает общую устойчивость системы за счёт того, что при выходе из строя основного экземпляра система продолжает функционировать с минимальными задержками.

  • Локализация данных: это полезно в географически распределённых системах, где можно развернуть реплику (или несколько реплик) ближе к месту нахождения пользователей, чтобы уменьшить задержки.

Стоит сказать, что performance-реплика поддерживает только операции чтения. Для записей данные должны перенаправляться к основному кластеру, который управляет всей информацией.

Disaster recovery-реплика синхронизирует данные из основного кластера, но не обрабатывает пользовательские запросы, пока её не активируют. Главное её назначение — обеспечение устойчивости системы к критическим сбоям и катастрофам. Обычно реплику для аварийного восстановления размещают в другой локации или отдельном дата-центре: так она функционирует независимо от основного кластера, что защищает её от локализованных сбоев, которые могут повлиять на основную инфраструктуру.

P. S. 

Читайте также в нашем блоге:

  1. Репликация KV1/KV2 в Deckhouse Stronghold: как добиться идентичности секретов

  2. Безопасная миграция данных из HashiCorp Vault одной командой

  3. Бэкапы для HashiCorp Vault с разными бэкендами

Теги:
Хабы:
+18
Комментарии4

Публикации

Информация

Сайт
flant.ru
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия
Представитель
Александр Лукьянов