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. |