Задание 4: Создание транспортных паролей и grace-период
Pangolin поддерживает концепцию транспортных (временных) паролей. При смене пароля пользователь может продолжать подключаться к СУБД по старому паролю в течение определенного настроенного времени, известного как grace-период.
Это особенно важно для автоматической ротации паролей технических учетных записей, используемых приложениями.
Grace-период позволяет обновить пароль технической учетной записи с сохранением доступности приложения, давая время на распространение нового пароля по всем компонентам системы.
Grace-пароль позволяет пользователю подключиться к СУБД на ограниченный период времени, даже если его основной пароль истек или был изменен.
Если пользователь предоставляет валидный grace-пароль, период активности аутентификации будет ограничен оставшимся временем действия grace-пароля.
Действие по смене пароля с транспортного на постоянный всегда фиксируется в логе аудита, независимо от общих настроек аудита.
Параметры настройки:
transport_password_life_time– поле функцииselect_all_password_policies()определяет время жизни транспортного пароля (временного пароля, который пользователь должен сменить при первом входе).istransportpassword– параметр функцииselect_all_password_policies()определяет, является ли пароль технической учетной записи временным (true) или постоянным (false).password_policy.transport_password_mark_automatic– этот конфигурационный параметр регулирует, будет ли пароль автоматически помечаться как транспортный при его изменении другим пользователем (например, администратором).
Упражнение 1. Настройка grace-периода
-
Создайте роль
grace_user, установив 10 секунд (10 sec) в качестве grace-периода:postgres@postgres=# CREATE ROLE grace_user PASSWORD '#securePassword456';CREATE ROLEpostgres@postgres=# SELECT * FROM set_role_policies('grace_user', max_age('10 sec'),grace_login_limit(2), policy_enable('1'))\gx┌─[ RECORD 1 ]──────────────────────┬────────────┐│ roleid │ grace_user ││ reuse_time │ ││ in_history │ ││ max_age │ 00:00:10 ││ min_age │ ││ grace_login_limit │ 2 ││ grace_login_time_limit │ ││ expire_warning │ ││ lockout │ ││ lockout_duration │ ││ max_failure │ ││ failure_count_interval │ ││ check_syntax │ ││ min_length │ ││ illegal_values │ ││ alpha_numeric │ ││ min_alpha_chars │ ││ min_special_chars │ ││ min_uppercase │ ││ min_lowercase │ ││ max_rpt_chars │ ││ policy_enable │ t ││ track_login │ ││ max_inactivity │ ││ use_password_strength_estimator │ ││ password_strength_estimator_score │ ││ custom_function │ ││ transport_password_life_time │ ││ grace_authid_period │ │└───────────────────────────────────┴────────────┘Не забудьте включить возможность для роли авторизовываться по логину:
postgres@postgres=# ALTER ROLE grace_user LOGIN;ALTER ROLE -
Включите парольные политики в конфигурационном файле
postgresql.conf, как делали в задании 2. -
Подождите 10 секунд и попробуйте подключиться пользователем
grace_userк серверу со старым паролем:[postgres@ServerName ~]$ psql -h <IP-Address> -U grace_user -d postgresPassword for user grace_user:WARNING: Password was expired. 1 grace logins leftPager is used for long output.Border style is 2.Line style is unicode.psql (15.5)SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)Type "help" for help.grace_user@postgres=# \qПодключение осуществлено, выведено сообщение об оставшемся количестве возможных подключений по старому паролю.
-
Подключайтесь снова с прежним паролем, пока не исчерпаете возможности подключиться по истекшему паролю:
[postgres@ServerName ~]$ psql -U grace_user -h ServerName -d postgresPassword for user test_user:WARNING: Password was expired. 0 grace logins leftPager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help.test_user@postgres=# \qТеперь при попытке подключиться роль будет заблокирована:
[postgres@ServerName ~]$ psql -U grace_user -h ServerName -d postgresPassword for user grace_user:psql: error: connection to server at "ServerName" (<IP-Address>), port 5432 failed: FATAL: password authentication failed for user "grace_user": Role is blocked due to expired password -
Запросите последние записи системного журнала:
[postgres@ServerName ~]$ tail /pgerrorlogs/06/postgresql-{year}-{month}-{day}_*.log2025-07-23 13:50:04.207 MSK [1340109] WARNING: Password was expired. 1 grace logins left2025-07-23 13:50:04.207 MSK [1340125] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user2025-07-23 13:50:14.837 MSK [1340128] WARNING: Password was expired. 0 grace logins left2025-07-23 13:50:23.937 MSK [1340148] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user2025-07-23 13:50:55.716 MSK [1340149] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user2025-07-23 13:50:55.716 MSK [1340149] FATAL: password authentication failed for user "grace_user": Role is blocked due to expired password
Упражнение 2. Использование транспортного пароля
-
Создайте пользователя с временным паролем:
[postgres@ServerName ~]$ psqlPager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help.postgres@postgres=# CREATE USER transport_user WITH TEMPORARY PASSWORD 'Transport_Password@123';CREATE ROLEpostgres@postgres=# ALTER ROLE transport_user LOGIN;ALTER ROLE -
Создайте базу данных, в которой пользователь
transport_userбудет владельцем:postgres@postgres=# CREATE DATABASE db1 WITH OWNER transport_user;CREATE DATABASEpostgres@postgres=# \q -
Подключитесь под созданным на предыдущем шаге пользователем:
[postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgresPassword for user transport_user:Pager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help. -
Запросите список баз данных, доступных пользователю
transport_user:transport_user@postgres=# \lList of databases┌───────────┬────────────────┬──────────┬─────────────┬─────────────┬────────────┬─────────────────┬───────────────────────┐│ Name │ Owner │ Encoding │ Collate │ Ctype │ ICU Locale │ Locale Provider │ Access privileges │├───────────┼────────────────┼──────────┼─────────────┼─────────────┼────────────┼─────────────────┼───────────────────────┤│ db1 │ transport_user │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ │ libc │ ││ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ │ libc │ ││ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ │ libc │ =c/postgres ↵││ │ │ │ │ │ │ │ postgres=CTc/postgres ││ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ │ libc │ =c/postgres ↵││ │ │ │ │ │ │ │ postgres=CTc/postgres │└───────────┴────────────────┴──────────┴─────────────┴─────────────┴────────────┴─────────────────┴───────────────────────┘(4 rows) -
Попробуйте подключиться к базе данных
db1:transport_user@postgres=# \c db1You are now connected to database "db1" as user "transport_user".transport_user@db1=# CREATE SCHEMA test;ERROR: Action is forbidden.HINT: There was a login with a transport password. It is necessary to change the password.Выведено сообщение, что данное действие запрещено пользователю с транспортным паролем.
Единственным доступным действием для такого пользователя является смена пароля.
-
Проверьте наличие сообщения об ошибке в системном журнале:
[postgres@ServerName ~]$ tail /pgerrorlogs/06/postgresql-{year}-{month}-{day}_*.log2025-07-23 14:10:55.716 [1340275] ERROR: Action is forbidden.2025-07-23 14:10:55.716 MSK [1340275] HINT: There was a login with a transport password. It is necessary to change the password.2025-07-23 14:10:55.716 MSK [1340275] STATEMENT: CREATE SCHEMA test; -
Попробуйте сменить транспортный пароль:
[postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgresPassword for user transport_user:Pager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help.transport_user@postgres=# \passwordEnter new password for user "transport_user":Enter it again:ERROR: Password policy got sha256 encrypted password and can't continueHINT: Setting plaintext password with \password command needs psql_encrypt_password = 'on' config option.Setting sha256 hashed password needs password_policy.allow_hashed_password = 'on' config option.Выведено сообщение о недопустимом формате пароля (
PLAIN_TEXT), для использования которого необходимо разрешить хешированные пароли. -
Включите параметры
password_policy.allow_hashed_passwordиpsql_encrypt_passwordв конфигурационном файлеpostgresql.confдля использования хешированных паролей:[postgres@ServerName ~]$ vi $PGDATA/postgresql.confpassword_policy.allow_hashed_password = 'on'psql_encrypt_password = 'on'[UserName@ServerName ~]$ sudo systemctl restart postgresql -
Подключитесь под пользователем
transport_user, используя транспортный пароль:[postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgresPassword for user transport_user:Pager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help. -
Убедитесь, что были приняты новые значения параметров в конфигурационном файле
postgresql.conf:transport_user@postgres=# SHOW psql_encrypt_password;┌───────────────────────┐│ psql_encrypt_password │├───────────────────────┤│ on │└───────────────────────┘(1 row)transport_user@postgres=# SHOW password_policy.allow_hashed_password;┌───────────────────────────────────────┐│ password_policy.allow_hashed_password │├───────────────────────────────────────┤│ on │└───────────────────────────────────────┘(1 row) -
Поменяйте пароль на соответствующий настройкам сложности. В нашем случае, пусть будет строка
Secure_password@123:transport_user@postgres=# \passwordEnter new password for user "transport_user":Enter it again: -
Перезайдите под пользователем
transport_user, но используя новый, заданный вами пароль:[postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgresPassword for user transport_user:Pager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help. -
После успешной авторизации попробуйте подключиться к базе данных
db1:transport_user@postgres=# \c db1You are now connected to database "db1" as user "transport_user". -
Создайте схему в этой базе:
transport_user@db1=# CREATE SCHEMA test;CREATE SCHEMAtransport_user@db1=# \dnList of schemas┌────────┬───────────────────┐│ Name │ Owner │├────────┼───────────────────┤│ public │ pg_database_owner ││ test │ transport_user │└────────┴───────────────────┘(2 rows)transport_user@db1=# \q -
Подключитесь под пользователем
postgres:[postgres@ServerName ~]$ psqlPager is used for long output.Border style is 2.Line style is unicode.psql (15.5)Type "help" for help. -
Убедитесь, что пароль перестал был транспортным (значение поля
istransportpassword=f(false)):postgres@postgres=# SELECT * FROM pp_password WHERE roloid = to_regrole('transport_user')\gx┌─[ RECORD 1 ]────────┬───────────────────────────────┐│ roloid │ transport_user ││ failcounter │ 0 ││ lastfailtime │ ││ gracesuccesscounter │ 0 ││ lastsuccesstime │ 2025-07-23 14:33:46.886204+03 ││ createtime │ 2025-07-23 14:27:23.177726+03 ││ unblockexpirytime │ ││ istransportpassword │ f │└─────────────────────┴───────────────────────────────┘