Настройка Vault Agent Templates
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.