338 lines
19 KiB
Markdown
338 lines
19 KiB
Markdown
---
|
||
title: PostgreSQL через Vault - управление динамическими учетными записями
|
||
description:
|
||
published: true
|
||
date: 2024-08-01T15:52:14.268Z
|
||
tags: vault, postgresql
|
||
editor: markdown
|
||
dateCreated: 2024-08-01T14:55:31.582Z
|
||
---
|
||
|
||
# Управление динамическими учетными записями в PostgreSQL через Hashicorp Vault
|
||
|
||
>В инструкции мы рассмотрим процесс хранения учетной записи PostgreSQL в хранилище секретов Hashicorp Vault, используя механизм database, с возможностью автоматической смены секрета в СУБД при его смене в Vault. Также мы настроим Vault для создания временных учетных записей в PostgreSQL.
|
||
|
||
|
||
## Настройка прав PostgreSQL
|
||
|
||
На сервере PostgreSQL нам необходимо:
|
||
|
||
- Задать пароль для пользователя postgres.
|
||
- Создать пользователя, пароль для которого мы будем хранить в Vault.
|
||
- Разрешить подключение к базе данных для postgres и созданного пользователя.
|
||
- Открыть порт 5432 для удаленного подключения.
|
||
- Проверить доступы.
|
||
|
||
Рассмотрим действия по шагам.
|
||
|
||
### Задаем пароль для postgres
|
||
Данные действия необходимы, если мы не задавали пароль для пользователя postgres или мы не знаем данный пароль.
|
||
>Стоит иметь ввиду, что данный пользователь может использоваться другими приложениями — таким образом, смена пароля приведет к потере их работоспособности. В этом случае, стоит уточнить текущий пароль и использовать его.
|
||
|
||
Заходим под пользователем postgres и подключаемся к СУБД:
|
||
```
|
||
su - postgres
|
||
$ psql
|
||
```
|
||
|
||
Вводим:
|
||
```
|
||
=# ALTER USER postgres PASSWORD 'qwerty123';
|
||
```
|
||
*в данном примере мы задаем пароль qwerty123 для пользователя postgres.*
|
||
|
||
### Создаем нового пользователя
|
||
На данном шаге мы создадим пользователя, для которого и будем хранить секрет в Vault. В рамках примера мы не будем его предоставлять никаких доступов. Для нас достаточно, чтобы мы могли подключиться и удостовериться, что пароль будет меняться.
|
||
|
||
В той же командной оболочке postgresql вводим:
|
||
```
|
||
=# CREATE USER ksu WITH PASSWORD 'qwerty123';
|
||
```
|
||
*с помощью данной команды мы создадим пользователя ksu с паролем qwerty123.*
|
||
|
||
### Разрешаем подключение к СУБД
|
||
Нам необходимо разрешить подключаться к базе данных пользователю ksu (создали на шаге 2) с локального компьютера и пользователю postgres с сервера Vault. Это делается посредством редактирования файла pg_hba.conf.
|
||
|
||
Но размещение этого файла может быть разным — это зависит от версии установленного PostgreSQL. Вводим команду:
|
||
```
|
||
=# SHOW config_file;
|
||
```
|
||
Данная команда нам покажет место размещения конфигурационного файла postgresql.conf — в этом же каталоге находятся и другие конфигурационные файлы. Например, если команда показала:
|
||
```
|
||
----------------------------------------
|
||
/etc/postgresql/11/main/postgresql.conf
|
||
(1 row)
|
||
```
|
||
... то значит нужный нам файл в каталоге /etc/postgresql/11/main/.
|
||
|
||
Выходим из командной оболочки psql:
|
||
```
|
||
=# \q
|
||
```
|
||
Разлогиниваемся из-под пользователя postgres:
|
||
```
|
||
$ exit
|
||
```
|
||
И вводим:
|
||
```
|
||
vi /etc/postgresql/11/main/pg_hba.conf
|
||
```
|
||
*где /etc/postgresql/11/main/ — путь, который мы получили с помощью sql-команды SHOW config_file.*
|
||
|
||
В данном файле мы должны добавить 2 строки:
|
||
```
|
||
...
|
||
# "local" is for Unix domain socket connections only
|
||
local all ksu md5
|
||
...
|
||
# IPv4 local connections:
|
||
host all postgres 172.30.5.19/32 md5
|
||
...
|
||
```
|
||
|
||
*где 172.30.5.19 — IP-адрес предполагаемого сервера Vault, с которого мы будем подключаться под пользователем postgres.*
|
||
|
||
Открываем конфигурационный файл:
|
||
```
|
||
vi /etc/postgresql/11/main/postgresql.conf
|
||
```
|
||
Приводим опцию listen_addresses к виду:
|
||
```
|
||
listen_addresses = '*'
|
||
```
|
||
*в данном примере мы настроили, чтобы postgresql слушал запросы на всех сетевых интерфейсах. При необходимости. мы можем ограничить их число вводом конкретного адреса.*
|
||
|
||
Перезапускаем службу СУБД:
|
||
```
|
||
systemctl restart postgresql
|
||
```
|
||
*команда для перезапуска PostgreSQL может отличаться и зависит от версии СУБД.*
|
||
|
||
### Настраиваем межсетевой экран
|
||
Для подключения к серверу баз данных по сети, нам необходимо открыть порт 5432.
|
||
|
||
Как правило, в CentOS используется firewalld, как средство управления брандмауэром. Вводим:
|
||
```
|
||
firewall-cmd --permanent --add-port=5432/tcp
|
||
|
||
firewall-cmd --reload
|
||
```
|
||
5. Делаем проверку
|
||
Убедимся, что наши учетные записи имеют права для подключения к базе данных.
|
||
|
||
На сервере с СУБД вводим:
|
||
```
|
||
psql -Uksu -W template1
|
||
```
|
||
* в данном примере мы подключаемся к локальному хосту под пользователем ksu.
|
||
|
||
Система запросит пароль — вводим тот, что задали при создании нашего пользователя. Мы должны попасть в оболочку psql.
|
||
|
||
Теперь подключаемся по SSH на сервер Vault. Нам придется установить на него клиента postgresql.
|
||
|
||
На Deb (Ubuntu, Debian):
|
||
```
|
||
apt install postgresql
|
||
```
|
||
После установки можно подключаться к нашему серверу с помощью команды psql.
|
||
|
||
Вводим:
|
||
```
|
||
psql -h172.30.30.87 -Upostgres -W
|
||
```
|
||
*в данном примере мы подключимся к серверу 172.30.30.87 под учетной записью 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}}@172.30.30.87:5432/postgres?sslmode=disable \
|
||
username="postgres" \
|
||
password="qwerty123"
|
||
```
|
||
где:
|
||
|
||
- **database/config/postgresql** — путь в системе Vault к секрету.
|
||
- **plugin_name** — плагин, который будем использоваться конфигурацией.
|
||
- **allowed_roles** — для каких ролей будет использоваться данная конфигурация. Ниже по инструкции мы создадим 2 роли — для ротации паролей и для создания временных пользователей.
|
||
- **connection_url** — строка подключения к базе данных. В данном примере 172.30.30.87 — сервер 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="ksu" \
|
||
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 2024-08-01T17:08:42.837263316+03:00
|
||
password O-Zl1M15Ze1FWzTtPZN1
|
||
rotation_period 720h
|
||
ttl 719h39m58s
|
||
username ksu
|
||
|
||
```
|
||
Где **O-Zl1M15Ze1FWzTtPZN1** — наш пароль от учетной записи ksu.
|
||
|
||
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
|
||
```
|
||
psql -Uksu -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
|
||
Ранее в инструкции мы настраивали данный файл, чтобы обеспечить возможность подключения к базе пользователям ksu и postgresql. Но при создании динамических учетных записей, логины будут разные — необходимо разрешить парольный вход для всех пользователей.
|
||
|
||
Открываем файл:
|
||
```
|
||
vi /etc/postgresql/11/main/pg_hba.conf
|
||
```
|
||
* напомню, что путь до нашего файла может быть другим — это зависит от операционной системы и версии postgresql. Посмотреть расположение конфигурационных файлов можно sql-командой **SHOW config_file**;
|
||
|
||
В открывшемся редакторе необходимо внести изменения:
|
||
```
|
||
...
|
||
# "local" is for Unix domain socket connections only
|
||
local all ksu 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/dluf4Zt8DUn28jsEhAv6tqmE
|
||
lease_duration 1h
|
||
lease_renewable true
|
||
password SREUIRWI2D-IyGi5npN9
|
||
username v-ldap-dfe-postgres-73SnRsVbtmVw86CAAlPy-1722523328
|
||
```
|
||
Наши логин и пароль соответственно — **v-root-postgres-0VO0sWprjEuCPZkZpu62-1631008720** и **9oAhg1VIEhleeRA7EU-U**.
|
||
|
||
Перейдем на сервер с PostgreSQL и попробуем войти в СУБД с использованием этих данных:
|
||
```
|
||
psql -U'v-ldap-dfe-postgres-73SnRsVbtmVw86CAAlPy-1722523328' -W template1
|
||
```
|
||
Мы должны подключиться с использованием пароля, который получили от Vault. |