Перейти к основному содержимому

Задание 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-периода​

  1. Создайте роль grace_user, установив 10 секунд (10 sec) в качестве grace-периода:

    postgres@postgres=# CREATE ROLE grace_user PASSWORD '#securePassword456';
    CREATE ROLE
    postgres@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
  2. Включите парольные политики в конфигурационном файле postgresql.conf, как делали в задании 2.

  3. Подождите 10 секунд и попробуйте подключиться пользователем grace_user к серверу со старым паролем:

    [postgres@ServerName ~]$ psql -h <IP-Address> -U grace_user -d postgres
    Password for user grace_user:

    WARNING: Password was expired. 1 grace logins left
    Pager 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

    Подключение осуществлено, выведено сообщение об оставшемся количестве возможных подключений по старому паролю.

  4. Подключайтесь снова с прежним паролем, пока не исчерпаете возможности подключиться по истекшему паролю:

    [postgres@ServerName ~]$ psql -U grace_user -h ServerName -d postgres
    Password for user test_user:

    WARNING: Password was expired. 0 grace logins left
    Pager 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 postgres
    Password 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
  5. Запросите последние записи системного журнала:

    [postgres@ServerName ~]$ tail /pgerrorlogs/06/postgresql-{year}-{month}-{day}_*.log
    2025-07-23 13:50:04.207 MSK [1340109] WARNING: Password was expired. 1 grace logins left
    2025-07-23 13:50:04.207 MSK [1340125] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user
    2025-07-23 13:50:14.837 MSK [1340128] WARNING: Password was expired. 0 grace logins left
    2025-07-23 13:50:23.937 MSK [1340148] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user
    2025-07-23 13:50:55.716 MSK [1340149] LOG: AUDIT: SESSION, CONNECTION, FAILED,database = postgres,user = grace_user
    2025-07-23 13:50:55.716 MSK [1340149] FATAL: password authentication failed for user "grace_user": Role is blocked due to expired password

Упражнение 2. Использование транспортного пароля​

  1. Создайте пользователя с временным паролем:

    [postgres@ServerName ~]$ psql
    Pager 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 ROLE
    postgres@postgres=# ALTER ROLE transport_user LOGIN;
    ALTER ROLE
  2. Создайте базу данных, в которой пользователь transport_user будет владельцем:

    postgres@postgres=# CREATE DATABASE db1 WITH OWNER transport_user;
    CREATE DATABASE
    postgres@postgres=# \q
  3. Подключитесь под созданным на предыдущем шаге пользователем:

    [postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgres
    Password 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.
  4. Запросите список баз данных, доступных пользователю transport_user:

    transport_user@postgres=# \l
    List 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)
  5. Попробуйте подключиться к базе данных db1:

    transport_user@postgres=# \c db1
    You 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.

    Выведено сообщение, что данное действие запрещено пользователю с транспортным паролем.

    Единственным доступным действием для такого пользователя является смена пароля.

  6. Проверьте наличие сообщения об ошибке в системном журнале:

    [postgres@ServerName ~]$ tail /pgerrorlogs/06/postgresql-{year}-{month}-{day}_*.log
    2025-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;
  7. Попробуйте сменить транспортный пароль:

    [postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgres
    Password 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=# \password
    Enter new password for user "transport_user":

    Enter it again:

    ERROR: Password policy got sha256 encrypted password and can't continue
    HINT: 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), для использования которого необходимо разрешить хешированные пароли.

  8. Включите параметры password_policy.allow_hashed_password и psql_encrypt_password в конфигурационном файле postgresql.conf для использования хешированных паролей:

    [postgres@ServerName ~]$ vi $PGDATA/postgresql.conf
    password_policy.allow_hashed_password = 'on'
    psql_encrypt_password = 'on'
    [UserName@ServerName ~]$ sudo systemctl restart postgresql
  9. Подключитесь под пользователем transport_user, используя транспортный пароль:

    [postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgres
    Password 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.
  10. Убедитесь, что были приняты новые значения параметров в конфигурационном файле 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)
  11. Поменяйте пароль на соответствующий настройкам сложности. В нашем случае, пусть будет строка Secure_password@123:

    transport_user@postgres=# \password
    Enter new password for user "transport_user":

    Enter it again:
  12. Перезайдите под пользователем transport_user, но используя новый, заданный вами пароль:

    [postgres@ServerName ~]$ psql -U transport_user -h ServerName -d postgres
    Password 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.
  13. После успешной авторизации попробуйте подключиться к базе данных db1:

    transport_user@postgres=# \c db1
    You are now connected to database "db1" as user "transport_user".
  14. Создайте схему в этой базе:

    transport_user@db1=# CREATE SCHEMA test;
    CREATE SCHEMA
    transport_user@db1=# \dn
    List of schemas
    ┌────────┬───────────────────┐
    │ Name │ Owner │
    ├────────┼───────────────────┤
    │ public │ pg_database_owner │
    │ test │ transport_user │
    └────────┴───────────────────┘
    (2 rows)
    transport_user@db1=# \q
  15. Подключитесь под пользователем postgres:

    [postgres@ServerName ~]$ psql
    Pager is used for long output.
    Border style is 2.
    Line style is unicode.
    psql (15.5)

    Type "help" for help.
  16. Убедитесь, что пароль перестал был транспортным (значение поля 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 │
    └─────────────────────┴───────────────────────────────┘

Подведем итоги​

Вопрос 1

Вопрос 1: Для чего нужен grace-период? Выберите все подходящие утверждения:

Вопрос 2

Вопрос 2: Какой параметр отвечает за время grace-периода?

Вопрос 3

Вопрос 3: Для чего используется транспортный пароль? (один верный ответ)