Настройка Vault Agent Templates

Обновлено Обновлено: Опубликовано Опубликовано:

Vault Agent Templates позволит нам получать информацию об изменениях на сервере хранения секретов и своевременно менять информацию на конечном узле. Например, мы можем автоматизировать изменение секрета для нашего проекта в исходных файлах или поменять пароль для входа на сервер.
Предполагается, что у нас уже настроен сервер Vault. В противном случае, смотрим инструкцию Установка, настройка и работа с Hashicorp 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» копируем ссылку на бинарник для подходящей операционной системы, например:

Копируем ссылку на необходимый бинарник Vault

* в данном примере мы копируем ссылку на архив под систему 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.

# DevOps # Безопасность # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет