Thank you for reading this post, don't forget to subscribe!
В инструкции рассмотрим процесс хранения учетной записи PostgreSQL в хранилище секретов Hashicorp Vault, используя механизм database, с возможностью автоматической смены секрета в СУБД при его смене в Vault. Также мы настроим Vault для создания временных учетных записей в PostgreSQL.
Установка и запуск PostgreSQL
удаленное подключение к PostgreSQL
работа с пользователями в PostgreSQL
Настройка прав доступа к базе с помощью групп
Редактирование пользователя
Назначение особых прав пользователям PostgreSQL
Установка, настройка и работа с Hashicorp Vault
Управление динамическими учетными записями в PostgreSQL через Hashicorp Vault
Установка и запуск PostgreSQL
PostgreSQL 9/10
В зависимости от версии операционной системы, из коробки будет установлена версия 9.2 (CentOS 7) или 10 (CentOS 8).
Просто вводим команду:
yum install postgresql-server
PostgreSQL > 9.2
Для установки более свежей версии PostgreSQL на CentOS необходимо подключить репозиторий:
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-`rpm -E %{rhel}`-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Установка PostgreSQL в CentOS 8 осуществлена через модульные репозитории, что помешает нам — отключаем их командой:
dnf module disable postgresql
И чистим кэш:
dnf clean all
После чего обновляем список пакетов:
yum makecache -y
Устанавливаем postgres:
yum install postgresql11-server
* в данном примере будет установлен postgresql версии 11.
** система проверит репозиторий на наличие нужного пакета и задаст запрос на подтверждение установки программы — отвечаем Y.
Запуск
После установки СУБД необходимо:
- Инициализировать базу. Это делается с помощью утилиты postgresql-setup с ключом initdb.
- Разрешить автозапуск сервиса.
- Стартовать службу.
В зависимости от версии postgresql, эти операции выполняются, немного, по-разному.
PostgreSQL (базовый репозиторий)
Инициализация базы:
postgresql-setup initdb
Запуск сервиса:
systemctl enable postgresql --now
PostgreSQL (другая версия — на примере 11)
Инициализация базы (синтаксис):
/usr/pgsql-<версия>/bin/postgresql-<версия>-setup initdb
Например:
/usr/pgsql-11/bin/postgresql-11-setup initdb
Разрешаем запуск сервиса и стартуем его:
systemctl enable postgresql-11 --now
Тестовое подключение
Задаем пароль для пользователя postgres:
passwd postgres
Заходим в систему под данной учетной записью:
su - postgres
Подключаемся к базе:
psql
Делаем тестовый запрос на получение списка таблиц:
=# \dt *
Выходим из оболочки psql:
=# \q
Отключаемся от системы пользователем postgres:
exit
Настройка завершена. Следующим шагом настраиваем подключение к PostgreSQL и создаем пользователя.
Удаленное подключение к PostgreSQL
По умолчанию, сервер баз данных pgsql разрешает подключение только с локального компьютера. Данная инструкция показывает, как разрешить подключения с удаленных систем
Для начала посмотрим путь расположения конфигурационного файла postgresql.conf:
# su - postgres -c "psql -c 'SHOW config_file;'"
Команда выдаст, примерно, следующее:
-----------------------------------------
/db/pgsql/postgresql.conf
(1 row)
* нас интересует строчка /db/pgsql/postgresql.conf — это путь расположения нужного нам конфигурационного файла.
Теперь открываем на редактирование основной файл конфигурации PostgreSQL:
# vi /db/pgsql/postgresql.conf
* напоминаю, что начало пути /db/pgsql может быть другим. Мы его получили командой ps.
Находим и редактируем следующее:
listen_addresses = '*'
* по умолчанию, параметр закомментирован и настроен на прослушивание запросов только с локального сетевого интерфейса. В данном примере мы разрешили прослушивание запросов на всех IP-адресах (*), но, если требуется более безопасная настройка, можно просто перечислить последние через пробел.
После открываем на редактирование следующий конфигурационный файл:
# vi /db/pgsql/pg_hba.conf
и внизу добавляем следующую строку:
host all all 192.168.0.10/32 password
* в данном примере мы разрешаем удаленные подключения к серверу с компьютера 192.168.0.10. Доступ предоставляется всем учетным записям и всем базам (значение all). При желании, вместо all можно указать конкретные данные для повышения безопасности.
Чтобы изменения вступили в силу, перезапускаем службу postgresql:
# systemctl restart postgresql-9.5
Проверить подключение можно с удаленного компьютера следующей командой:
# psql -h 192.168.0.15 -U usersql
* где 192.168.0.15 — IP-адрес сервера баз данных; usersql — имя учетной записи, от которой идет подключение.
работа с пользователями в PostgreSQL
Часть нижеописанных операций нужно выполнять в командной оболочке PostgreSQL. Она может быть запущена от пользователя postgres — чтобы войти в систему от данного пользователя, вводим:
su - postgres
* если система выдаст ошибку, связанную с нехваткой прав, сначала повышаем привилегии командой sudo su или su.
Теперь запускаем командную оболочку PostgreSQL:
$ psql -Upostgres template1
* в данном примере, вход выполняется от учетной записи postgres к шаблонной базе template1.
Для просмотра всех пользователей СУБД:
=# select * from pg_user;
Создание нового пользователя
Для того, чтобы была возможность подключения к СУБД PostgreSQL от нового пользователя, необходимо создать данного пользователя, назначить ему права, выполнить настройку файла pg_hba.conf.
1. Создание пользователя
а) Добавление новой роли (пользователя) из оболочки SQL:
=# CREATE USER user1 WITH PASSWORD 'myPassword';
* в примере создана роль user1 с паролем myPassword.
б) Добавление новой роли (пользователя) из командной строки Linux:
createuser -P user1
2. Назначение прав на использование базы данных
Даем права на базу командой:
=# GRANT ALL PRIVILEGES ON DATABASE "database1" to user1;
Теперь подключаемся к базе, к которой хотим дать доступ:
=# \c database1
* в примере подсоединимся к базе с названием database1.
а) Так мы добавим все права на использование всех таблиц в базе database1 учетной записи user1:
database1=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "user1";
* в большинстве случаев, используется схема по умолчанию public. Но администратор может создать новую схему. Это нужно учитывать при назначении прав.
б) Также можно дать доступ к базе для определенных таблиц:
database1=# GRANT ALL PRIVILEGES ON TABLE table1 IN SCHEMA public TO "user1";
* в данном примере мы даем права на таблицу table1.
Выходим из SQL-оболочки:
database1=# \q
3. Настройка файла pg_hba.conf
Для возможности подключиться к СУБД от созданного пользователя, необходимо проверить настройки прав в конфигурационном файле pg_hba.conf.
Для начала смотрим путь расположения данных для PostgreSQL:
=# SHOW config_file;
В ответ мы получим, что-то на подобие:
-----------------------------------------
/var/lib/pgsql/9.6/data/postgresql.conf
(1 row)
* в данном примере /var/lib/pgsql/9.6/data/ — путь расположения конфигурационных файлов.
Открываем pg_hba.conf:
vi /var/lib/pgsql/9.6/data/pg_hba.conf
Добавляем права на подключение нашему созданному пользователю:
…
# IPv4 local connections:
host all user1 127.0.0.1/32 md5
…
* в данном примере мы разрешили подключаться пользователю user1 ко всем базам на сервере (all) от узла 127.0.0.1 (localhost) с требованием пароля (md5).
* необходимо, чтобы данная строка была выше строки, которая прописана по умолчанию
host all all 127.0.0.1/32 ident.
После перезапускаем службу:
systemctl restart postgresql-9.6
* в данном примере установлен postgresql версии 9.6, для разных версий на разных операционных системах команды для перезапуска сервиса могут быть разные.
4. Проверка
Для теста пробуем подключиться к Postgre с помощью созданного пользователя:
psql -Uuser template1 -h127.0.0.1
Настройка прав доступа к базе с помощью групп
Сначала создадим групповую роль:
=# CREATE ROLE "myRole" NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
* данной командой создана группа myRole с минимальными правами.
Теперь добавим ранее созданного пользователя user1 в эту группу:
=# GRANT "myRole" TO user1;
Подключимся к базе данных, для которой хотим настроить права
=# \c database1
и предоставим все права для группы myRole всем таблицам базы database1
database1=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO GROUP "myRole";
Редактирование пользователя
1. Смена пароля
Рассмотрим несколько примеров смены пароля пользователя.
Одной командой:
=# ALTER USER postgres PASSWORD 'password'
* в данном примере мы зададим пароль password для пользователя postgres.
С запросов ввода пароля:
=# \password postgres
* после ввода данной команды система потребует дважды ввести пароль для пользователя (в нашем примере, postgres).
Из командной строки Linux:
sudo -u postgres psql -U postgres -d postgres -c "ALTER USER postgres PASSWORD 'password'"
* по сути, мы выполняем также запрос в оболочке sql.
Удаление пользователей и групп
Удаление пользователя выполняется следующей командой:
=# DROP USER user;
Забрать права:
database1=# REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM "user";
* обратите внимание, данный запрос отличается от предоставления прав двумя моментами: 1) вместо GRANT пишем REVOKE; 2) вместо TO "user" пишем FROM "user";
Назначение особых прав пользователям PostgreSQL
Помимо ALL PRIVILEGES можно выдавать права на особые операции, например:
=# GRANT SELECT, UPDATE, INSERT ON ALL TABLES IN SCHEMA public TO "user1";
* команда позволит выдать права на получение данных, их обновление и добавление. Другие операции, например, удаление будут запрещены для пользователя user1.
Назначение прав для определенной таблицы:
database1=# GRANT ALL PRIVILEGES ON table_users TO "user1";
* в данном примере мы предоставим все права на таблицу table_users в базе данных database1;
Учетная запись для резервного копирования
Для выполнения резервного копирования лучше всего подключаться к базе с минимальными привилегиями.
Сначала создаем роль, которую будем использовать для выполнения резервного копирования:
=# CREATE USER bkpuser WITH PASSWORD 'bkppasswd';
* мы создадим учетную запись bkpuser с паролем bkppasswd.
Предоставляем права на подключения к базе
=# GRANT CONNECT ON DATABASE database TO bkpuser;
* в данном примере к базе database.
Подключаемся к базе (в нашем примере database):
=# \c database
Даем права на все последовательности в схеме:
=# GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO bkpuser;
* мы дали права для схемы public. Это схема является схемой по умолчанию, но в вашем случае она может быть другой. В таком случае, подставляем свое значение.
Графический интерфейс
Иногда проще воспользоваться программой для выставления прав и работы с PostgreSQL. Могу посоветовать приложение pgAdmin. Оно позволит в оконном режиме не только создать и удалить пользователей, но и полноценно работать с СУБД.
Удаление
Для удаления достаточно ввести следующую команду.
PostgreSQL (базовый репозиторий)
yum remove postgresql-server
PostgreSQL (другая версия — на примере 11)
yum remove postgresql11-server
Установка, настройка и работа с Hashicorp Vault
В данной инструкции попробуем охватить как можно больше примеров работы с Hashicorp Vault. Мы выполним установку на системы Linux, настоим сервер, сохраним несколько секретов и попробуем получить доступ к данным секретам из различных систем. В качестве Linux рассмотрим Debian и CentOS 7 и 8.
Установка пакетов
Нам понадобятся некоторые утилиты. Команды для их установки зависят от используемой системы.
а) Debian:
apt-get install wget chrony curl apt-transport-https
б) CentOS:
yum install wget chrony curl
* где:
- wget — утилита для загрузки файлов.
- chrony — сервис для синхронизации времени.
- curl — утилита для отправки POST и GET запросов на веб-сервер.
- apt-transport-https — дополнение для возможности использовать репозитории по https.
Настройка времени
Для корректного получения токенов необходимо, чтобы время на сервере было правильное. Задаем необходимый нам часовой пояс:
timedatectl set-timezone Europe/Moscow
* полный перечень вариантов можно посмотреть командой timedatectl list-timezones.
Если у нас в сети есть свой сервер синхронизации времени, открываем на редактирование файл настройки chrony.
а) Debian:
vi /etc/chrony/chrony.conf
б) CentOS:
vi /etc/chrony.conf
Нам нужно поменять источник, с которым мы будем синхронизировать наше время. Данная опция отличается в зависимости от версии системы или дистрибутива.
а) в Debian или CentOS 8:
pool user1.local
#pool …
* в нашем примере мы комментируем тот адрес pool, который был в конфигурации и подставляем адрес нашего сервера user1.local.
а) в CentOS 7:
server user1.local
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
* в нашем примере мы комментируем адреса server, которые были в конфигурации и подставляем адрес нашего сервера user1.local.
Разрешаем автоматический запуск для сервиса синхронизации времени и перезапускаем его.
а) для Debian:
systemctl enable chrony
systemctl restart chrony
б) для CentOS:
systemctl enable chronyd
systemctl restart chronyd
Настройка брандмауэра
Для корректной работы сервиса нам необходимо открыть порт 8200. В зависимости от используемой утилиты управления netfilter мы должны применять разные инструменты.
а) Iptables (как правило, Debian):
iptables -I INPUT -p tcp --dport 8200 -j ACCEPT
Для сохранения правила можно воспользоваться утилитой iptables-persistent:
apt-get install iptables-persistent
netfilter-persistent save
б) Firewalld (как правило, для CentOS):
firewall-cmd --permanent --add-port=8200/tcp
firewall-cmd --reload
Установка и запуск
Программный продукт поддерживает различные варианты установки. Мы рассмотрим установку из репозитория.
Подключаем официальный репозиторий и устанавливаем пакет vault.
а) Debian:
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
echo "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list
apt-get update
apt-get install vault
б) CentOS:
wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo -O /etc/yum.repos.d/hashicorp.repo
yum install vault
Разрешаем автозапуск службы и если она не запущена, стартуем ее:
systemctl enable vault --now
Установка выполнена. При попытке зайти по адресу https://<IP-адрес сервера Vault>:8200/ мы должны увидеть страницу начальной настройки мастер-ключей.
Идем дальше.
Настройка рабочего окружения
При попытке выполнить любую операцию в командной строке, мы получим ошибку:
Error checking seal status: Get "https://127.0.0.1:8200/v1/sys/seal-status": x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs
Это значит, что мы пытаемся подключиться к нашему серверу по https с неправильным сертификатом. На этапе первичной настройки не хочется заниматься получением и настройкой валидного сертификата. В официальной документации сказано, что нужно ввести команду:
export VAULT_ADDR=http://127.0.0.1:8200
Она укажет текущему окружению подключаться к серверу по http. Однако, это приведет к другой ошибке:
Error checking seal status: Error making API request.
URL: GET http://127.0.0.1:8200/v1/sys/seal-status
Code: 400. Raw Message:
Client sent an HTTP request to an HTTPS server.
Она говорит, что мы подключаемся к серверу по незащищенному каналу, когда сервер требует безопасного соединения.
Для решения проблемы открываем файл:
vi /etc/vault.d/vault.hcl
И снимаем комментарии со следующих строк, а также меняем значение для поля address:
1 2 3 4 |
listener "tcp" { address = "127.0.0.1:8201" tls_disable = 1 } |
* так как для https уже используется порт 8200, мы должны поменять предложенный по умолчанию вариант на свой, чтобы не возникало конфликтов при запуске сервиса.
Перезапускаем службу vault:
systemctl restart vault
Обновляем системную переменную VAULT_ADDR:
export VAULT_ADDR=http://127.0.0.1:8201
* обратите внимание, что мы поменяли порт подключения на 8201.
Пробуем вывести на экран статус:
vault status
Мы должны получить что-то на подобие:
1 2 3 4 5 6 7 8 9 10 11 12 |
Key Value --- ----- Seal Type shamir Initialized false Sealed true Total Shares 0 Threshold 0 Unseal Progress 0/0 Unseal Nonce n/a Version 1.7.1 Storage Type file HA Enabled false |
Чтобы данная системная переменная создавалась каждый раз при входе пользователя в систему, открываем файл:
vi /etc/environment
И добавляем:
VAULT_ADDR=http://127.0.0.1:8201
Распечатывание
После установки, сервер Vault находится в запечатанном (sealed) состоянии. То есть, он не знает, как ему расшифровывать секреты, которые будут храниться в базе.
При попытке выполнить любую операцию с хранилищем секретов мы получим ошибку:
* Vault is sealed
Чтобы исправить ситуацию, нужно выполнить инициализацию сервера — мы получим ключи для распечатывания (Unseal Keys). После необходимо ввести эти ключи и можно будет авторизоваться в системе.
Инициализация, распечатывание и вход
Для начала, нам необходимо инициализировать наш сервер. Это выполняется командой:
vault operator init
Команда нам вернет 5 ключей. Любые 3 из них являются ключами для распечатывания сервера (Unseal Key). Также нам будет предоставлен токен для root (Initial Root Token), с помощью которого можно будет войти в систему vault.
И так, распечатаем наш сервер, введя по очереди 3 команды.
Для первого ключа:
vault operator unseal
Для второго:
vault operator unseal
И третьего:
vault operator unseal
После выполнения каждой команды система будет запрашивать ключ. Необходимо ввести любые 3 из сгенерированных ранее. При правильном вводе ключа, мы будем видеть общую информацию по ключу. А при вводе третьего ключа мы должны увидеть:
Sealed false
Это значит, что сервер больше не запечатан и с ним можно работать.
Теперь необходимо залогиниться в систему командой:
vault login
… и ввести ключ root, который мы получили после инициализации.
Мы можем выполнять команды для работы с Hashicorp Vault.
Автоматическое распечатывание
После перезагрузки нашего сервера он опять становится запечатанным. Предполагается, что полученных 5 ключей необходимо выдать пяти ответственным за безопасность сотрудникам. После перезагрузки, трое из них должны будут ввести свои данные. Это правильно с точки зрения безопасности.
Однако, если у нас есть причины автоматически поднимать сервер после перезагрузки, рассмотрим, как это сделать.
Данный способ противоречит безопасности, однако, реальная эксплуатация систем не всегда вписывается в рамки идеальных концепций.
Выполним настройку в несколько шагов.
1. Скрипт.
Создадим каталог для хранения скриптов:
mkdir /scripts
Создадим скрипт:
vi /scripts/unseal.sh
1 2 3 4 5 6 7 |
#!/bin/bash PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin sleep 10 vault operator unseal w1SgHSWyXm+7kwmYk4bFX2rBLG5jKxIn01DMkj57071D vault operator unseal 38s4+FkxKTTANFZgCwEPFOgJIMwTvLca1j36yYPc3gdx vault operator unseal 4xlpKVwPuNlskydM/qmCmW22x7WZdfuiFu92HGRNOa8o |
* где w1SgHSWyXm+7kwmYk4bFX2rBLG5jKxIn01DMkj57071D, 38s4+FkxKTTANFZgCwEPFOgJIMwTvLca1j36yYPc3gdx и 4xlpKVwPuNlskydM/qmCmW22x7WZdfuiFu92HGRNOa8o — любых 3 токена (из 5 сгенерированных). Обратите внимание, мы задерживаем выполнение скрипта на 10 секунд — на практике, сервис vault может не успеть запуститься, и мы тогда получим ошибку при выполнении команды vault operator unseal.
Разрешаем запуск скрипта на выполнение:
chmod +x /scripts/unseal.sh
Можно, даже, выполнить скрипт:
/scripts/unseal.sh
В итоге, мы распечатаем наш сервер.
2. Автозапуск скрипта при старте системы:
Большинство современных серверных систем работает на основе systemd. Рассмотрим автозапуск с помощью последней.
Создаем юнит:
vi /etc/systemd/system/vault-unseal.service
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Unit] Description=Vault Auto Unseal Service After=network.target After=vault.service [Service] Environment="VAULT_ADDR=http://127.0.0.1:8201" ExecStart=/scripts/unseal.sh Type=oneshot RemainAfterExit=no [Install] WantedBy=multi-user.target |
* в данном примере мы выполняем одну команду при запуске сервиса — запуск скрипта /scripts/unseal.sh. Перед этим мы создаем системную переменную VAULT_ADDR, чтобы при выполнении команд в скрипте система понимала, к какому серверу подключаться.
Перечитаем конфигурацию для systemd:
systemctl daemon-reload
Разрешаем автозапуск созданного сервиса:
systemctl enable vault-unseal
Пробуем перезагрузить сервер — vault должен оказаться распечатанным.
Работа с секретами
Наша система полностью готова, чтобы ей пользоваться.
Для начала дадим разрешение на хранение секретов по пути secret:
vault secrets enable -path=secret/ kv
Мы должны получить ответ:
Success! Enabled the kv secrets engine at: secret/
Теперь выполним простую операцию по созданию секрета. Введем команду, предложенную на официальном сайте разработчика:
vault kv put secret/hello foo=world
* команда kv взаимодействует с хранилищем Vault. В данном примере мы добавляем пару ключ-значение, соответственно foo-world.
Мы должны получить ответ:
Success! Data written to: secret/hello
Посмотреть содержимое можно командой:
vault kv get secret/hello
На что мы получим:
===== Data =====
Key Value
--- -----
foo world
Также можно внести за раз множество значений:
vault kv put secret/hello foo=world excited=yes
Посмотреть список созданных секретов можно командой:
vault kv list secret
Теперь удалим секрет командой:
vault kv delete secret/hello
Полный перечень команд можно увидеть так:
vault -help
После чего можно будет получить помощь по конкретной команде vault, например:
vault kv -help
Данной информации достаточно, чтобы познакомиться с продуктом. Пойдем дальше.
Версионность и метаданные
Hashicorp Vault поддерживает версионность данных, то есть, мы можем посмотреть определенную версию данных внутри секрета. Однако, по умолчанию, сервис устанавливается с kv версии 1, которая не поддерживает данной операции. При попытке выполнить любую команду, захватывающую версионность, мы получим ошибку:
Metadata not supported on KV Version 1
Для решения необходимо создание механизма kv с поддержкой версии 2. Это делается командой:
vault secrets enable -version=2 kv
Или для ранее созданного пути включаем ведение версионности командой:
vault kv enable-versioning secret/
Теперь занесем 2 раза данные:
vault kv put secret/hello foo=world
vault kv put secret/hello foo=world2
Посмотреть данные определенной версии можно командой:
vault kv get -version=1 secret/hello
В нашем примере мы увидим:
=== Data ===
Key Value
--- -----
foo world
* то есть значение, которое вводилось первой командой.
Посмотреть метаданные секрета можно командой:
vault kv metadata get secret/hello
Для удаления определенной версии секрета вводим:
vault kv destroy -versions=1 secret/hello
Динамические секреты
Мы можем настроить автоматическое создание временных пользователей в различных системах. Это удобно для автоматического назначения прав приложению. При этом, через некоторое время пароль уже не будет действовать, что повышает безопасность системы.
Рассмотрим пример настройки динамических секретов для базы данных MariaDB/MySQL.
Первым делом, создадим пользователя в СУБД с правами создавать других пользователей. Подключаемся к базе данных:
mysql -uroot -p
Создаем учетную запись, под которой будет подключаться vault к СУБД:
> CREATE USER 'vaultuser'@'localhost' IDENTIFIED BY 'vaultpass';
Дадим права созданной учетной записи создавать других пользователей и назначать им права:
> GRANT CREATE USER ON *.* TO 'vaultuser'@'localhost' WITH GRANT OPTION;
Выходим из оболочки SQL:
> exit;
Теперь разрешаем механизм секретов базы данных (database secrets engine):
vault secrets enable database
Мы должны увидеть:
Success! Enabled the database secrets engine at: database/
* также мы можем получить ошибку path is already in use at database/, если данный механизм уже разрешен в нашей системе.
Создадим настройку для подключения к нашей базе:
1 2 3 4 5 6 |
vault write database/config/test \ plugin_name=mysql-database-plugin \ connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \ allowed_roles="test-role" \ username="vaultuser" \ password="vaultpass" |
* предполагается, что:
- test — имя базы, для которой vault сможет создать временную учетную запись.
- plugin_name — имя плагина для создания учетной записи. Важный параметр, который должен правильно быть подобран в зависимости от версии СУБД. Ниже будет комментарий, с какой ошибкой мы можем столкнуться, выбрав неправильный плагин.
- test-role — роль, которая будет использоваться vault (ее создадим ниже).
- vaultuser — пользователь, под которым мы подключаемся к СУБД (создали выше).
- vaultpass — пароль, с которым мы подключаемся к серверу баз данных.
Создадим роль, по сути, зададим команду для создания временной учетной записи:
1 2 3 4 5 |
vault write database/roles/test-role \ db_name=test \ creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT ON *.* TO '{{name}}'@'%';" \ default_ttl="1h" \ max_ttl="24h" |
* где:
- db_name — имя базы данных, для которой мы будем создавать пользователя.
- creation_statements — команды SQL для создания нового пользователя. {{name}} и {{password}} являются специальными переменными, вместо которых vault подставит сгенерированные значения. Обратите внимание, что в данном примере создается пользователь с правами подключения с любого хоста, однако, в зависимости от версии MariaDB, именно с локального хоста подключиться под данным пользователем будет нельзя. При такое необходимости, меняем % на localhost.
- default_ttl — время, в течение которого будет действовать пароль.
- max_ttl — время, в течение которого пользователю можно будет обновлять пароль.
И так, теперь давайте создадим пользователя и пароль:
vault read database/creds/test-role
* после ввода команды vault сгенерирует и создаст в базе нового пользователя и пароль.
Мы должны увидеть что-то на подобие:
1 2 3 4 5 6 7 |
Key Value --- ----- lease_id database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW lease_duration 1h lease_renewable true password 7v9jC-XHXJjQ2sicLI42 username v-test--gVPavnGVr |
* Если мы увидим ошибку, на подобие Error 1470: String 'v-root-test-role-KHWyA2IwdoaUth7c' is too long for user name (should be no longer than 16) мы столкнулись с ограничением на стороне СУБД (нельзя создавать имя пользователя с длиной более 16 символов). Чтобы решить проблему мы должны пересоздать подключение database/config/test с новым плагином mysql-legacy-database-plugin.
Также для создания пользователя мы можем использовать API запрос:
curl --header "X-Vault-Token: s.e0YKJEOHlpfgQiWqZlzVuUbY" http://127.0.0.1:8201/v1/database/creds/test-role
* где X-Vault-Token — токен с доступом. Для теста можно использовать тот, что был получен для root после инициализации системы.
Теперь давайте проверим, что созданные учетные записи имеют нужный нам доступ. Для начала, под пользователем root можно проверить, что записи созданы:
> SELECT user, host FROM mysql.user;
Мы должны увидеть в списках нужную запись (в нашем примере, v-test--gVPavnGVr).
Теперь зайдем под учетной записью, которая была создана с помощью vault:
mysql -h192.168.0.15 -u'v-test--gVPavnGVr' -p'7v9jC-XHXJjQ2sicLI42'
* в моем случае из-за доступа %, подключение с localhost было запрещено. Поэтому я проверяю доступ с другого хоста в локальной сети, добавив опцию -h192.168.0.15 (где 192.168.0.15 — сервер с СУБД, доступ к которой предоставлялся через vault).
Мы должны подключиться к базе.
Отменить доступ можно командой:
vault lease revoke database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW
* где database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW — значение lease_id, которое нам вернула система при создании временной учетной записи.
Посмотреть список всех идентификатором можно командой:
vault list sys/leases/lookup/database/creds/test-role
* где test-role — имя созданной нами роли.
Продлить lease_duration или default_ttl (пароль) можно с помощью команды:
vault lease renew database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW
Аутентификация и политики
Hashicorp Vault позволяет управлять доступами с помощью политик и токенов авторизации. Рассмотрим процесс настройки.
Работа с токенами
Для начала научимся управлять токенами. Простая команда для создания нового:
vault token create
Система сгенерирует новый ключ и сделает вывод на экран.
Также мы можем создать временный токен:
vault token create -period=1h
* на один час.
Посмотреть информацию о токене можно через его аксессор. Сначала получим список аксессоров:
vault list auth/token/accessors
После смотрим токен по аксессору:
vault token lookup -accessor uW9Ajr8VzFiCwHzHWn75qWVe
Войти в систему с помощью токена можно командой:
vault login
После вводим наш токен. Или одной командой:
vault login s.Db9j6Q4TvyFDr3j2aQmXttrX
Посмотреть информацию о токене, под которым мы зарегистрировались в системе, можно командой:
vault token lookup
А данной командой мы создаем пользователя и привязываем его к политике my-policy:
vault token create -policy=my-policy
Если политики нет в системе, то мы получим предупреждение:
WARNING! The following warnings were returned from Vault:
* Policy "my-policy" does not exist
Нас это не должно заботить — на следующем шаге мы ее создадим.
При необходимости привязать токен к нескольким политикам, перечисляем из в опциях policy:
vault token create -policy=my-policy -policy=my-policy2
Работа с политиками
Выше мы создали токен и привязали его к политике my-policy. Создадим ее:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
vault policy write my-policy - << EOF path "secret/data/foo/*" { capabilities = ["read", "create", "update"] } path "secret/data/hello/*" { capabilities = ["read", "update"] } path "secret/data/*" { capabilities = ["read"] } EOF |
* в данной политике мы разрешаем чтение всех секретов в secret. Для ранее созданного секрета secret/hello мы разрешим чтение и обновление записей, а для секрета secret/foo также мы разрешаем создавать записи. Обратите внимание, что на самом деле, данные хранятся в secret/data…
Посмотреть список политик можно командой:
vault policy list
Посмотреть информацию о конкретной политике можно командой:
vault policy read my-policy
Проверка политики
И так, мы создали токен, привязали его к политике, создали саму политику. Проверим, что наши права работают.
Если нужно, можно создать еще токен и привязать его к нашей политике:
vault token create -policy=my-policy
Зарегистрируемся с нужным нам токеном (который привязан к проверяемой политике):
vault login
Попробуем сначала создать секрет в ветке secret/foo и в нем указать пару ключ-значение:
vault kv put secret/foo/new foo=world
Команда должна выполниться успешно.
Теперь сделаем то же самое для secret/hello
vault kv put secret/hello/new foo=world
Мы должны получить ошибку
Error writing data to secret/data/hello/new: Error making API request.
URL: PUT http://127.0.0.1:8201/v1/secret/data/hello/new
Code: 403. Errors:
* 1 error occurred:
* permission denied
Теперь логинимся под токеном с полными правами и добавим запись:
vault kv put secret/hello/new foo=world
И снова заходим под токеном с ограниченными правами. Пробуем обновить запись:
vault kv put secret/hello/new foo=world2
Команда должна выполниться успешно, так как мы разрешили политикой обновлять записи.
Аутентификация на основе пользователей
Также в Hashicorp Vault мы можем создать пользователя с паролем и привязать к нему политику. Администратор сможем входить в систему под учетной записью, а не с помощью токена.
Разрешаем метод auth по пути userpass:
vault auth enable userpass
Создаем пользователя:
vault write auth/userpass/users/user1 password="test-pass" policies="my-profile"
* данной командой мы создали пользователя user1 с паролем test-pass и привязали его к политике my-profile.
Войти в систему можно командой:
vault login -method=userpass username=user1
Вводим пароль и попадаем в систему под пользователем user1. Можно выполнить тесты, которые мы делали выше.
Одноразовые SSH пароли
Рассмотрим варианты хранения секретов для авторизации по SSH с использованием одноразовых паролей или One-Time SSH Password (OTP).
Настройка на сервере Vault
Разрешаем механизм ssh:
vault secrets enable ssh
Создаем роль для создания одноразового пароля:
vault write ssh/roles/otp_key_role \
key_type=otp \
default_user=test \
cidr_list=10.0.2.0/24
* в данном примере:
- key_type — тип создаваемого ключа. Оставляем otp.
- default_user — имя учетной записи.
- cidr_list — подсеть, для которой будет разрешен доступ. Это должна быть подсеть компьютеров, на которых мы будем проходить аутентификацию по одноразовому паролю.
На сервере, пока, все. Переходим к настройке клиента.
Настройка на клиенте
На клиенте необходимо выполнить настройку, которая позволит выполнять две задачи:
- Создавать одноразовые пароли на стороне Vault.
- Осуществлять проверку подлинности при подключении по SSH.
Данной задачей занимается vault-ssh-helper. Рассмотрим процесс его установки и настройки.
Нам понадобится пакет для распаковки zip-архивов. В зависимости от системы ставим его одной из команд ниже.
а) для Debian / Ubuntu:
apt-get install unzip
б) для CentOS / Red Hat / Fedora:
yum install unzip
Установка vault-ssh-helper выполняется простым копированием бинарника. Переходим на официальный сайт для загрузки и выбираем последнюю версию пакета. На следующей страницы копируем ссылку на нужный вариант архива, в зависимости от архитектуры нашего сервера:
С помощью скопированной ссылки загружаем архив:
wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip
Распаковываем его:
unzip vault-ssh-helper_*.zip -d /usr/bin
Создадим каталог для конфигурационных файлов vault-ssh-helper:
mkdir /etc/vault-ssh-helper
Создадим конфигурационный файл:
vi /etc/vault-ssh-helper/config.hcl
vault_addr = "https://192.168.0.20:8200"
ssh_mount_point = "ssh"
tls_skip_verify = true
allowed_roles = "*"
* где:
- vault_addr — адрес нашего сервера секретов.
- ssh_mount_point — путь на стороне Vault, по которому будут храниться секреты. Настраивается при включении механизма SSH.
- tls_skip_verify — стоит ли пропускать проверку подлинности сертификата. Так как у нас еще не настроен валидный сертификат, устанавливаем значение в true.
- allowed_roles — на стороне сервера можно создавать разным пользователей от разных ролей. В данной настройке мы можем определить, пользователям с какой ролью будет разрешен вход по SSH.
Открываем конфигурационный файл pamd для sshd:
vi /etc/pam.d/sshd
И в самый верх добавляем:
auth sufficient pam_exec.so quiet expose_authtok log=/tmp/vaultssh.log /usr/bin/vault-ssh-helper -config=/etc/vault-ssh-helper/config.hcl
auth optional pam_unix.so not_set_pass use_first_pass nodelay
…
* в данной конфигурации мы, по-прежнему, сможем авторизоваться под учетными записями, созданными на самом сервере. Если необходимо это отключить, разрешив вход только с OTP, комментируем @include common-auth и меняем sufficient на required.
Наконец, редактируем конфигурационный файл sshd. Открываем его:
vi /etc/ssh/sshd_config
Выставляем следующие значения для опций:
ChallengeResponseAuthentication yes
…
UsePAM yes
* где ChallengeResponseAuthentication разрешает авторизацию с применением интерактивного ввода пароля; UsePAM разрешает использование модуля pam.
Перезапустим сервис ssh:
systemctl restart sshd
Выполняем проверку нашей настройки командой:
vault-ssh-helper -verify-only -config /etc/vault-ssh-helper/config.hcl
Мы должны получить ответ:
2021/05/18 14:07:14 [INFO] using SSH mount point: ssh
2021/05/18 14:07:14 [INFO] using namespace:
2021/05/18 14:07:14 [INFO] vault-ssh-helper verification successful!
Значит настройка на клиенте выполнена коррекнто.
Создаем учетную запись на клиенте, под которой будем входить в систему с одноразовым паролем:
useradd test -m
* в нашей политике будет создаваться пароль для учетной записи test.
Создаем одноразовый пароль
Вводим команду:
vault write ssh/creds/otp_key_role ip=192.168.0.25
* в данном примере мы создаем одноразовый пароль для компьютера с IP-адресом 192.168.0.25.
Мы должны получить, примерено, такой вывод:
Key Value
--- -----
lease_id ssh/creds/otp_key_role/5SYfW5VDZ3qGnaMtPhUEHbNr
lease_duration 768h
lease_renewable false
ip 192.168.0.25
key 83a57021-74b0-3ce3-8179-6fb92288c0ce
key_type otp
port 22
username test
* мы получили одноразовый пароль 83a57021-74b0-3ce3-8179-6fb92288c0ce.
Пробуем войти в систему:
ssh test@192.168.0.25
Вводим тот пароль, который нам выдала система (key). Войти мы сможем только один раз, после нужно будет уже генерировать новый пароль.
Настройка SSL
В инструкции выше мы настроили наше окружение для локального подключения по http. Данный метод временный, так как не позволит управлять системой с другого компьютера или придется жертвовать безопасностью. Рассмотрим процесс настройки запросов по защищенному протоколу https.
Первое, что нам нужно, это получить сертификат. Правильнее всего купить сертификат или запросить через Let's Encrypt. После прописать в конфигурационном файле vault путь до данного сертификата. Но мы рассмотрим процесс получения самоподписанного сертификата, но при этом, который примет система. Для этого необходимо выполнить несколько условий:
- Сертификат должен быть выдан для hostname, по которому мы будем отправлять запросы.
- Для сертификата мы должны указать альтернативное имя subjectAltName.
И так, создаем каталог для хранения сертификатов:
mkdir /etc/ssl/vault
Проверяем версию openssl:
openssl version
Она должна быть 1.1.1 и выше. В противном случае, необходимо выполнить обновление OpenSSL. Как правило, данное действие требуется только на CentOS 7.
Генерируем сертификат:
openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/vault/cert.pem -keyout /etc/ssl/vault/cert.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=vault.user1.local" -addext "subjectAltName = DNS:vault.user1.local"
* в данном примере мы сгенерируем необходимые ключи по пути /etc/ssl/vault; обязательно, нужно поменять значения vault.user1.local на имя сервера, который используется у вас.
Если команда вернет ошибку, проверяем, что у нас обновленная версия openssl, которая поддерживает ключ addext.
Теперь откроем конфигурационный файл hashicorp vault:
vi /etc/vault.d/vault.hcl
Приведем секцию HTTPS listener к виду:
# HTTPS listener
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/ssl/vault/cert.pem"
tls_key_file = "/etc/ssl/vault/cert.key"
}
* необходимо поменять пути до файлов tls_cert_file и tls_key_file.
Перезапускаем сервис:
После перезагрузки сервиса, он станет запечатанным и нам нужно будет снова ввести 3 части ключа (команды vault operator unseal).
systemctl restart vault
Меняем в окружении переменную VAULT_ADDR:
export VAULT_ADDR=https://vault.user1.local:8200
* мы указываем протокол https, обращения должны выполняться по доменному имени, для которого мы получили сертификат; также указываем порт 8200.
Выполняем команду:
vault status
Мы должны получить состояние системы. Значит запросы по https работают.
И последнее, снова открываем файл:
vi /etc/environment
И также меняем значение для переменной VAULT_ADDR:
VAULT_ADDR=https://vault.user1.local:8200
Запуск в виде контейнера Docker
В инструкции мы рассмотрели установку Hashicorp Vault как пакета. Также мы можем установить данный сервис в виде контейнера Docker из официального образа. Рассмотрим вкратце данный вопрос.
Для начала, необходимо установить в систему Docker. После загружаем образ
docker pull vault
Для запуска vault в режиме сервера вводим:
docker run --cap-add=IPC_LOCK --name vault -d -p 8200:8200 -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "listener": {"tcp": {"address": "127.0.0.1:8200", "tls_disable": "true"}}}' vault server
После заходим внутрь контейнера:
docker exec -it vault sh
Задаем системную переменную для подключения к vault по http:
export VAULT_ADDR=http://127.0.0.1:8200
Инициализируем сервер:
vault operator init
… и так далее.
Установка клиента и удаленное подключение
Мы можем управлять нашим сервером с удаленного компьютера из командной строки. Для этого необходимо установить клиента и настроить системное окружение.
Установка клиента ничем не отличается от установки сервера. Только нам не нужно инициализировать систему и запускать ее в качестве сервиса. Операции отличаются в зависимости от установленной операционной системы.
а) для Debian / Ubuntu / Mint:
apt-get install wget apt-transport-https
echo "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list
apt-get update
apt-get install vault
б) для CentOS / Red Hat / Fedora:
yum install wget
wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo -O /etc/yum.repos.d/hashicorp.repo
yum install vault
После чего задаем переменную системного окружения
export VAULT_ADDR=https://vault.user1.local:8200
* обратите внимание, что мы подключаемся уже по https. Имя нашего сервера должно разрешаться в DNS или быть прописано в файле hosts на компьютере управления.
Также, если у нас самоподписанный сертификат, вводим:
export VAULT_SKIP_VERIFY=true
* данная системная переменная указывает системе не проверять валидность сертификата.
Пробуем посмотреть статус удаленного сервера:
vault status
Регистрируемся в системе:
vault login -method=userpass username=user1
* в данном примере мы заходим под пользователем user1. Также мы можем войти с использованием токена.
Можно выполнять действия согласно разрешениям.
Управление динамическими учетными записями в PostgreSQL через Hashicorp Vault
Настройка прав PostgreSQL
На сервере PostgreSQL нам необходимо:
- Задать пароль для пользователя postgres.
- Создать пользователя, пароль для которого мы будем хранить в Vault.
- Разрешить подключение к базе данных для postgres и созданного пользователя.
- Открыть порт 5432 для удаленного подключения.
- Проверить доступы.
Рассмотрим действия по шагам.
1. Задаем пароль для postgres
Данные действия необходимы, если мы не задавали пароль для пользователя postgres или мы не знаем данный пароль.
Стоит иметь ввиду, что данный пользователь может использоваться другими приложениями — таким образом, смена пароля приведет к потере их работоспособности. В этом случае, стоит уточнить текущий пароль и использовать его.
Заходим под пользователем postgres и подключаемся к СУБД:
su - postgres
$ psql
Вводим:
=# ALTER USER postgres PASSWORD 'password';
* в данном примере мы задаем пароль password для пользователя postgres.
2. Создаем нового пользователя
На данном шаге мы создадим пользователя, для которого и будем хранить секрет в Vault. В рамках примера мы не будем его предоставлять никаких доступов. Для нас достаточно, чтобы мы могли подключиться и удостовериться, что пароль будет меняться.
В той же командной оболочке postgresql вводим:
=# CREATE USER user1 WITH PASSWORD 'myPassword';
* с помощью данной команды мы создадим пользователя user1 с паролем myPassword.
3. Разрешаем подключение к СУБД
Нам необходимо разрешить подключаться к базе данных пользователю user1 (создали на шаге 2) с локального компьютера и пользователю postgres с сервера Vault. Это делается посредством редактирования файла pg_hba.conf.
Но размещение этого файла может быть разным — это зависит от версии установленного PostgreSQL. Вводим команду:
=# SHOW config_file;
Данная команда нам покажет место размещения конфигурационного файла postgresql.conf — в этом же каталоге находятся и другие конфигурационные файлы. Например, если команда показала:
----------------------------------------
/var/lib/pgsql/11/data/postgresql.conf
(1 row)
… то значит нужный нам файл в каталоге /var/lib/pgsql/11/data.
Выходим из командной оболочки psql:
=# \q
Разлогиниваемся из-под пользователя postgres:
$ exit
И вводим:
vi /var/lib/pgsql/11/data/pg_hba.conf
* где /var/lib/pgsql/11/data — путь, который мы получили с помощью sql-команды SHOW config_file.
В данном файле мы должны добавить 2 строки:
1 2 3 4 5 6 7 |
... # "local" is for Unix domain socket connections only local all user1 md5 ... # IPv4 local connections: host all postgres 192.168.1.20/32 md5 ... |
* где 192.168.1.20 — IP-адрес предполагаемого сервера Vault, с которого мы будем подключаться под пользователем postgres.
Открываем конфигурационный файл:
vi /var/lib/pgsql/11/data/postgresql.conf
Приводим опцию listen_addresses к виду:
listen_addresses = '*'
* в данном примере мы настроили, чтобы postgresql слушал запросы на всех сетевых интерфейсах. При необходимости. мы можем ограничить их число вводом конкретного адреса.
Перезапускаем службу СУБД:
systemctl restart postgresql
* команда для перезапуска PostgreSQL может отличаться и зависит от версии СУБД.
4. Настраиваем межсетевой экран
Для подключения к серверу баз данных по сети, нам необходимо открыть порт 5432.
Как правило, в CentOS используется firewalld, как средство управления брандмауэром. Вводим:
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload
5. Делаем проверку
Убедимся, что наши учетные записи имеют права для подключения к базе данных.
На сервере с СУБД вводим:
psql -Uuser1 -W template1
* в данном примере мы подключаемся к локальному хосту под пользователем user1.
Система запросит пароль — вводим тот, что задали при создании нашего пользователя. Мы должны попасть в оболочку psql.
Теперь подключаемся по SSH на сервер Vault. Нам придется установить на него клиента postgresql.
а) На системы RPM (Rocky Linux, CentOS):
yum install postgresql
б) На Deb (Ubuntu, Debian):
apt install postgresql
После установки можно подключаться к нашему серверу с помощью команды psql.
Вводим:
psql -h192.168.1.15 -Upostgres -W
* в данном примере мы подключимся к серверу 192.168.1.15 под учетной записью postgres.
Консоль у нас запросит пароль — вводим тот, что задали для пользователя postgres. В итоге мы должны подключиться к серверу:
postgres=#
Выходим из SQL-оболочки:
postgres=# \q
… и переходим к настройке Vault.
Настройка Vault
На стороне хранилища паролей необходимо:
- Включить механизм хранения database.
- Создать конфигурацию для подключения к СУБД и привязать ее к роли.
Выполним настройки по шагам.
Включаем механизм database
Для включения механизма database вводим:
vault secrets enable database
Мы должны получить ответ:
Success! Enabled the database secrets engine at: database/
… или:
Error enabling: Error making API request.
…
* path is already in use at database/
Второй ответ говорит нам о том, что механизм database уже работает по пути database/. Так или иначе, идем дальше.
Настройка подключения к postgresql
Создаем конфигурацию с опциями подключения к базе данных:
1 2 3 4 5 6 |
vault write database/config/postgresql \ plugin_name=postgresql-database-plugin \ allowed_roles="postgresql-rotate,postgresql-create" \ connection_url=postgresql://{{username}}:{{password}}@192.168.0.15:5432/postgres?sslmode=disable \ username="postgres" \ password="password" |
* где:
- database/config/postgresql — путь в системе Vault к секрету.
- plugin_name — плагин, который будем использоваться конфигурацией.
- allowed_roles — для каких ролей будет использоваться данная конфигурация. Ниже по инструкции мы создадим 2 роли — для ротации паролей и для создания временных пользователей.
- connection_url — строка подключения к базе данных. В данном примере 192.168.0.15 — сервер PostgreSQL.
- username — пользователь, под которым выполняется подключение к СУБД.
- password — пароль для пользователя, под которым выполняем подключение.
Наш Vault подготовлен для работы с базой PostgreSQL.
Настройка ротации паролей
Данная настройка позволит автоматически по таймеру менять пароли в СУБД PostgreSQL для определенных учетных записей.
На стороне хранилища паролей необходимо:
- Создать роль, которая будет менять пароль в базе данных.
- Проверить настройки, создав новый пароль и подключившись к базе данных.
Переходим к настройке.
Создаем роль для смены пароля
Настройка задается с помощью static-roles. В нашем Vault вводим команду:
1 2 3 4 5 |
vault write database/static-roles/postgresql-rotate \ db_name=postgresql \ rotation_statements="ALTER USER \"{{name}}\" WITH PASSWORD '{{password}}';" \ username="user1" \ rotation_period=720h |
* обратите внимание, что запрос rotation_statements важно написать именно так — первая кавычка двойная, вторая одинарная.
** в данном примере:
- Мы создадим роль с названием postgresql-rotate (с тем названием, которое мы использовали в allowed_roles, когда создавали конфигурацию).
- Опция db_name должна называться как настройка, которую мы создали на предыдущем шаге (database/config/postgresql).
- Наша роль будет выполнять команду rotation_statements (менять пароль для пользователя).
- Каждые 720 часов (30 дней) пароль будет меняться автоматически.
Мы должны увидеть что-то на подобие:
Success! Data written to: database/static-roles/postgresql-rotate
Готово.
Меняем пароль и проверяем доступ
Давайте посмотрим текущий пароль:
vault read database/static-creds/postgresql-rotate
Мы получим что-то на подобие:
1 2 3 4 5 6 7 |
Key Value --- ----- last_vault_rotation 2021-09-07T11:35:07.796668266+03:00 password Cai-dzsJDtKTLHSl6Bvt rotation_period 720h ttl 719h48m55s username user1 |
Где Cai-dzsJDtKTLHSl6Bvt — наш пароль от учетной записи user1.
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
psql -Uuser1 -W template1
Мы должны подключиться с использованием пароля, который получили от Vault.
Создание временных пользователей в PostgreSQL
Давайте теперь рассмотрим настройку, при которой Vault будет создавать временных пользователей. Для этого мы:
- Создадим роль в Vault, которая будет создавать учетную запись в базе PostgreSQL.
- Настроим файл pg_hba.conf для возможности подключаться к базе пользователям по паролю.
- Проверим настройки, создав учетную запись и подключившись к СУБД.
Приступим.
Создаем роль для создания нового пользователя
Настройка задается с помощью roles. На сервере Vault вводим команду:
1 2 3 4 5 |
vault write database/roles/postgresql-create \ db_name=postgresql \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "{{name}}";" \ default_ttl="1h" \ max_ttl="24h" |
* обратите внимание, что запрос creation_statements важно написать именно так — первая кавычка двойная, остальные одинарные.
** в данном примере:
- Мы создадим роль с названием postgresql-create (с тем названием, которое мы использовали в allowed_roles, когда создавали конфигурацию).
- Опция db_name должна называться как настройка, которую мы создали на шаге создания конфига (database/config/postgresql).
- Наша роль будет выполнять команду creation_statements — создавать пользователя и задавать ему права. Нужно переписать запрос, чтобы права выдавались такими, какими нужны именно вам. Для тестовых целей можно поставить как в данном примере.
- default_ttl — время, в течение которого будет действовать пароль.
- max_ttl — время, в течение которого пользователю можно будет обновлять пароль.
Мы должны увидеть что-то на подобие:
Success! Data written to: database/roles/postgresql-create
Готово.
Настраиваем файл pg_hba.conf
Ранее в инструкции мы настраивали данный файл, чтобы обеспечить возможность подключения к базе пользователям user1 и postgresql. Но при создании динамических учетных записей, логины будут разные — необходимо разрешить парольный вход для всех пользователей.
Открываем файл:
vi /var/lib/pgsql/11/data/pg_hba.conf
* напомню, что путь до нашего файла может быть другим — это зависит от операционной системы и версии postgresql. Посмотреть расположение конфигурационных файлов можно sql-командой SHOW config_file;
В открывшемся редакторе необходимо внести изменения:
1 2 3 4 5 6 7 |
... # "local" is for Unix domain socket connections only local all user1 md5 local all postgres peer local all all md5 ##local all all peer ... |
* мы добавили строку, разрешающую пользователю postgres логин с локального хоста (local) без запроса пароля; также мы закомментировали строку, которая позволяет вход всем пользователям с локального хоста без пароля и добавили новую, почти, такую же, но требующую ввода логина и пароля.
** это, всего лишь, пример настройки. В вашем случае необходимо руководствоваться политикой безопасности, принятой в компании и требованиями приложения.
Перезапускаем сервис СУБД:
systemctl restart postgresql
* также напомню, что название сервиса может отличаться и это зависит от версии PostgreSQL.
Создаем нового пользователя и проверяем доступ
Создаем временного пользователя командой:
vault read database/creds/postgresql-create
Мы должны увидеть что-то на подобие:
1 2 3 4 5 6 7 |
Key Value --- ----- lease_id database/creds/postgresql-create/HMkEz1q6zuaSeyDNBeC8nhDK lease_duration 1h lease_renewable true password 9oAhg1VIEhleeRA7EU-U username v-root-postgres-0VO0sWprjEuCPZkZpu62-1631008720 |
Наши логин и пароль соответственно — v-root-postgres-0VO0sWprjEuCPZkZpu62-1631008720 и 9oAhg1VIEhleeRA7EU-U.
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
psql -U'v-root-postgres-0VO0sWprjEuCPZkZpu62-1631008720' -W template1
Мы должны подключиться с использованием пароля, который получили от Vault.