--- title: PostgreSQL через Vault - управление динамическими учетными записями description: published: true date: 2024-08-01T15:34:42.498Z 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 'password'; ``` *в данном примере мы задаем пароль password для пользователя postgres.* ### Создаем нового пользователя На данном шаге мы создадим пользователя, для которого и будем хранить секрет в Vault. В рамках примера мы не будем его предоставлять никаких доступов. Для нас достаточно, чтобы мы могли подключиться и удостовериться, что пароль будет меняться. В той же командной оболочке postgresql вводим: =# CREATE USER dmosk WITH PASSWORD 'myPassword'; *с помощью данной команды мы создадим пользователя dmosk с паролем myPassword.* ### Разрешаем подключение к СУБД Нам необходимо разрешить подключаться к базе данных пользователю 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 может отличаться и зависит от версии СУБД.* ### Настраиваем межсетевой экран Для подключения к серверу баз данных по сети, нам необходимо открыть порт 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.