Vault Agent Templates позволит нам получать информацию об изменениях на сервере хранения секретов и своевременно менять информацию на конечном узле. Например, мы можем автоматизировать изменение секрета для нашего проекта в исходных файлах или поменять пароль для входа на сервер.
Предполагается, что у нас уже настроен сервер Vault. В противном случае, смотрим инструкцию Установка, настройка и работа с Hashicorp Vault .
Настройка сервера Vault
Установка и запуск агента Vault
Настройка работы агента как сервиса
Скорость обновления данных с Vault
Выполнение команд с помощью агента Vault
Настройка на стороне сервера
Настройка агента
Проверка выполнения команды
Настройка Vault Server
На стороне сервера мы создадим тестовый секрет (ключ-значение), политику доступа к данному секрету и роль, которая будет привязана к созданной политике. Рассмотрим процесс по шагам.
1. Разрешаем механизм kv (key-value):
vault secrets enable -version=2 -path=secret/ kv
В данном примере мы создали механизм секретов версии 2 — это важно для работы агента. Если у нас уже создан механизм версии 1, то необходимо разрешить версионность командой:
vault kv enable-versioning secret/
* где secret/ — путь, по которому механизм хранит секреты.
Создаем секрет:
vault kv put secret/applications/myapp/db login=db_user password=db_password
* в данном примере мы создали 2 записи по пути secret/applications/myapp/db — login со значением db_user и password с db_password .
Посмотреть добавленные строки можно командой:
vault kv get secret/applications/myapp/db
2. Создаем политику доступа к секрету:
vault policy write pl-agent-app-test — << EOF
path «secret/data/applications/myapp/*» {
capabilities = [«read»]
}
path «secret/metadata/applications/myapp/*» {
capabilities = [«list»]
}
EOF
* в данном примере мы разрешаем чтение всех элементов внутри secret/applications/myapp .
3. Создаем роль:
vault auth enable approle
vault write -f auth/approle/role/agent-app-test policies=»pl-agent-app-test»
* первая команда разрешает механизм auth по пути auth/approle .
** обратите внимание, что мы привязали нашу роль к ранее созданной политике pl-agent-app-test .
Смотрим идентификатор роли:
vault read auth/approle/role/agent-app-test/role-id
Пример ответа:
Key Value
— ——
role_id ffe4397a-f660-e513-f007-c45c0353badf
Сохраняем role_id — он нам нужен для настройки агента.
Создаем секрет secret-id:
vault write -f auth/approle/role/agent-app-test/secret-id
Мы должны увидеть что-то на подобие:
Key Value
— ——
secret_id 91318b1c-de35-546a-9c5a-2d434b6365aa
secret_id_accessor 0f52e4fd-285e-f23b-3174-c5c81979ee6b
secret_id_ttl 0s
Сохраняем secret_id — он нам нужен для настройки агента.
Установка и запуск Vault Agent
Для начала, на конечном узле, где должен меняться секрет, установим Vault и настроим его запуск в качестве агента.
Нам нужны будут некоторые пакеты.
а) для Ubuntu / Debian:
apt-get install wget unzip
б) для CentOS / Red Hat:
yum install wget unzip
После переходим на страницу загрузки Vault и в разделе «Release Information» копируем ссылку на бинарник для подходящей операционной системы, например:
* в данном примере мы копируем ссылку на архив под систему Linux x64.
Используя ссылку, загружаем на компьютер архив:
wget https://releases.hashicorp.com/vault/1.7.2/vault_1.7.2_linux_amd64.zip
Распаковываем скачанный архив:
unzip vault_*.zip -d /usr/bin/
* распаковка выполняется в каталог /usr/bin .
Создаем каталог для хранения конфигурации vault:
mkdir -p /etc/vault/templates
Создадим конфигурационный файл:
vi /etc/vault/vault.conf
pid_file = «./pidfile»
vault {
address = «https://10.0.2.5:8200»
}
auto_auth {
method {
type = «approle»
config = {
role_id_file_path = «/etc/vault/roleid»
secret_id_file_path = «/etc/vault/secretid»
remove_secret_id_file_after_reading = false
}
}
sink {
type = «file»
config = {
path = «/tmp/file-foo»
}
}
}
template {
source = «/etc/vault/templates/template.ctmpl»
destination = «/etc/vault/templates/render.txt»
}
* где обращаем внимание на опции:
- vault address — адрес до сервера Vault.
- auto_auth method type — название для механизма аутентификации, которую мы создали при настройке Vault.
- template destination — путь до файла, где будут сохранены результаты обработки шаблона.
Создаем файлы.
а) Ранее полученный идентификатор роли ( role_id ):
vi /etc/vault/roleid
ffe4397a-f660-e513-f007-c45c0353badf
б) Секрет для роли (ранее полученный secret_id):
vi /etc/vault/secretid
91318b1c-de35-546a-9c5a-2d434b6365aa
в) Шаблон:
vi /etc/vault/templates/template.ctmpl
{{ with secret «secret/applications/myapp/db» }}
login: {{ .Data.data.login }}
passwd: {{ .Data.data.password }}
{{ end }}
* где:
- secret/applications/myapp/db — путь, по которому мы сохранили наши секреты.
- . Data.data.login — конструкция для извлечения значения ключа login.
- .Data.data.password — конструкция для извлечения значения ключа password.
Создадим системную переменную, которая скажет агенту не проверять валидность сертификата Vault:
export VAULT_SKIP_VERIFY=true
Запускаем агента:
vault agent -config /etc/vault/vault.conf
На экране мы должны увидеть что-то на подобие:
2021-05-28T15:34:50.594+0300 [INFO] auth.handler: renewed auth token
[INFO] (runner) rendered «/etc/vault/templates/template.ctmpl» => «/etc/vault/templates/render.txt»
Это значит, что агент получил данные и внес их в файл /etc/vault/templates/render.txt согласно шаблону.
Оставляем работать агента и создаем дополнительное подключение к серверу по SSH. Смотрим содержимое файла сформированного файла:
cat /etc/vault/templates/render.txt
Мы должны увидеть:
login: db_user
passwd: db_password
* мы должны увидеть наши логин и пароль, которые мы занесли в Vault.
Теперь переходим к серверу Vault и меняем секрет:
vault kv patch secret/applications/myapp/db password=db_password2
Ждем около 5 минут — агент должен вывести на экран сообщение:
[INFO] (runner) rendered «/etc/vault/templates/template.ctmpl» => «/etc/vault/templates/render.txt»
А содержимое файла /etc/vault/templates/render.txt должно измениться. Агент работает. Идем дальше.
Автоматический запуск
Настроим запуск нашего агента в качестве сервиса.
Открываем на редактирование конфигурационный файл для агента:
vi /etc/vault/vault.conf
Комментируем строку:
#pid_file = «./pidfile»
…
* для сервиса мы создадим свой путь до pid-файла.
Создаем новый юнит в systemd:
vi /usr/lib/systemd/system/vault-agent.service
[Unit]
Description=»HashiCorp Vault Agent — A tool for managing secrets»
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault/vault.conf
[Service]
Environment=»VAULT_SKIP_VERIFY=true»
RuntimeDirectory=vault
PIDFile=/var/run/vault/vault.pid
ExecStart=/usr/bin/vault agent -config=/etc/vault/vault.conf
ExecReload=/bin/kill —signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
StartLimitIntervalSec=60
StartLimitBurst=3
Restart=on-failure
[Install]
WantedBy=multi-user.target
Перечитываем конфигурацию systemd:
systemctl daemon-reload
Стартуем сервис:
systemctl start vault-agent
Проверяем, что он работает:
systemctl status vault-agent
Разрешаем его автозапуск:
systemctl enable vault-agent
Попробуем проверить, что наш агент работает. На сервере Vault меняем секрет:
vault kv patch secret/applications/myapp/db password=db_password3
Примерно, через 5 минут, проверяем:
cat /etc/vault/templates/render.txt
Данные должны обновиться.
Скорость получения данных из Vault
По умолчанию, интервал получения новых данных из Vault равен 5-и минутам. Как правило, это очень много и стоит его сократить. В зависимости от версии Vault, это делается по разному. Рассмотрим оба варианта.
1. Версия ниже 1.8
Открываем файл для нашего юнита vault-agent и приводим его к следующему виду:
vi /usr/lib/systemd/system/vault-agent.service
[Unit]
Description=»HashiCorp Vault Agent — A tool for managing secrets»
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault/vault.conf
[Service]
Environment=»VAULT_SKIP_VERIFY=true»
RuntimeDirectory=vault
PIDFile=/var/run/vault/vault.pid
ExecStart=/usr/bin/vault agent -config=/etc/vault/vault.conf
ExecReload=/bin/kill —signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
StartLimitIntervalSec=60
StartLimitBurst=3
Restart= always
WatchdogSec=30
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target
* желтым отмечено то, что необходимо изменить. В данном примере мы говорим нашему процессу перезапускаться каждые 30 секунд.
Перечитываем конфигурацию systemd:
systemctl daemon-reload
Перезапускаем сервис:
systemctl restart vault-agent
2. Версия 1.8 и выше
В более всежих версиях процесс контролируется, намного, проще.
Открываем конфигурационный файл:
vi /etc/vault/vault.conf
Дописываем в корень конфигурации:
…
template_config {
static_secret_render_interval = 30
}
* каждые 30 секунд.
Перезапускаем сервис:
systemctl restart vault-agent
Выполнение команд средствами шаблона
Давайте теперь рассмотрим, как можно выполнить команду при изменении данных в Vault. В нашем примере, мы будем менять пароль для системной учетной записи. Нам предстоит внести настройки на стороне сервера Vault, а также создать скрипт из шаблона, после чего, запустить его.
Настройка Vault Server
На стороне сервера нам нужно создать секрет. Для этого выполняем команду:
vault kv put secret/servers/myserver/ssh login=test_user password=password_1
Смотрим содержимое:
vault kv get secret/servers/myserver/ssh
Расширим права ранее созданной нами политике:
vault policy write pl-agent-app-test — << EOF
path «secret/data/applications/myapp/*» {
capabilities = [«read»]
}
path «secret/metadata/applications/myapp/*» {
capabilities = [«list»]
}
path «secret/data/servers/myserver/*» {
capabilities = [«read»]
}
path «secret/metadata/servers/myserver/*» {
capabilities = [«list»]
}
EOF
* разрешаем чтение секретов по пути secret/servers/myserver и secret/metadata/servers/myserver .
Мы готовы продолжить. Переходим на агента.
Настройка агента
Создадим в системе тестового пользователя, для которого будем проверять смену пароля:
useradd test_user
Откроем на редактирование наш конфигурационный файл:
vi /etc/vault/vault.conf
Добавим в конец:
…
template {
create_dest_dirs = true
source = «/etc/vault/templates/passwd.ctmpl»
destination = «/scripts/passwd.sh»
command = «/bin/bash /scripts/passwd.sh»
}
* где:
- create_dest_dirs — создать автоматически каталог destination, если его нет.
- source — путь до исходного шаблон-файла, на основе которого будет создаваться файл destination.
- destination — путь до конечного файла, который будет сформирован на основе source.
- command — команда, которая должна быть выполнена, если изменился destination.
Откроем файл шаблона:
vi /etc/vault/templates/passwd.ctmpl
{{ with secret «secret/servers/myserver/ssh» }}
echo «{{ .Data.data.password }}» | passwd —stdin {{ .Data.data.login }}
{{ end }}
Перезапустим агента:
systemctl restart vault-agent
Проверка
Теперь на стороне сервера попробуем поменять пароль для учетной записи, которая хранится в Vault:
vault kv put secret/servers/myserver/ssh login=test_user password=password_2
На клиенте в логе мы должны увидеть строку:
[INFO] (runner) rendered «/etc/vault/templates/passwd.ctmpl» => «/scripts/passwd.sh»
…
Changing password for user test_user.
passwd: all authentication tokens updated successfully.
Можно попробовать зайти под учетной записью test_user с паролем password_2 .