Управление динамическими учетными записями в PostgreSQL через Hashicorp Vault
Используемые термины: PostgreSQL, Hashicorp Vault.
В инструкции мы рассмотрим процесс хранения учетной записи PostgreSQL в хранилище секретов Hashicorp Vault, используя механизм database, с возможностью автоматической смены секрета в СУБД при его смене в Vault. Также мы настроим Vault для создания временных учетных записей в PostgreSQL.
Предполагается, что у нас уже установлены сервер Vault и СУБД PostgreSQL (инструкция на примере CentOS).
Наши действия:
Настройка прав 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 dmosk WITH PASSWORD 'myPassword';
* с помощью данной команды мы создадим пользователя dmosk с паролем myPassword.
3. Разрешаем подключение к СУБД
Нам необходимо разрешить подключаться к базе данных пользователю dmosk (создали на шаге 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 строки:
...
# "local" is for Unix domain socket connections only
local all dmosk 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 -Udmosk -W template1
* в данном примере мы подключаемся к локальному хосту под пользователем dmosk.
Система запросит пароль — вводим тот, что задали при создании нашего пользователя. Мы должны попасть в оболочку 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
Создаем конфигурацию с опциями подключения к базе данных:
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 вводим команду:
vault write database/static-roles/postgresql-rotate \
db_name=postgresql \
rotation_statements="ALTER USER \"{{name}}\" WITH PASSWORD '{{password}}';" \
username="dmosk" \
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
Мы получим что-то на подобие:
Key Value
--- -----
last_vault_rotation 2021-09-07T11:35:07.796668266+03:00
password Cai-dzsJDtKTLHSl6Bvt
rotation_period 720h
ttl 719h48m55s
username dmosk
Где Cai-dzsJDtKTLHSl6Bvt — наш пароль от учетной записи dmosk.
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
psql -Udmosk -W template1
Мы должны подключиться с использованием пароля, который получили от Vault.
Создание временных пользователей в PostgreSQL
Давайте теперь рассмотрим настройку, при которой Vault будет создавать временных пользователей. Для этого мы:
- Создадим роль в Vault, которая будет создавать учетную запись в базе PostgreSQL.
- Настроим файл pg_hba.conf для возможности подключаться к базе пользователям по паролю.
- Проверим настройки, создав учетную запись и подключившись к СУБД.
Приступим.
Создаем роль для создания нового пользователя
Настройка задается с помощью roles. На сервере Vault вводим команду:
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
Ранее в инструкции мы настраивали данный файл, чтобы обеспечить возможность подключения к базе пользователям dmosk и postgresql. Но при создании динамических учетных записей, логины будут разные — необходимо разрешить парольный вход для всех пользователей.
Открываем файл:
vi /var/lib/pgsql/11/data/pg_hba.conf
* напомню, что путь до нашего файла может быть другим — это зависит от операционной системы и версии postgresql. Посмотреть расположение конфигурационных файлов можно sql-командой SHOW config_file;
В открывшемся редакторе необходимо внести изменения:
...
# "local" is for Unix domain socket connections only
local all dmosk 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
Мы должны увидеть что-то на подобие:
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.