Hashicorp Vault — это давно известное и зарекомендовавшее себя решения с открытым исходным кодом, который обеспечивает безопасное хранение и доступ к различным секретам (паролям, сертификатам, токенам). В данной статья я опишу базовую установку, настройку и работу с Vault на Ubuntu 22.04
Исходные данные: ОС Ubuntu 22.04
Задача: Установить и произвести базовую настройку Hashicorp Vault, сделать пару секретов и простую политику и токен доступа.
1. Установка дополнительных пакетов:
apt-get install -y wget net-tools apt-transport-https
2. Проверка синхронизации времени и часового пояса:
Для корректной работы Vault очень желательно, чтобы на вашем сервере было корректное время и часовой пояс. Поэтому Вы должны проверить осуществляется ли синхронизация времени на сервере с внешними NTP серверами или с каким-то внутренним (корпоративным), для этого можно воспользоваться утилитой timedatectl, которая выдаст примерно такие данные:
Local time: Thu 2023-01-26 14:41:05 UTC Universal time: Thu 2023-01-26 14:41:05 UTC RTC time: Thu 2023-01-26 14:41:05 Time zone: Etc/UTC (UTC, +0000) System clock synchronized: yes NTP service: active RTC in local TZ: no
Нас интересует строка System clock synchronized = yes — это означает, что часы синхронизированы и Time zone — где будет указан часовой пояс, проверьте чтобы он был тот, что Вам нужен.
Если нужно изменить часовой пояс, то вначале посмотрите список часовых поясов командой:
timedatectl list-timezones
А потом установите нужный:
timedatectl set-timezone Europe/Moscow
3. Проверка настроек firewall:
По умолчанию Vault ожидает входящие соединения на порту 8200, проверьте настройки firewall и разрешите входящие соединения на этот порт.
Способ настройки firewall может быть разный, поэтому я не привожу тут конкретных вариантов.
4. Установка GPG ключа Hashicorp:
Сразу хочу заметить, что в Ubuntu 22.04 утилиты apt-key является depricated и ее использование не рекомендуется, поэтому будем использовать рекомендованные методы установки GPG ключа, хоть они и будут более громозкие:
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor > /tmp/hashicorp.gpg mv /tmp/hashicorp.gpg /etc/apt/trusted.gpg.d/ chown root:root /etc/apt/trusted.gpg.d/hashicorp.gpg chmod ugo+r /etc/apt/trusted.gpg.d/hashicorp.gpg chmod go-w /etc/apt/trusted.gpg.d/hashicorp.gpg echo "deb https://apt.releases.hashicorp.com $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/hashicorp.list
5. Установка Vault из репозитория Hashicorp:
apt-get update apt-get install vault
6. Проверка установленной версии и запуск Vault:
Выполните:
vault --version
В ответ будет выдана версия Vault, например на момент написания статьи:
Vault v1.12.2 (415e1fe3118eebd5df6cb60d13defdc01aa17b03), built 2022-11-23T12:53:46Z
Теперь запустим Vault и добавим его запуск при старте системы:
systemctl enable vault --now
Проверим статус:
# systemctl status vault ● vault.service - "HashiCorp Vault - A tool for managing secrets" Loaded: loaded (/lib/systemd/system/vault.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2023-01-26 14:49:05 UTC; 2s ago Docs: https://www.vaultproject.io/docs/ Main PID: 4096 (vault) Tasks: 7 (limit: 1149) Memory: 88.6M CPU: 232ms CGroup: /system.slice/vault.service └─4096 /usr/bin/vault server -config=/etc/vault.d/vault.hcl Jan 26 14:49:05 myserver vault[4096]: Mlock: supported: true, enabled: true Jan 26 14:49:05 myserver vault[4096]: Recovery Mode: false Jan 26 14:49:05 myserver vault[4096]: Storage: file Jan 26 14:49:05 myserver vault[4096]: Version: Vault v1.12.2, built 2022-11-23T12:53:46Z Jan 26 14:49:05 myserver vault[4096]: Version Sha: 415e1fe3118eebd5df6cb60d13defdc01aa17b03 Jan 26 14:49:05 myserver vault[4096]: ==> Vault server started! Log data will stream in below: Jan 26 14:49:05 myserver vault[4096]: 2023-01-26T14:49:05.332Z [INFO] proxy environment: http_proxy="" https_proxy="" no_proxy="" Jan 26 14:49:05 myserver vault[4096]: 2023-01-26T14:49:05.332Z [WARN] no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible,> Jan 26 14:49:05 myserver vault[4096]: 2023-01-26T14:49:05.580Z [INFO] core: Initializing version history cache for core Jan 26 14:49:05 myserver systemd[1]: Started "HashiCorp Vault - A tool for managing secrets".
Проверим порты:
# netstat -ltupn | grep vault tcp 0 0 0.0.0.0:8200 0.0.0.0:* LISTEN 4096/vault
7. Настройка окружения и инициализация Vault:
Управлять Vault можно 3 способами:
a) Через API по http/https
b) Через консольную CLI утилиту vault, которая по сути обращается к API по http/https
c) Через UI интерфейс (по умолчанию доступен по https, на порту 8200)
Чтобы управлять через CLI нужно прописать правильный адрес в переменной VAULT_ADDR. Но есть один нюанс — т.к. по умолчанию Vault стартует с поддержкой https на порту 8200 с самоподписным сертификатом, то консольная утилита vault не даст Вам подключиться к нему просто так (будет выдана ошибка проверки SSL сертификата). Вам придется получить корректный SSL сертификат например от Let’s Encrypt.
Но из данной ситуации есть два варианта выхода:
a) Это запуск Vault без https на дополнительном порту, например на порту 8201, для этого нужно отредактировать файл конфигурации /etc/vault.d/vault.hcl и прописать там (вернее раскомментировать опции ниже, поменяв порт):
Пример конфига в /etc/vault.d/vault.hcl для запуска листенера по HTTP на порту 8201:
# HTTP listener listener "tcp" { address = "127.0.0.1:8201" tls_disable = 1 }
Вариант неплохой, но немного не безопасный.
b) Добавить опцию для пропуска проверки сертификата — это более приемлемый вариант, т.к. соединение остается шифрованный, но не происходит проверка сертификата.
Для этого добавим в файл /etc/vault.d/vault.env 2 переменные (данный файл он используется для указания переменных окружения службы Vault)
echo "VAULT_API_ADDR=https://127.0.0.1:8200" > /etc/vault.d/vault.env echo "VAULT_API_SKIP_VERIFY=true" >> /etc/vault.d/vault.env
После этого перезапустим Vault:
systemctl restart vault
И снова проверим порты:
# netstat -ltupn | grep vault tcp 0 0 0.0.0.0:8200 0.0.0.0:* LISTEN 5803/vault
Я не стал запускать Vault с небезопасным подключением, а пошел по варианту b)
Теперь установим переменную VAULT_ADDR и VAULT_SKIP_VERIFY для использования CLI утилиты vault:
export VAULT_ADDR=https://127.0.0.1:8200 export VAULT_SKIP_VERIFY=true
После этого можно проверить статус Vault:
vault status
В ответ мы получим:
Key Value --- ----- Seal Type shamir Initialized false Sealed true Total Shares 0 Threshold 0 Unseal Progress 0/0 Unseal Nonce n/a Version 1.12.2 Build Date 2022-11-23T12:53:46Z Storage Type file HA Enabled false
Что интересного есть в этом выводе:
1. Seal Type — это тип печати, по умолчанию используется алгоритм Шамира (EN — Shamir’s Secret Sharing, RU — Схема разделения секрета Шамира, кстате в RSA, вторая буква — это он и есть), суть которого в том, что мастер-ключ разделяется на N частей и для его воссоздания нужны M частей этого ключа. Более подробно об этом можно почитать в оффициальной документации на Vault, а для тех кто хочет углубиться есть неплохая статья с наглядными примерами как работает алгоритм Шамира.
2. Initialized — состояние инициализации, то есть заданы ли те самые составные части ключа для «распечатывания» хранилища секретов. При первоначальной установке мастер-ключ не созданы, хранилище секретов так же не создано, то есть по сути Vault сейчас просто пустышка.
3. Sealed — состояние секретного хранилища, в случае true — значит что хранилище «запечатано» и его нельзя использовать, нужно его «распечатать» или открыть.
4. Unseal Progress — состояние процесса «распечатывания» секретного хранилища, показаны сколько частей (N) мастер-ключа введено из необходимого количества (M).
5. Storage Type — указано file, то есть все секреты будут храниться в зашифрованном виде на файловой системе сервера, путь к хранилищу определен в файле конфигурации /etc/vault.d/vault.hcl. В качестве хранилища так же можно использовать продукт Hashicorp Consul
Теперь нам нужно инициировать Vault и создать мастер-ключ и секретное хранилище, для этого используется команда
vault operator init
Вы так же можете открыть в браузере UI Vault и там будет предложено ввести на сколько частей будет разделен мастер-ключ и сколько частей понадобится для его воссоздания. Vault очень мощный инструмент и позволяет использовать cпециализированные аппаратные решения — HSM модули, а так же облачные KMS.
Мы же будем использовать простое хранилище на основе файлов и зададим нестандартные параметры количества частей мастер-ключа, мы разделим ключ на 3 части и для «распечатывания» хранилища нужны будет любые 2 части ключа, выполним:
vault operator init -key-shares=3 -key-threshold=2
В ответ Вы получите примерно такой вывод:
Unseal Key 1: U8mZuneAIP4OtdGv3xd66qtpct2KnaravSxfHp/wTW6y Unseal Key 2: z+jjsHvMtXb96HnuFK/CNYutV0TQY57RQ+UKeg4m0tgg Unseal Key 3: 4v8A0s4aHJ9cyywmeKTJnTeS2liP3OYY/MQGPz0KGSv1 Initial Root Token: hvs.go2Qmqzg6bN2qrcNw47Bi8zs Vault initialized with 3 key shares and a key threshold of 2. Please securely distribute the key shares printed above. When the Vault is re-sealed, restarted, or stopped, you must supply at least 2 of these keys to unseal it before it can start servicing requests. Vault does not store the generated root key. Without at least 2 keys to reconstruct the root key, Vault will remain permanently sealed! It is possible to generate new unseal keys, provided you have a quorum of existing unseal keys shares. See "vault operator rekey" for more information.
Итак, Vault инициализировался и выдал там 3 ключа (Unseal Key 1,2,3) необходимые для воссоздания мастер-ключа, а так же он нам выдал root-токен который понадобится для входа в Vault и его настройки через API/CLI/WebUI
ВАЖНО! Каждый из трех ключей должен быть отдан одному человеку и никогда не должен храниться вместе с другими ключами! Выбор параметров key-shares и key-threshold должны осуществляться исходя из политики безопасности в Вашей компании, например можно разделить мастер-ключ на 7 частей (key-shares), а для его реконструкции необходимы только 3 части (key-threshold).
Настоятельно рекомендую использовать root-токен только для начальной настройки Vault и создания других (пользовательских) токенов. При компрометации root-токен можно перегенерировать.
Если теперь посмотреть статус Vault то мы увидим немного иную картину:
# vault status Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 3 Threshold 2 Unseal Progress 0/2 Unseal Nonce n/a Version 1.12.2 Build Date 2022-11-23T12:53:46Z Storage Type file HA Enabled false
Теперь мы видим что хранилище секретов Vault инициализировано (Initialized = true) и что Unseal Progress у нас 0/2, что говорит о том, что нужны 2 ключа для «распечатывания» и ни один пока не введен. В строке Threshold мы видим 2 — это как раз тот самый порог для «распечатывания».
«Распечатать» хранилище можно как через CLI так и через Web-UI, так что Вам не придется давать доступ к консоли всем владельцам ключей, все можно сделать через Web-браузер с другого конца планеты.
Начнем «распечатывать» хранилище Vault введя пока 3-й по счету ключ через CLI (на запрос ключа введите например 3-й ключ, Ваш ввод не будет отображен на экране):
# vault operator unseal Unseal Key (will be hidden): Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 3 Threshold 2 Unseal Progress 1/2 Unseal Nonce 596288db-1516-ab7d-3984-e35ea83f09b7 Version 1.12.2 Build Date 2022-11-23T12:53:46Z Storage Type file HA Enabled false
ВАЖНО! Не вводите ключ в качестве аргумента команды vault operator unseal, т.к. он сохраниться в истории bash и это может очень негативно сказаться на безопасности!
НЕ ДЕЛАЙТЕ ТАК!
vault operator unseal 4v8A0s4aHJ9cyywmeKTJnTeS2liP3OYY/MQGPz0KGSv1
После ввода ключа в строке Unseal Progress мы видим 1/2 — то есть введен 1 из необходимых 2-х ключей и Sealed = true, то есть хранилище все еще «запечатано».
Продолжим «распечатывать» хранилище Vault введя 1-й по счету ключ через CLI (на запрос ключа введите например 1-й ключ, Ваш ввод не будет отображен на экране):
# vault operator unseal Unseal Key (will be hidden): Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 3 Threshold 2 Version 1.12.2 Build Date 2022-11-23T12:53:46Z Storage Type file Cluster Name vault-cluster-ec4ac4d3 Cluster ID a8806adb-a4c7-0945-4d4a-f9006ffeea09 HA Enabled false
Теперь после правильного ввода ключа мы видим что Sealed = false, то есть хранилище секретов «распечатано».
Так же появились такие вещи как Cluster Name и Cluster ID
Теперь мы может пройти аутентификацию по root-токену через CLI или Web-UI и начать пользоваться Vault.
8. Базовая настройка и работа через CLI:
Аутентификация по root-токену.
Если root-токен будет введен правильно, то Вы увидите надпись Success! и массу других данных, например политику применяемую для этого токена (policies).
# vault login Token (will be hidden): Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token hvs.go2Qmqzg6bN2qrcNw47Bi8zs token_accessor Hu906xc3qfyj7gZYchGlJ3ww token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]
Чтобы понять под каким токеном мы вошли нужно выполнить:
# vault token lookup Key Value --- ----- accessor Hu906xc3qfyj7gZYchGlJ3ww creation_time 1674756773 creation_ttl 0s display_name root entity_id n/a expire_time <nil> explicit_max_ttl 0s id hvs.go2Qmqzg6bN2qrcNw47Bi8zs meta <nil> num_uses 0 orphan true path auth/token/root policies [root] ttl 0s type service
После инициализации в нашем Vaul подключен только один Secrets Engines (или бэкенд) — это cubbyhole, он работает как уникальное пространство имён для каждого токена. Уничтожение токена удаляет также все данные в его cubbyhole пространстве. Эту важную особенность не стоит забывать если у наших токенов есть установленное время жизни (TTL).
У Vault довольно много разных Secrets Engines прямо из коробки, это например KV, SSH, TOTP, Transit, Database, Consul, RabbitMQ, Nomad, AWS, Azure, Google Cloud и другие.
Давайте подключим еще какое-нибудь Secrets Engines, например KV, версии 2 (версия 2 позволяет поддерживать версионирование данных, тогда как версия 1 этого не позволяла), по пути secrets/:
# vault secrets enable -version=2 -path=secrets kv Success! Enabled the kv secrets engine at: secrets/
Для проверки Вы можете зайти через Web-UI и на странице Secrets Engines увидите подключенный бэкенд.
Теперь добавим новый секрет по пути secrets/database, скажем это будет связка логин=пароль:
# vault kv put -mount=secrets database root=password ==== Secret Path ==== secrets/data/database ======= Metadata ======= Key Value --- ----- created_time 2023-01-26T20:08:09.228855285Z custom_metadata <nil> deletion_time n/a destroyed false version 1
И добавим еще один секрет по пути secrets/web, скажем это будет тоже связка логин=пароль:
# vault kv put -mount=secrets web admin=pa$$w0rd == Secret Path == secrets/data/web ======= Metadata ======= Key Value --- ----- created_time 2023-01-26T20:10:59.347403763Z custom_metadata <nil> deletion_time n/a destroyed false version 1
Проверив через Web-UI мы их легко увидим:
Посмотреть секрет определенной версии можно и через CLI:
# vault kv get -version=1 secrets/database ==== Secret Path ==== secrets/data/database ======= Metadata ======= Key Value --- ----- created_time 2023-01-26T20:08:09.228855285Z custom_metadata <nil> deletion_time n/a destroyed false version 1 ==== Data ==== Key Value --- ----- root password
Теперь давайте создадим простую политику (policy) для этого Secret Engine, которая будет определять доступ по пути secrets/ только на чтение, для этого в файл secrets.hcl запишем:
path "secrets/*" { policy = "read" }
По умолчанию в Vault есть только 2 политики:
# vault policy list default root
Добавим новую:
# vault policy write mysecrets secrets.hcl Success! Uploaded policy: mysecrets
Проверим:
# vault policy list default mysecrets root
Политика на месте, теперь создадим токен и свяжем его с этой политикой:
# vault token create -policy=mysecrets Key Value --- ----- token hvs.CAESIBAoisN_3b6ImeGn5J6wSjdmIkaLdUaL30Ju9S9dlHMyGh4KHGh2cy5aUkplNzZ1TDhBcHBQOGcwTjNlbWhET1g token_accessor fiFMC6kVWa9DS2N1bCp58ff9 token_duration 768h token_renewable true token_policies ["default" "mysecrets"] identity_policies [] policies ["default" "mysecrets"]
Токен создан, теперь по нему можно войти, например через Web-UI.
Обратите внимание, что время жизни токена 768h — это 1 месяц. Мы так же можем указать другое время жизни (например 24 часа) через опцию -period=24h
Посмотреть информацию о токенах можно через его accessors.
Для этого сначала получим список всех accessors командой:
# vault list auth/token/accessors Keys ---- Hu906xc3qfyj7gZYchGlJ3ww fiFMC6kVWa9DS2N1bCp58ff9
А теперь посмотрим сам токен по accessors = fiFMC6kVWa9DS2N1bCp58ff9
# vault token lookup -accessor fiFMC6kVWa9DS2N1bCp58ff9 Key Value --- ----- accessor fiFMC6kVWa9DS2N1bCp58ff9 creation_time 1674764895 creation_ttl 768h display_name token entity_id n/a expire_time 2023-02-27T20:28:15.680386108Z explicit_max_ttl 0s id n/a issue_time 2023-01-26T20:28:15.680398818Z meta <nil> num_uses 0 orphan false path auth/token/create policies [default mysecrets] renewable true ttl 767h21m15s type service
Здесь мы видим детали о ранее созданном токене, включая expire_time, policies, ttl и другие.
На картинке ниже видно, что доступ по токену к содержимому secrets/ только чтение и редактирование не возможно, а так же видна дата истечения срока токена ровно через 1 месяц.
На этом базовая настройка Vault завершена, так же мы освоили создание секретов и простой политики через CLI, до скорых встреч.
Если у Вас возникли вопросы или Вы хотите чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.
Профессионально занимаюсь системным администрированием Linux -серверов и баз данных (MySQL, POstgreSQL) на протяжении последних 24 лет.
Добрый день! Столкнулся с трудностями при установки, как я понял из-за санкций или ещё что… Подскажите можно из пакета и без интернета установить vault? Спасибо.
Зеркало есть здесь — https://hashicorp-releases.yandexcloud.net/. Либо из исходников собрать, но это муторно.
Спасибо, интересная статья.
Подскажите пожалуйста, на сайте хашикорп написано, что это всё платные продукты, а судя по вашей инструкции всё ставится бесплатно. Не пойму ценообразование.
Hashicorp Vault бесплатен, но есть нюансы для облачных провайдеров в связи с переходом на лицензию BSL
Почитайте эту статью — https://habr.com/ru/companies/flant/news/754094/
Если хочется полностью опенсорсный аналог Vault, то обратите внимание на Infisical — https://infisical.com/
Про Infisical я думаю скоро напишу статью, продукт очень интересный.