Парольные политики#
Парольные политики — это набор правил, регулирующих создание, использование и проверку паролей. Механизм проверки паролей реализуется с помощью утилит или самой системой.
Основные функции механизма:
расширение функциональности авторизации и смены пароля пользователя в части проверки пароля;
создание транспортного (временного) пароля;
хранение истории паролей роли;
сбор и хранение статистической информации о пароле роли;
назначение роли парольной политики;
управление парольной политикой:
создание, удаление и изменение политики;
активация и деактивация политики;
создание, удаление и изменение алгоритма проверки пароля.
Настройка#
Настройки механизма хранятся в файле конфигурации и таблице pg_pp_policy (в приоритете заполненные параметры в таблице). В зависимости от типа конфигурации сервера, парольные политики хранятся в различных файлах:
для standalone-конфигурации — в файле
$PGDATA/postgresql.conf;для кластерной конфигурации — в файле
/etc/pangolin-manager/postgres.yml.
Подробнее о параметрах в подразделе «Конфигурационные параметры» данного документа.
Политики не имеют имени, поэтому отображается идентификатор (roloid) соответствующей роли (см. раздел «Таблицы» документа «Справочное руководство»).
Внимание
При подключении через Pangolin Pooler с включенной сквозной аутентификацией проверка пароля выполняется только при первом подключении, что ограничивает политику по срокам действия пароля и количеству подключений.
Внимание
При активированной защите от привилегированных пользователей параметры политик могут храниться в HashiCorp Vault. Подробнее ознакомиться с решением HashiCorp Vault можно в разделе «HashiCorp Vault и KMS-заменитель».
Зависимости#
Для работы механизма необходимы:
библиотека OpenSSL;
утилита проверки сложности пароля
zxcvbn.
Примечание:
Указанное ПО включено в дистрибутив СУБД Pangolin.
Основные параметры#
Параметр |
Описание |
|---|---|
|
Включает ( |
|
Включает ( |
|
Управляет засекречиванием пароля при передаче от клиента к базе данных. |
Внимание
Изменение параметра password_policies_enable требует перезагрузки сервера (restart) для применения изменений.
Обязательные настройки парольной политики#
Обязательные настройки хранятся в таблице pg_pp_policy. Все настройки для парольной политики имеют аналог в конфигурационном файле, это необходимо для возможности задания значений по умолчанию при создании пользователя (см. подраздел «Конфигурационные параметры»). Приоритетными считаются значения в таблице pg_pp_policy (подробнее в разделе «Вычислении значений настроек для парольной политики пользователя»).
Функциональность |
Обязательный параметр |
Зависимые параметры |
|---|---|---|
Хранение паролей |
Один из: |
- |
Изменение пароля |
|
- |
Синтаксическая проверка пароля |
|
|
Проверка вхождения пароля в черный список |
|
- |
Проверка пароля библиотекой |
|
|
Пользовательская PSQL функция проверки пароля |
|
- |
Аутентификация |
|
- |
Конфигурационные параметры#
В данном разделе более подробно описаны параметры файла postgresql.conf/postgres.yml и их значения по умолчанию.
Параметр |
Описание |
Тип |
POSIX шаблон |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|
|
Включение/выключение парольной политики |
|
|
|
|
|
Включение/выключение использования настроек из |
|
|
|
- |
|
Засекречивание пароля при передаче от клиента к БД |
|
|
- |
- |
|
Включение механизма исключения повторных попыток подключения psql |
|
|
|
- |
|
Разрешить задание пароля в виде хеша |
|
|
|
- |
Рекомендации по заданию стойких паролей#
Пароль считается стойким, если он удовлетворяет следующим условиям:
должен изменяться не менее 1 раза в 80 дней с момента последнего изменения;
должен быть сложен (обязательно использование строчных и прописных букв и цифр);
длина пароля — минимум 12 символов;
должен быть уникален, недопустимо использование одного и того же пароля для нескольких УЗ одного пользователя;
не должен содержать имя УЗ пользователя или какую-либо его часть;
в случае компрометации пароля необходимо незамедлительно его сменить;
должен храниться в засекреченном виде.
Пароли хранятся в виде хешей для всех методов аутентификации, кроме PLAIN. Метод PLAIN не рекомендуется к использованию.
Не рекомендуется передавать или хранить пароль в открытом виде в:
файле
pgpass;строке параметров подключения (Connection string);
переменной окружения
PGPASSWORD.
Настроечные параметры, управляемые администраторами безопасности через KMS в режиме защищенного конфигурирования, находятся в таблице документа «Настроечные параметры».
Парольные политики для Pangolin по умолчанию настроены следующим образом:
выключены для пользователей, проходящих внешнюю аутентификацию: LDAP;
для локальных УЗ включено использование библиотеки zxcvb;
для специальных УЗ выключены проверки времени жизни пароля:
SELECT * FROM set_role_policies('masteromni', max_age('0 sec'), min_age('0 sec'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('zabbix_oasubd', max_age('0 sec'), min_age('0 sec'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('monitoring_php', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('auditor', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('pstgcmdb', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('as_TUZ', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('as_admin', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('db_admin', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3')); SELECT * FROM set_role_policies('postgres', max_age('0'), min_age('0'), check_syntax('1'), policy_enable('1'), lockout('0'), illegal_values('1'), use_password_strength_estimator('1'), password_strength_estimator_score('3'));
Настройка хранения паролей#
Параметр |
Описание |
Тип |
POSIX шаблон |
Ограничение значения |
Значение по умолчанию |
Специальные значения параметров |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|---|
|
Время в секундах, в течение которого старый пароль сохраняется, и попытка сменить пароль на совпадающий со старым заканчивается ошибкой |
|
|
неотрицательное |
|
- |
|
|
Максимальное количество сохраненных старых паролей |
|
[0-1000] |
0-1000 |
|
|
|
Примечание
Если задан параметр password_policy.reuse_time, то параметр password_policy.in_history не используется.
Время жизни пароля#
Параметр |
Описание |
Тип |
POSIX шаблон |
Ограничение значения |
Значение по умолчанию |
Специальные значения параметров |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|---|
|
Время жизни пароля в секундах |
|
|
неотрицательное |
|
|
|
|
Минимальное время между изменениями пароля |
|
|
неотрицательное |
|
|
|
|
Максимальное количество аутентификаций после истечения срока действия пароля |
|
[0-1000] |
0-1000 |
|
- |
|
|
Время, в течение которого пароль остается рабочим после окончания срока его действия |
|
|
неотрицательное |
|
|
|
|
Время до истечения пароля, при котором выводится предупреждение |
|
|
неотрицательное |
|
|
|
Поведение при неудачной аутентификации#
Параметр |
Описание |
Тип |
POSIX шаблон |
Ограничение значения |
Значение по умолчанию |
Специальные значения параметров |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|---|
|
Блокировка аккаунта при достижении максимума неверных попыток аутентификации |
|
|
|
|
- |
|
|
Максимальное количество неверных попыток аутентификации |
|
[1-1000] |
1-1000 |
|
- |
|
|
Время, после которого количество неверных попыток сбрасывается |
|
|
>= 0 |
|
|
|
|
Время блокировки аккаунта |
|
|
неотрицательное |
24 hours |
|
|
Синтаксические проверки пароля#
Параметр |
Описание |
Тип |
Ограничение значения |
Значение по умолчанию |
Специальные значения параметров |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|
|
Включение синтаксической проверки пароля |
|
|
|
– |
|
|
Минимальное количество цифр в пароле |
|
0-1000 |
|
|
|
|
Минимальная длина пароля |
|
0-1000 |
|
|
|
|
Минимальное количество букв в пароле |
|
0-1000 |
|
|
|
|
Минимальное количество специальных символов |
|
0-1000 |
|
|
|
|
Минимальное количество прописных букв |
|
0-1000 |
|
|
|
|
Минимальное количество строчных букв |
|
0-1000 |
|
|
|
|
Максимальное количество повторяющихся символов |
|
0-1000 |
|
|
|
Проверка максимального времени неактивности пользователя#
Параметр |
Описание |
Тип |
Ограничение значения |
Значение по умолчанию |
Специальные значения параметров |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|
|
Запоминать ли время последней аутентификации |
|
|
|
– |
|
|
Время последней аутентификации, после которого аккаунт блокируется |
|
неотрицательное |
|
|
|
Использование библиотеки zxcvbn#
Параметр |
Описание |
Тип |
POSIX шаблон |
Ограничение значения |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|
|
Включение использования библиотеки |
|
|
|
|
|
|
Минимальная оценка сложности пароля |
|
[0-4] |
0-4 |
|
|
Использование пользовательской функции проверки пароля#
Параметр |
Описание |
Тип |
POSIX шаблон |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|
|
Пользовательская функция проверки пароля |
|
|
- |
|
Проверка вхождения пароля в черный список#
Параметр |
Описание |
Тип |
Ограничение значения |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|
|
Проверка, что пароль не входит в список часто используемых |
|
|
|
|
Настройка кеширования#
Параметр |
Описание |
Тип |
POSIX шаблон |
Ограничение значения |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|---|---|
|
Интервал сохранения данных кеша на диск |
|
|
|
|
- |
|
Размер инициализированного кеша парольных политик |
|
|
|
|
- |
|
Предполагаемый максимальный размер кеша |
|
|
|
|
- |
|
Ограничение сверху на размер кеша |
|
|
|
|
- |
Параметры управления транспортными паролями#
Параметр |
Описание |
Тип |
Значение по умолчанию |
Аналог в pg_pp_policy |
|---|---|---|---|---|
|
При значении |
|
|
- |
|
Определяет время жизни транспортного пароля |
|
|
|
|
Определяет тип пароля (транспортный или нет) для указанных ТУЗ |
|
|
- |
Таблицы#
В механизме управления парольной политикой используются таблицы:
pg_pp_history- таблица ранее использованных паролей;pg_pp_password- Таблица с информацией о текущем пароле;pg_pp_policy- таблица с информацией о парольных политиках.
Представления#
Для просмотра информации о состоянии роли и кеша парольных политик созданы следующие представления:
pp_password_detailed— для мониторинга состояния ролей;pp_password— для просмотра кеша парольных политик.
Примечание
В случае обращения к выводу view при отключенных парольных политиках (password_policies_enable = 'off') вернется пустая таблица, а также будет выведено предупреждение (WARNING).
Функции#
Управление парольными политиками осуществляется соответствующими функциями:
recognize_password_policy- отображение парольных политик, примененных к роли;select_all_password_policies- отображение всех активных политик;
Транспортный пароль#
Транспортный (временный) пароль нужен для аутентификации пользователя с ограничениями на все действия, кроме:
смены своего пароля;
чтения из таблиц, расположенных в схемах
pg_catalogиinformation_schema;вызовов функций, расположенных в
pg_catalogиinformation_schema;использования
SET;использования
SET ROLE TO none;использования
SET SESSION AUTHORIZATION;использования
SHOW;использования
LISTEN/UNLISTEN;использования
PREPARE/EXECUTE.
Когда администратор меняет пароль пользователю, новый пароль автоматически отмечается как транспортный. При авторизации с транспортным паролем для снятия ограничений пользователь должен сменить пароль на постоянный (команда ALTER ROLE/USER ... WITH PASSWORD), при этом соединение должно быть открыто именно тем пользователем, которому меняется пароль. Такое условие нужно для того, чтобы суперпользователь не смог сменить пароль другому пользователю с транспортного на постоянный, переключившись на другого пользователя с помощью SET SESSION AUTHORIZATION или SET ROLE. При попытке любого другого действия выводится сообщение о запрете по причине авторизации с транспортным паролем. В таком случае необходимо сменить пароль на постоянный.
Схема блокировки запроса с транспортным паролем:

Пароль отмечается как транспортный или явным указанием при его задании, или автоматически при смене пароля другим пользователем. Возможность автоматической отметки определяется параметром (password_policy.transport_password_mark_automatic) конфигурации сервера БД (см. Параметры управления транспортными паролями).
Действие по смене пароля с транспортного на постоянный попадает в лог аудита независимо от его настроек.
Управление#
Создание парольной политики пользователя#
Создание парольной политики для пользователя происходит с помощью выполнения PL/pgSQL функции set_role_policies. При этом настройки не будут применены без их активации с помощью функции enable_policy.
Примечание
Создание и активацию настроек парольной политики можно осуществить одним запросом. Для этого при создании парольной политики для пользователя нужно указать параметр policy_enable(1::boolean). В таком случае новые параметры парольной политики начнут действовать сразу.
Пример создания парольной политики:
Создайте пользователя:
CREATE USER username_3 WITH ENCRYPTED PASSWORD <password>Вывод:
CREATE ROLEСоздайте парольную политику для пользователя:
Пример запроса:
SELECT * FROM set_role_policies('username_2', check_syntax(1::boolean), min_length(12), alpha_numeric(3), min_special_chars(2), min_uppercase(2), policy_enable(1::boolean));Вывод:
-[ RECORD 1 ]---------------------+------- roleid | username_2 reuse_time | in_history | max_age | min_age | grace_login_limit | grace_login_time_limit | expire_warning | lockout | lockout_duration | max_failure | failure_count_interval | check_syntax | t min_length | 12 illegal_values | alpha_numeric | 3 min_alpha_chars | min_special_chars | 2 min_uppercase | 2 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 |
Проверить успешность применение заданной политики для пользователя можно с помощью функции recognize_password_policy, либо протестировать с помощью процесса замены пароля.
Вычисление значений настроек для парольной политики пользователя#
Алгоритм вычисления парольной политики пользователя сводится к заполнению всех полей таблицы pg_pp_policy, за исключением поля roloid:
Из таблицы
pg_pp_policyсобираются все заданные настройки для конкретного пользователя (значение неNULL) по идентификатору.Ищутся все роли, в которые входит данный пользователь.
Примечание:
Чтобы пользователь мог наследовать политики у родителей, он должен иметь настройку
INHERIT.Для каждой найденной роли по идентификатору роли из таблицы
pg_pp_policyвыбираются настройки по условию:настройка не была выбрана на шаге 1;
значение настройки не
NULL.
Примечание:
Исключение — все заданные значения параметра
customfunctionсохраняются в исходном порядке, формируя список функций на выполнение. Соответствующие функции будут последовательно применены в указанном параметре.Если на шаге 3 для одной настройки было найдено несколько значений, то выбирается наиболее строгое ограничение. Ниже указаны параметры и способ определения строгости значения (от менее к более строгому):
reusetime;inhistory;minage;expirewarning;lockoutduration;failurecountinterval;minlength;alphanumeric;minalphachars;minspecialchars;minuppercase;minlowercase;passwordstrengthestimatorscore.
От более к менее строгому:
maxage;graceloginlimit;gracelogintimelimit;maxfailure;maxrptchars;maxinactivity.
Если
password_policy.deny_default=off, то:Настройки, которые остались не заданы, заполняются значениями параметров из конфигурационного файла
postgresql.conf/postgres.yml.Настройки, которые остались не заданы, заполняются значениями по умолчанию для параметров из конфигурационного файла
postgresql.conf/postgres.yml.
Производится проверка на взаимозависимость настроек:
Настройка
Условие, при котором не работают зависимые настройки
Зависимые настройки
policyenable= falseВсе остальные
reusetime> 0inhistorymaxage= NULL,= 0graceloginlimit,gracelogintimelimit,expirewarninglockout= NULL,= falselockoutduration,maxfailure,failurecountintervalchecksyntax= NULL,= falseminlength,alphanumeric,minalphachars,minspecialchars,minuppercase,minlowercase,maxrptcharstracklogin= NULL,= falsemaxinactivityusepasswordstrengthestimator= NULL,= falsepasswordstrengthestimatorscore
Если
password_policy.deny_default=on, то проверяется, что заданы все обязательные настройки.
Разблокировка пользователя#
Есть ситуации (превышение количества неудачных аутентификаций, длительная неактивность пользователя и другие), при которых пароль становится неактивным, а роль блокируется. При попытке подключения под заблокированной учетной записью, будет выведено сообщение:
psql: FATAL: Role is blocked due to fail authentication attempts
FATAL: Role is blocked due to fail authentication attempts
Для разблокировки пользователя, администратору потребуется воспользоваться функцией unblock_role.
Рассмотрим пример блокировки пользователя по причине неверно введенных паролей большего количества раз, чем указано в параметре password_policy.max_failure.
Действия по разблокировке пользователя:
Выведите текущее состояние пользователя:
SELECT * FROM pp_password_detailed WHERE roloid = to_regrole('username');Пример вывода:
-[ RECORD 1 ]----------------------------+----------------------------------- roloid | username failcounter | 6 lastfailtime | 2022-07-19 0{major_version}:00:05.097145+03 gracesuccesscounter | 0 lastsuccesstime | 2022-07-18 13:36:05.033878+03 createtime | 2022-07-18 07:49:47.175947+03 unblockexpirytime | istransportpassword | f is_auth_available | f is_blocked | t check_policy_for_max_age | t check_policy_for_max_age_text | OK check_policy_for_lockout | t check_policy_for_lockout_text | OK check_policy_for_inactivity_check | t check_policy_for_inactivity_check_text | OK check_policy_for_password_check | t check_policy_for_password_check_text | OK check_lockout | f check_lockout_text | Role was blocked with 6 fail authentification attempts. Last fail at 19.07.2022 0{major_version}:00:05 Role wasnt unblocked. check_inactivity | t check_inactivity_text | OK. Inactivity check is off. check_password_age | t check_password_age_text | OK. Max_age check is off. check_policy_for_transport_password | t check_policy_for_transport_password_text | OK check_transport_password_life_time | check_transport_password_life_time_text |Пользователь заблокирован, на это указывают поля:
failcounter=6;lastfailtime=“2022-07-19 0{major_version}:00:05.097145+03“;is_blocked=“t“;в поле
check_lockout_textтакже сообщение о том, что роль была заблокирована в результате 6 неудачных попыток аутентификации.
Выполните разблокировку пользователя:
SELECT unblock_role('username');Проверьте состояние пользователя после разблокировки:
SELECT * FROM pp_password_detailed WHERE roloid = to_regrole('username');Пример вывода:
-[ RECORD 1 ]----------------------------+----------------------------------- roloid | username failcounter | 6 lastfailtime | 2022-07-19 0{major_version}:00:05.097145+03 gracesuccesscounter | 0 lastsuccesstime | 2022-07-18 13:36:05.033878+03 createtime | 2022-07-18 07:49:47.175947+03 unblockexpirytime | 2022-07-19 0{major_version}:05:43.197962+03 istransportpassword | f is_auth_available | t is_blocked | f check_policy_for_max_age | t check_policy_for_max_age_text | OK check_policy_for_lockout | t check_policy_for_lockout_text | OK check_policy_for_inactivity_check | t check_policy_for_inactivity_check_text | OK check_policy_for_password_check | t check_policy_for_password_check_text | OK check_lockout | t check_lockout_text | OK. Role was unblocked at 19.07.2022 0{major_version}:05:43Role was blocked with 6 fail authentification attempts. check_inactivity | t check_inactivity_text | OK. Inactivity check is off. check_password_age | t check_password_age_text | OK. Max_age check is off. check_policy_for_transport_password | t check_policy_for_transport_password_text | OK check_transport_password_life_time | check_transport_password_life_time_text |Поле
check_lockout_textсодержит сообщение о том, что роль была разблокирована.
Замена транспортного пароля ТУЗ#
После окончания процесса развертывания СУБД Pangolin необходимо сменить транспортный пароль ТУЗ на постоянный.
Примечание
До тех пор, пока транспортный пароль для ТУЗ не будет изменен на новый постоянный (в соответствии с используемыми парольными политиками), из всех возможных действий для ТУЗ будет доступна только авторизация с последующей сменой пароля.
Установить транспортный (temporary) пароль ТУЗ может пользователь с правами групповой роли db_admin.
Для этого необходимо выполнить вход Администратором в консоль и переключиться на роль
db_admin:SET ROLE db_admin;Выполнить команду для установки транспортного (temporary) пароля ТУЗ:
ALTER USER 'name_tuz' WITH TEMPORARY PASSWORD '<password>';Далее необходимо подключиться ТУЗ самостоятельно, с полученным транспортным паролем, и сменить пароль на постоянный (соединение должно быть открыто именно тем пользователем, которому меняется пароль).
Пример подключения ТУЗ к БД и смена пароля:
=> psql -U 'name_tuz' -d 'name db' -p 5433Вводим полученный транспортный пароль
Password for user 'name_tuz': psql (13.4) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help.Смена пароля:
ALTER USER 'name_tuz' WITH ENCRYPTED PASSWORD '<password>'; ALTER ROLE
Диагностика ошибок#
В этом разделе указаны возможные ошибки, которые могут возникнуть в случае блокировки пользователя (аварийная ситуация). Ошибки пишутся в журнал сообщений или в вывод приложения, через которое происходит доступ к БД (например, при попытке подключения).
Справочник журнальных сообщений#
Сообщение |
Расшифровка |
Решение |
|---|---|---|
|
Пользователь заблокирован из-за превышения счетчика неудачных аутентификаций |
Пользователь будет разблокирован, когда пройдет |
|
Пользователь заблокирован из-за просроченного пароля |
Сменить пароль пользователя |
|
Пользователь заблокирован из-за долгой неактивности |
Пользователь может быть разблокирован с помощью команд |
|
Предупреждение об оставшемся времени до обязательной смены пароля |
|
|
Время жизни пароля превышено. Осталось <число> входов, после которых пользователь будет заблокирован |
|
|
Время жизни пароля превышено. Остался <интервал>, по истечении которого пользователь будет заблокирован |
Сценарии использования#
Активация функциональности парольной политики#
Установите значение параметра
password_policies_enable: 'on'в конфигурационном файлеpostgresql.conf/postgres.yml.Для применения настроек перезапустите сервер:
pg_ctl restartСоздайте пользователя с простым паролем:
CREATE USER username_1 WITH ENCRYPTED PASSWORD '<simple_password>';Пример вывода:
ERROR: Syntax check fail: minimum length for password is 16 Syntax check fail: minimum number of special characters for password is 1 Syntax check fail: minimum number of uppercase characters for password is 1В результате создания пользователя с паролем, возникла ошибка синтаксической проверки пароля на несоответствие парольным политикам:
минимальная длина пароля - 16 символов;
минимальное количество спецсимволов - 1 символ;
минимальное количество прописных букв - 1 буква.
Причина возникновения данной ошибки в активации парольных политик и включенности механизма управления ими. Параметры для проверки берутся из конфигурационного файла (столбец «Значения по умолчанию»).
Создайте пользователя с паролем, удовлетворяющим настройкам парольной политики:
CREATE USER username_1 WITH ENCRYPTED PASSWORD '<hard_password>';Вывод:
CREATE ROLEПользователь успешно создан с заданным паролем, так как он соответствует требованиям парольной политики, заданным в конфигурационном файле.
Создание и активация парольной политики для пользователя#
Пример создания парольной политики описан в разделе «Управление».
Просмотр примененных настроек парольной политики для пользователя#
При создании пользователя или роли в базе данных все настройки парольной политики для этого пользователя берутся автоматически из конфигурационного файла (при условии, что он не наследует права от какой-либо роли). Это можно проверить, посмотрев детальную информацию о парольной политике для конкретного пользователя:
Создайте пользователя:
CREATE USER username_3 WITH ENCRYPTED PASSWORD <password>;Вывод:
CREATE ROLEВыведите информацию о примененной парольной политики для созданного пользователя:
SELECT * FROM recognize_password_policy_detailed('username_3');Пример вывода:
policy_name | value | source_type | source ----------------------------------+----------+-------------+-------- reuse_time | 365 days | config | in_history | | | max_age | 00:00:00 | config | min_age | 00:00:00 | config | grace_login_limit | | | grace_login_time_limit | | | expire_warning | | | lockout | true | config | lockout_duration | 24:00:00 | config | max_failure | 6 | config | failure_count_interval | 00:00:00 | config | check_syntax | true | config | min_length | 16 | config | illegal_values | true | config | alpha_numeric | 3 | config | min_alpha_chars | 0 | config | min_special_chars | 1 | config | min_uppercase | 1 | config | min_lowercase | 0 | config | max_rpt_chars | 0 | config | track_login | false | config | max_inactivity | | | use_password_strength_estimator | true | config | password_strength_estimator_score | 3 | config | custom_function | 0 | config | transport_password_life_time | 00:00:00 | config | (26 rows)Поля
source_typeиsourceпоказывают, откуда берется значение для конкретной политики. В приведенном примере видно, что для пользователя применяются параметры парольной политики, взятые из конфигурационного файла (source_type=config).
Просмотр применения метки транспортного пароля#
При просмотре представления pp_password для пользователя с транспортным паролем значение поля istransportpassword равняется True:
SELECT * FROM pp_password WHERE roloid = to_regrole('user2');
-[ RECORD 1 ]-------+-----------------------------
roloid | user2
failcounter | 0
lastfailtime |
gracesuccesscounter | 0
lastsuccesstime |
createtime | 2022-07-14 07:38:35.80058+03
unblockexpirytime |
istransportpassword | t
Деактивация функциональности парольной политики#
Установите значение параметра
password_policies_enable: 'off'в конфигурационном файлеpostgresql.conf/postgres.yml.Для применения настроек перезапустите сервер:
pg_ctl restartСоздайте пользователя с простым паролем:
CREATE USER username_2 WITH ENCRYPTED PASSWORD '123';Вывод:
CREATE ROLEПри создании пользователя ошибка не возникла, поскольку проверка пароля не производится из-за отключенного механизма управления парольной политикой.
Генерация и установка постоянного пароля пользователя (включая ТУЗ)#
Генерация пароля осуществляется функцией rotate_password в соответствии с парольной политикой.
Функция генерации пароля rotate_password создает новый пароль для выбранного пользователя и:
возвращает его в качестве результата;
изменяет его в БД.
Входные параметры функции rotate_password:
(обязательный)
Oidили имя пользователя;(не обязательный) длина пароля. При отсутствии будет сгенерирован по минимальной длине пароля согласно парольным политикам (случайная длина до 5 символов).
Выходной параметр: сгенерированный пароль.
Пример запроса генерации пароля для пользователя User1:
SELECT * FROM rotate_password('User1');
Настройка#
Функция генерации пароля доступна при установленном расширении psql_rotate_password.
Откройте конфигурационный файл
postgersql.conf.Добавьте или измените следующие параметры:
rotate_password_enable = 'on'— включение функции генерации пароля;rotate_password_num_rounds:'20'— количество попыток генерации пароля;rotate_password.valid_roles = 'user1, user2, user3'— список пользователей (через запятую), для которых разрешена генерация пароля.
При изменении параметров перечитайте конфигурацию (reload).
Диагностика ошибок#
При использовании функции могут возникать следующие ошибки:
Исчерпано количество попыток: превышено значение параметра
rotate_password_num_rounds;Пользователь не входит в список ролей: убедитесь, что пользователь указан в параметре
rotate_password.valid_roles;Невозможно сгенерировать подходящий пароль: комбинация синтаксических требований и длины пароля не позволяет создать соответствующий требованиям пароль.
Сценарии использования#
Установите значение („username“) параметра
rotate_password.valid_rolesв конфигурационном файле. Для применения изменений перечитайте конфигурацию (reload).Создайте политики для пользователя. В примере указаны значения для параметров по умолчанию, при необходимости вы можете их изменить:
SELECT * FROM set_role_policies('username', policy_enable(1::boolean), check_syntax(1::boolean), min_length(16), illegal_values(0::boolean), alpha_numeric(5), min_alpha_chars(1), min_special_chars(1), min_uppercase(1), min_lowercase(1), max_rpt_chars(2), use_password_strength_estimator(0::boolean), transport_password_life_time('3 days'));Пример вывода:
-[ RECORD 1 ]---------------------+------- roleid | username reuse_time | in_history | max_age | min_age | grace_login_limit | grace_login_time_limit | expire_warning | lockout | lockout_duration | max_failure | failure_count_interval | check_syntax | t min_length | 16 illegal_values | f alpha_numeric | 5 min_alpha_chars | 1 min_special_chars | 1 min_uppercase | 1 min_lowercase | 1 max_rpt_chars | 2 policy_enable | t track_login | max_inactivity | use_password_strength_estimator | f password_strength_estimator_score | custom_function | transport_password_life_time | 3 daysСгенерируйте пароль для пользователя:
SELECT * FROM rotate_password('username');Пример вывода:
rotate_password -------------------- x3<2BTf?ma3P119_fs (1 row)
Обеспечение ротации секретов ТУЗ#
Описание#
При смене пароля, пользователь, на определенное настройками время (grace-период), может подключаться к Pangolin и с использованием старого пароля, и с использованием нового пароля, по выбору. Этот механизм позволяет осуществлять автоматическую ротацию паролей ТУЗ, которые используют приложения, сохраняя их доступность. После ротации паролей ТУЗ, приложения продолжают работу с Pangolin, используя старый пароль, который необходимо обновить в течении grace-периода.
Внимание!
Настройка grace-периода применяется в порядке приоритета:
Низкий приоритет — конфигурационный файл
postgresql.conf.Средний приоритет — парольные политики.
Высокий приоритет — сессионные параметры пользователя.
Настройка функциональности в процессе установки Pangolin#
Настройка grace-периода в процессе установки кластера Pangolin осуществляется в пользовательском конфигурационном файле (custom_config_sample.yml).
За включение функциональности отвечает параметр enable в yaml-словаре grace_authid. Значение периода настраивается параметром period.
Параметр skip_error позволяет контролировать ошибки в процессе создания grace-пароля (см. раздел «Обновление пароля»).
Пример настроек из файла custom_config_sample.yml:
grace_authid:
enable: 'off'
period: '0'
skip_error: 'off'
Параметр |
Значение по умолчанию |
Описание |
|---|---|---|
|
|
Включение функциональности grace-периода. По умолчанию функциональность будет выключена |
|
|
Период валидности grace-пароля (в секундах, минутах, часах и т.д. Например, |
|
|
Завершение запроса на обновление пароля пользователя без ошибки, если grace-пароль не может быть сохранен. По умолчанию запрос завершается с ошибкой, если grace-пароль не может быть сохранен |
Подробнее о процессе установки Pangolin читайте в документе «Руководство по установке», раздел «Установка».
Процесс настройки grace-периода в процессе установки Pangolin#
Настройте параметры grace-периода в пользовательском конфигурационном файле.
grace_authid_enable: on grace_authid_period: 300Запустите установку/обновление кластера Pangolin.
Настройка функциональности на запущенном кластере Pangolin#
Настройка осуществляется в конфигурационном файле postgresql.conf.
Включение и отключение функциональности настраивается параметром grace_authid_enable, который может принимать значения on (включен) и off (выключен). По умолчанию функциональность выключена (off).
Grace-период настраивается параметром grace_authid_period (в секундах, минутах, часах и т.д. Например, 5s или 5 seconds). Период применяется ко всем ролям, если функциональность включена и нет отдельной настройки параметров сессии или парольных политик. Значение периода по умолчанию равно нулю. Чтобы явно обозначить намерение включить функциональность для всех пользователей, необходимо установить значение отличное от нуля.
В результате запросов на обновление пароля (см. раздел «Обновление пароля») будет возвращаться ошибка, если grace-пароль не может быть сохранен, и параметр grace_skip_error установлен в значение off (выключен). Если параметр grace_skip_error установлен в значение on (включен), то запросы на обновление пароля будут успешны, даже если grace-пароль не может быть сохранен. По умолчанию параметр выключен.
После изменения настроек в файле postgresql.conf, необходимо перечитать конфигурационные файлы. Например, командой reload.
Настройка функциональности на время сеанса роли#
Значение grace-периода можно задать, изменив значение по умолчанию конфигурационной переменной, с помощью формы запроса ALTER ROLE ... SET grace_authid_period=значение. Значение задается в секундах, будет распространяться на сеансы роли.
Процесс настройки grace-периода на время сеанса роли#
Выполните команду изменения значения параметра для роли. Пример команды:
ALTER USER test_user SET grace_authid_period=1200;
Настройка функциональности в парольных политиках#
Значения grace-периода для роли можно так же задать при помощи парольных политик. Использование двойного пароля может работать без дополнительной настройки в парольных политиках, в этом случае в расчетах будет учитываться общий grace-период, указанный в конфигурации, или сессионный параметр.
Параметр grace_authid_period в парольных политиках позволяет для отдельной роли настроить свой grace-период, отличный от того, что указан в конфигурационном файле.
Если у пользователя задано несколько ролей с разными значениями grace-периода в парольных политиках, то среди них будет выбрано минимальное значение.
Чтобы отключить grace-период для отдельного пользователя, требуется, чтобы для одной из его ролей была применена политика с параметром grace_authid_period, который равен нулю.
Пример настройки grace-периода для роли с помощью парольных политик#
Включите парольные политики. Для этого в конфигурационном файле
/etc/patroni/postgres.yml:Установите значение параметра:
password_policies_enable: onПерезагрузите кластер:
reload && restart
Установите начальные пароли для пользователей:
psql -c "SET password_encryption='scram-sha-256'; ALTER USER test_user_1 WITH PASSWORD '<password_1>'; ALTER USER test_user_2 WITH PASSWORD '<password_2>'; ALTER USER test_user_3 WITH PASSWORD '<password_3>';" ALTER ROLEВключите функциональность grace-паролей, и установите значение grace-периода для всех ролей. Для этого в конфигурационном файле
/etc/patroni/postgres.yml:Установите значения параметров:
grace_authid_enable: on grace_authid_period: '1200'Перечитайте конфигурацию на кластере:
reload
Проверьте, что у пользователей отсутствуют grace-пароли в представлении
pg_shadow:psql -c "SELECT usename, grace_period, grace_period_source, grace_time_left, prevpassword, currpassword FROM pg_shadow WHERE usename='test_user_1' OR usename='test_user_2' OR usename='test_user_3'" usename | grace_period | grace_period_source | grace_time_left | prevpassword | currpassword -------------+--------------+---------------------+-----------------+--------------+-------------- test_user_1 | 00:20:00 | config | | | test_user_2 | 00:20:00 | config | | | test_user_3 | 00:20:00 | config | | | (3 rows)Проверьте, что у пользователей отсутствуют grace-пароли в представлении
pg_roles:psql -c "SELECT rolname, grace_period, grace_period_source, grace_time_left, rolprevpassword FROM pg_roles WHERE rolname='test_user_1' OR rolname='test_user_2' OR rolname='test_user_3'"rolname | grace_period | grace_period_source | grace_time_left | rolprevpassword————-±————-±——————–±—————-±—————- test_user_1 | 00:20:00 | config | | test_user_2 | 00:20:00 | config | | test_user_3 | 00:20:00 | config | | (3 rows)
Проверьте, что у пользователей отсутствуют grace-пароли в представлении
pg_user:psql -c "SELECT usename, grace_period, grace_period_source, grace_time_left, prevpasswd FROM pg_user WHERE usename='test_user_1' OR usename='test_user_2' OR usename='test_user_3'"usename | grace_period | grace_period_source | grace_time_left | prevpasswd————-±————-±——————–±—————-±———– test_user_1 | 00:20:00 | config | | test_user_2 | 00:20:00 | config | | test_user_3 | 00:20:00 | config | | (3 rows)
Обновите пароли пользователей:
psql -c "SET password_encryption='scram-sha-256'; ALTER USER test_user_1 WITH PASSWORD '<password_1>'; ALTER USER test_user_2 WITH PASSWORD '<password_2>'; ALTER USER test_user_3 WITH PASSWORD '<password_3>';" ALTER ROLEПроверьте, что у пользователей существуют grace-пароли в представлении
pg_shadow, grace-период для всех пользователей равен периоду из конфигурации, источник настройки grace-периода - конфигурация, используя команду из пункта 4.usename | grace_period | grace_period_source | grace_time_left | prevpassword | currpassword -------------+--------------+---------------------+-----------------+------------------------------+---------------------------------------- test_user_1 | 00:20:00 | config | 00:19:49.69486 | SCRAM-SHA-256${hash} | SCRAM-SHA-256${hash} test_user_2 | 00:20:00 | config | 00:19:49.701905 | SCRAM-SHA-256${hash} | SCRAM-SHA-256${hash} test_user_3 | 00:20:00 | config | 00:19:49.708737 | SCRAM-SHA-256${hash} | SCRAM-SHA-256${hash} (3 rows)Проверьте, что у пользователей существуют grace-пароли в представлении
pg_roles, grace-период для всех пользователей равен периоду из конфигурации, источник настройки grace-периода - конфигурация, используя команду из пункта 5.rolname | grace_period | grace_period_source | grace_time_left | rolprevpassword -------------+--------------+---------------------+-----------------+----------------- test_user_1 | 00:20:00 | config | 00:19:24.605765 | ******** test_user_2 | 00:20:00 | config | 00:19:24.6075 | ******** test_user_3 | 00:20:00 | config | 00:19:24.609161 | ******** (3 rows)Проверьте, что у пользователей существуют grace-пароли в представлении
pg_user, grace-период для всех пользователей равен периоду из конфигурации, источник настройки grace-периода - конфигурация, используя команду из пункта 6.usename | grace_period | grace_period_source | grace_time_left | prevpasswd -------------+--------------+---------------------+-----------------+------------ test_user_1 | 00:20:00 | config | 00:19:15.196007 | ******** test_user_2 | 00:20:00 | config | 00:19:15.197727 | ******** test_user_3 | 00:20:00 | config | 00:19:15.199377 | ******** (3 rows)Установите значение grace-периода, которое превышает значение периода из конфигурации, для пользователя 1 через парольные политики:
psql -c "SELECT set_role_policies('test_user_1', policy_enable(1::boolean), grace_authid_period('30 minutes'));"Парольная политика с указанием grace-периода успешно применена:
set_role_policies ---------------------------------------------- (19090,,,,,,,,,,,,,,,,,,,,,t,,,,,,,00:30:00) (1 row)Установите значение grace-периода равное нулю для пользователя 2 через парольные политики:
psql -c "SELECT set_role_policies('test_user_2', policy_enable(1::boolean), grace_authid_period('0 minutes'));"Парольная политика с указанием grace-периода успешно применена:
set_role_policies ---------------------------------------------- (19110,,,,,,,,,,,,,,,,,,,,,t,,,,,,,00:00:00) (1 row)Проверьте с помощью представления
pg_shadow, используя команду из пункта 4, что у пользователя 1 grace-период превышает период, указанный в конфигурации, у пользователя 2 отсутствует grace-пароль:В представлении
pg_shadowу пользователя 1 grace-период превышает период, указанный в конфигурации, у пользователя 2 отсутствует grace-пароль:usename | grace_period | grace_period_source | grace_time_left | prevpassword | currpassword -------------+--------------+---------------------+-----------------+------------------------------+---------------------------------------- test_user_1 | 00:30:00 | policy | 00:29:50.417189 | SCRAM-SHA-256${hash} | SCRAM-SHA-256${hash} test_user_2 | 00:00:00 | policy | | | test_user_3 | 00:20:00 | config | 00:19:50.429895 | SCRAM-SHA-256${hash} | SCRAM-SHA-256${hash} (3 rows)Проверьте с помощью представления
pg_roles, используя команду из пункта 5, что у пользователя 1 grace-период превышает период, указанный в конфигурации, у пользователя 2 отсутствует grace-пароль:В представлении
pg_rolesу пользователя 1 grace-период превышает период, указанный в конфигурации, у пользователя 2 отсутствует grace-пароль:rolname | grace_period | grace_period_source | grace_time_left | rolprevpassword -------------+--------------+---------------------+-----------------+----------------- test_user_1 | 00:30:00 | policy | 00:29:41.019018 | ******** test_user_2 | 00:00:00 | policy | | test_user_3 | 00:20:00 | config | 00:19:41.031715 | ******** (3 rows)Проверьте с помощью представления
pg_user, используя команду из пункта 6, что у пользователя 1 grace-период превышает период, указанный в конфигурации, у пользователя 2 отсутствует grace-пароль:usename | grace_period | grace_period_source | grace_time_left | prevpasswd -------------+--------------+---------------------+-----------------+------------ test_user_1 | 00:30:00 | policy | 00:29:33.396283 | ******** test_user_2 | 00:00:00 | policy | | test_user_3 | 00:20:00 | config | 00:19:33.408985 | ******** (3 rows)Проверьте, что пользователь 1 может подключиться со старым паролем:
PGPASSWORD='<password_1>' psql -U test_user_1 -c "select 1;"Запрос успешно выполнен:
?column? ---------- 1 (1 row)Проверьте, что пользователь 1 может подключиться с текущим паролем:
PGPASSWORD='<password_1>' psql -U test_user_1 -c "select 1;"Запрос успешно выполнен:
?column? ---------- 1 (1 row)Проверьте, что пользователь 2 не может подключиться со старым паролем:
PGPASSWORD='<password_2>' psql -U test_user_2 -c "select 1;"Запрос не выполнен, ошибка авторизации:
psql: error: FATAL: password authentication failed for user "test_user_1" FATAL: password authentication failed for user "test_user_1"Проверьте, что пользователь 2 может подключиться с текущим паролем:
PGPASSWORD='<password_2>' psql -U test_user_2 -c "select 1;"Запрос успешно выполнен:
?column? ---------- 1 (1 row)
Схема настройки grace-периода в парольных политиках#

Наименование шага |
Входной документ |
Описание |
Исполнитель |
Выходной документ |
ИТ-система |
Переход к шагу |
|---|---|---|---|---|---|---|
010 Включить парольные политики |
postgres.conf |
Администратор АС включает парольные политики |
Администратор АС |
обновленный postgres.conf |
СУБД Pangolin |
020 |
020 Применить парольную политику к роли |
роль |
Администратор АС применяет к роли парольную политику с установленным grace_authid_period |
Администратор АС |
роль с политикой |
СУБД Pangolin |
Выход |
Обновление пароля#
При включенной функциональности, старый пароль пользователя хранится в базе данных на время grace-периода, если пароль был обновлен одним из способов:
при помощи SQL-запроса
ALTER USER/ROLE ... WITH PASSWORD ...;при помощи функции
rotate_passwordиз расширенияpsql_rotate_password;при помощи функции
pm_set_security_admin_passwordдля обновления пароля Администратора безопасности.
Внимание!
Если администратор БД обновит пароль пользователя напрямую в каталоге
pg_authid, то старый пароль пользователя утеряется и механизм grace-периода не сможет его использовать.
Существует ряд ограничений на работу функциональности при обновлении пароля:
Если новый пароль задается в формате
scram-sha256, то старый пароль не будет работать во время grace-периода. Это обусловлено механизмом аутентификацииscram-sha256: пользователю передается соль из хеша хранимого пароля, которую он использует, чтобы создать хеш пароля и передать ее серверу. Использовать соль от нового пароля во время grace-периода невозможно, так как сервер не может получить хеш старого пароля с новой солью, используя хеш старого пароля со старой солью. Поэтому на время grace-периода сервер отдает клиенту соль от старого хеша и хранит не только старый хеш со старой солью, но и хеш от нового пароля со старой солью. В отличие от других типов аутентификации в данном случае будет проверяться два варианта grace-паролей.
Если формат хранения нового пароля отличается от формата старого, то старый пароль не будет работать во время grace-периода.
Если старый пароль является транспортным, то он не будет работать во время grace-периода.
Если ограничения не выполняются, то grace-пароль не может быть сохранен. Если старый пароль является транспортным, то запрос на обновление пароля происходит без ошибок. В остальных случаях результат будет зависеть от настроенного параметра grace_skip_error. Если параметр установлен (значение on), то запрос завершится без ошибок, если параметр не установлен (значение off) - с ошибкой.
Обновление паролей использует механизм транзакций, если в процессе обновления основного пароля или grace-паролей произошла ошибка, то ни основной пароль, ни grace-пароли изменены не будут.
Процесс обновления пароля#
Схема процесса обновления пароля:

После поступления запроса на изменение пароля (от пользователя / администратора БД / администратора безопасности) происходит следующее:
При успешном выполнении запроса СУБД Pangolin выполняется следующие шаги:
Обновление пароля в каталоге
pg_authid.Сохранение старого пароль в каталоге grace-паролей, если функциональность grace-периода включена и ограничения на работу функциональности не возникают (например, пароль не должен быть транспортным).
Очистка предыдущих grace-паролей.
Успешное завершение выполнения запроса на обновление пароля.
При неудачном завершении запроса:
Возникновение ошибка запроса.
Произведен вывод сообщения пользователю.
Хранение grace-паролей#
Grace-пароли хранятся в отдельном каталоге, который защищен от изменения.
Удаление grace-паролей происходит в процессе аутентификации пользователя перед этапом проверки grace-пароля: если найдены записи с истекшим grace-паролем, то такие записи будут удалены.
Внимание!
Если пароль хранится в формате
md5, то изменение имени пользователя приведет к преждевременному завершению grace-периода. Это обусловлено тем, что имя пользователя используется в качестве соли для хранения паролейmd5. При этом аутентификация по основному паролю так же работать не будет.
Если у пользователя есть валидные grace-пароли, то они отображаются в представлении pg_shadow. Наличие паролей так же отображается в представлении pg_user и pg_roles. Во всех представлениях будет отображен grace-период и источник его настройки.