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

Засекречивание параметров подключения

Для исключения хранения паролей в открытом виде и предотвращения компрометации паролей в СУБД Pangolin подготовлен набор утилит, позволяющих засекречивать и хранить пароли в закодированном виде:

  • pg_auth_config — утилита засекречивания/хранения параметров подключения к БД;
  • pg_auth_password — утилита засекречивания паролей. Позволяет получить пароль в засекреченном виде после ввода исходного пароля.

Обе утилиты располагаются в каталоге $PGHOME/bin и доступны только владельцу (postgres).

При работе с расширением oracle_fdw пароль пользователя oracle вносится в хранилище паролей, но при проверке хранилища этот пароль не проверяется при вызове команды: pg_auth_config check.

Внимание!

Ключи, используемые при засекречивании паролей, уникальны для сервера. Они вычисляемые и нигде не хранятся.

Как следствие, пароли в засекреченном виде и файл хранилища:

  • применимы только в рамках сервера, где выполнялось кодирование;
  • уникальные/свои для каждого узла кластера.

В случае изменения конфигурации сервера могут потребоваться действия по пересозданию засекреченного хранилища/перекодированию паролей в конфигурационных файлах.

Внимание!

При использовании ванильного libpq работа с шифрованным хранилищем недоступна, так как мы не гарантируем работоспособность сторонних решений.

Утилита засекречивания и хранения параметров подключения к БД (pg_auth_config)

Утилиты, выполняющие автоматизированное подключение к БД, выполняют получение параметров подключения из защищенного хранилища для дальнейшего подключения к БД.

Утилита pg_auth_config формирует засекреченное хранилище, которое хранится в файле /etc/postgres/enc_utils_auth_settings.cfg. Ключи, используемые при кодировании, уникальны в рамках узла. Они не хранятся, а вычисляются в процессе. Также возможно добавление нескольких записей одной командой через разделитель «,».

Примечание:

В качестве ключа засекречивания используется фраза, конструируемая из параметров:

  • парольная фраза - CPU manufacturer ID CPU, CPU stepping, CPU model, CPU family, CPU feature flags, список MAC и IP-адресов постоянных сетевых интерфейсов;
  • соль - тип credentials, machineId из /etc/machine-id, UUID корневой файловой системы, домен для использования credentials (сейчас POSTGRESQL - для засекречивания конфигурационных файлов компонент отказоустойчивого кластера или KMS - для засекречивания параметров доступа к KMS).

Алгоритм определяется сконфигурированным плагином засекречивания (по умолчанию AES-256). Хранилище может быть рассекречено только на узле, где было создано. Оно автоматически формируется на этапе установки дистрибутива СУБД Pangolin.

Запуск утилиты pg_auth_config отображает параметры использования:

pg_auth_config - view and edit encrypted postgres credentials
Usage:
./pg_auth_config show | add | remove | check | reset | edit [options...]
Options:
--host [-h] host (add only: hosts delimeted by ",") for which password will be used
--json [-j] show in json format
--port [-p] port (add only: ports delimeted by ",") for which password will be used
--user [-U] user name for which password will be used
--database-all [-D] pecify all database mark (must be before --database if both)
--database [-d] database (add only: databases delimeted by ",") for which password will be used
--all [-a] check only: database (databases delimited by ",") for the 'all' lines during check, use "-" to ignore
--skip-confirm [-s] manual input without confirmation
--help show this help, then exit

Pangolin product version information:
--product_version prints product name and version
--product_build_info prints product build number, date and hash
--product_component_hash prints component hash string


The './pg_auth_config' utility is used to securely save password information
for internal Pangolin utilities
Using corresponding host, port, database tuples if multiple provided
the concept is simular to .pgpass, except this utility encrypts password information
Report bugs to <pangolin@sbertech.ru>.

Параметры host и port необходимы для того, чтобы пароль нельзя было использовать для подключения к произвольным БД, в том числе к модифицированным версиям postgres, показывающим, с каким паролем пыталось произойти подключение. Запись в хранилище можно перезаписать только целиком. Например, нельзя поменять отдельно только host. Для добавления множества записей одной командой количество host, port, database, написанных через разделитель , должно совпадать:

  • add — команда добавляет в хранилище пароль пользователя name. По умолчанию утилита дважды просит ввести пароль. Передача пароля через командную строку отсутствует.

    Внимание!

    В момент добавления пароля в хранилище его корректность не проверяется (т.е. не проводится сверка с паролем, хранящимся в БД).

    Пример использования:

    ./pg_auth_config add -h 127.0.0.1 -p 5432 -d postgres -U test
    enter password:
    ****
    confirm password:
    ****

    Опция --skip-confirm позволяет не запрашивать второго ввода пароля. Данную опцию рекомендуется использовать в автоматизированных системах, когда ввод пароля автоматизирован.

    ./pg_auth_config add -h 127.0.0.1 -p 5432 -d postgres -U test --skip-confirm
    enter password:
    ****
    confirm password:
    ****

    Через разделитель , можно добавить несколько записей одной командой:

    ./pg_auth_config add -h <IP-адрес>,<IP-адрес> -p 5432,1234 -U postgres -d database,dabatase
  • show — команда выводит в консоль содержимое хранилища (за исключением паролей).

    Пример использования:

    $ pg_auth_config show
    | host | port | database | username |
    |----------------------------------------------------------|
    | localhost | 5433 | postgres | patroni |
    | localhost | 5433 |replication | patroni |
    | <hostname> | 5433 | postgres | patroni |
    | <hostname> | 5433 |replication | patroni |
    | <hostname> | 5433 | database | user |
    | <hostname> | 5433 | database | user1 |

    Команда show позволяет выборочно выводить в консоль данные, используя конкретные параметры подключения: host, port, database или user.

    Пример использования:

    -- Пример просмотра данных с параметрами host и port

    $ pg_auth_config show -h 127.0.0.1 -p 5433
    | host | port | database | username |
    |------------------------------------------------|
    | 127.0.0.1 | 5433 | postgres |backup_user |

    -- Пример просмотра данных с параметрами database

    $ $ pg_auth_config show -d replication
    | host | port | database | username |
    |--------------------------------------------------------|
    | localhost | 5433 |replication | patroni |
    |srv-1-1 | 5433 |replication | patroni |
    |srv-1-2 | 5433 |replication | patroni |

    Команда show может использоваться вместе с опцией --json.

    Пример использования:

    ./pg_auth_config show --json
    {
    "records" :
    [
    {
    "database" : "database",
    "host" : {IP-адрес},
    "port" : {Порт},
    "username" : "postgres"
    },
    {
    "database" : "dabatase",
    "host" : {IP-адрес},
    "port" : {Порт},
    "username" : "postgres"
    }
    ]
    }
  • check — команда проверяет актуальность данных в хранилище с данными БД. При подключении к БД используются параметры подключения из хранилища.

    Пример использования:

    $ pg_auth_config check
    Connection settings for host: "localhost", port {Порт}, database "postgres", user "patroni" are OK
    Connection settings for host: "localhost", port {Порт}, database "replication", user "patroni" are OK
    Connection settings for host: "srv-1-1", port {Порт}, database "postgres", user "patroni" are OK
    Connection settings for host: "srv-1-1", port {Порт}, database "replication", user "patroni" are OK
    Could not connect with host: "srv-1-1", port {Порт}, database "postgres", user "test"...

    -- Сообщение "Connection settings for host..." говорит о пройденной успешной проверке
    -- Сообщение "Could not connect with host:..." говорит о неуспешной проверке

    Если не удалось установить соединение с сервером по причине «исчерпан лимит подключений», формируется соответствующее сообщение с подсказкой: too many clients, try again.

    Команда check позволяет выборочно проверять актуальность данных, используя конкретные параметры подключения: host, port, database или user.

    Пример использования:

    -- Пример проверки данных с параметрами host и port:

    $ pg_auth_config check -h 127.0.0.1 -p 5433
    Connection settings for host: "127.0.0.1", port "5433", database "postgres", user "backup_user" are OK

    -- Пример проверки данных с параметрами database:
    $ pg_auth_config check -d replication
    Connection settings for host: "localhost", port "5433", database "replication", user "patroni" are OK
    Connection settings for host: "srv-1-1", port "5433", database "replication", user "patroni" are OK
    Connection settings for host: "srv-1-2", port "5433", database "replication", user "patroni" are OK

    -- Пример проверки данных с параметрами user:
    $ pg_auth_config check -U patroni
    Connection settings for host: "localhost", port "5433", database "postgres", user "patroni" are OK
    Connection settings for host: "localhost", port "5433", database "replication", user "patroni" are OK
    Connection settings for host: "srv-1-1", port "5433", database "postgres", user "patroni" are OK
    Connection settings for host: "srv-1-1", port "5433", database "replication", user "patroni" are OK
    Connection settings for host: "srv-1-2", port "5433", database "postgres", user "patroni" are OK
    Connection settings for host: "srv-1-2", port "5433", database "replication", user "patroni" are OK

    -- Пример проверки данных с параметрами host, port, database, user:
    $ pg_auth_config check -h 127.0.0.1 -p 5433 -d replication -U patroni
    Connection settings for host: "127.0.0.1", port "5433", database "replication", user "patroni" are OK

    Во всех режимах работы утилиты проверяется введенное значения порта. Значение порта должно находиться в диапазоне от 1 до 65535 (включительно).

    Внимание!

    Команда в рамках работы расширения oracle_fdw с хранилищем паролей не проверяет пароль пользователя БД Oracle.

  • remove — команда удаляет запись, связанную с host, port, database, user. Команда выводит запрос на подтверждение операции удаления.

    Пример использования:

    $ pg_auth_config remove -h srv-1-1 -p 5433 -U user -d database
    Do you want to remove auth record? (yes/no)?:
    yes
    Going to remove auth record for user: "user", host: "srv-1-1", port: "5433", database: "database"
    record removed
  • reset — команда очищает хранилище. Команда выводит запрос на подтверждение очистки хранилища. После выполнения команды файл /etc/postgres/enc_utils_auth_settings.cfg переименовывается в /etc/postgres/enc_utils_auth_settings.cfg.reset. Утилита не имеет команды для восстановления файла. Для восстановления необходимо самостоятельно переименовать файл /etc/postgres/enc_utils_auth_settings.cfg.reset в /etc/postgres/enc_utils_auth_settings.cfg.

    Пример использования:

    -- Очистка хранилища

    $ pg_auth_config reset
    Do you want to reset auth config? (yes/no)?:
    yes
    Auth config was reset

    -- Просмотр содержимого хранилища после очистки
    $ pg_auth_config show
    | host | port | database | username |
    |-----------------------------------------------|

    -- Восстановление файла хранилища
    $ mv /etc/postgres/enc_utils_auth_settings.cfg.reset /etc/postgres/enc_utils_auth_settings.cfg

    -- Просмотр содержимого хранилища после восстановления
    $ pg_auth_config show
    | host | port | database | username |
    |---------------------------------------------------------|
    | localhost | 5433 | postgres | patroni |
    | localhost | 5433 |replication | patroni |
    |srv-1-1 | 5433 | postgres | patroni |
    |srv-1-1 | 5433 |replication | patroni |
    |srv-1-2 | 5433 | postgres | patroni |
    |srv-1-2 | 5433 |replication | patroni |
    ...
  • edit — позволяет редактировать существующие записи в хранилище, без необходимости пересоздавать их. Поиск записей для редактирования осуществляется с использованием ключа, состоящего из имени хоста, номера порта, имени пользователя, названия базы данных.

    Для поиска записей требуется указать минимум одно поле ключа. Поля задаются через существующие аргументы утилиты:

    --host [-h] — имя хоста
    --port [-p] — номер порта
    --user [-U] — имя пользователя
    --database [-d] — название базы данных

    Пример запуска утилиты в режиме редактирования (поиск по ключу: имя пользователя patroni, название базы данных postgres):

    pg_auth_config edit -U patroni -d postgres

    При этом, если:

    • не задано ни одного поля, то работа утилиты завершится, и будет выведено предупреждение:

      At least one field must be defined: host, port, username, database
    • записи, соответствующие ключу поиска, не найдены, то работа утилиты завершится, и будет выведено предупреждение:

      Nothing to update: records not found
    • записи, соответствующие ключу поиска, найдены, то утилита перейдет в интерактивный режим ввода новых значений (см. ниже раздел «Ввод новых значений для редактируемых полей»).

Обработка значения универсального имени БД --database-all

При разборе файла /etc/postgres/enc_utils_auth_settings.cfg, начиная с версии 6.3.0, введена специальная обработка значения универсального имени БД (--database-all). Сопоставление данных аутентификации выполняется следующим образом:

  1. Просматривается весь файл enc_utils_auth_settings.cfg до момента полного совпадения всех ключей (включая имя БД). При обнаружении используются данные аутентификации из найденной строки.
  2. Если требуемые данные не найдены — ищется подходящий вариант с универсальным именем БД. При обнаружении используются данные найденной строки.
  3. Если в предыдущих пунктах данные не найдены — отказ доступа из-за отсутствия данных аутентификации.

Получение данных аутентификации унифицировано для всех доступных интерфейсов. Универсальное имя БД отображается как all.

Примеры:

  1. Добавление записи:

    $ pg_auth_config add -p 5433 --database-all --user profile_tuz -h 127.0.0.1
    ...--database-all requested (specify any DB)
    Enter password:
    ***
    Confirm password:
    ***
    Going to add auth record for user: "profile_tuz", host: "127.0.0.1", port: "5433", database: "*** all ***"
    New record added

    В таблицу данных аутентификации будет добавлена запись:

    $ pg_auth_config show
    | host | port | database | username |
    |-------------------------------------------------|
    | 127.0.0.1 | 5433 |*** all *** |profile_tuz |
  2. Изменение записи типа all:

    $ pg_auth_config edit -h 127.0.0.1 --database-all -U profile_tuz
    ...--database-all requested (specify any DB)
    Enter port or leave empty to skip update:
    5434
    Enter host or leave empty to skip update:

    Enter username or leave empty to skip update:

    Enter database or leave empty to skip update:
    db9
    Enter password or leave empty to skip update:

    Going to update 1 records:

    | host | port | database | username |
    |----------------------------------------------------------|
    | 127.0.0.1 |5433 -> 5434 |*** all *** -> db9 |profile_tuz |
    Do you want to update auth records? (yes/no)?:
    y

    Запись изменена:

    $ pg_auth_config show
    | host | port | database | username |
    |------------------------------------------------|
    | 127.0.0.1 | 5434 | db9 |profile_tuz |
  3. Изменение обычной записи на тип all:

    $ pg_auth_config edit -h 127.0.0.1 --database-all -d db9 -U profile_tuz
    ...--database-all requested (specify any DB)
    Enter port or leave empty to skip update:

    Enter host or leave empty to skip update:

    Enter username or leave empty to skip update:

    Enter database or leave empty to skip update:

    Enter password or leave empty to skip update:

    Going to update 1 records:

    | host | port | database | username |
    |--------------------------------------------------------|
    | 127.0.0.1 | 5434 |db9 -> *** all *** |profile_tuz |
    Do you want to update auth records? (yes/no)?:
    y

    Запись изменена:

    $ pg_auth_config show
    | host | port | database | username |
    |-------------------------------------------------|
    | 127.0.0.1 | 5434 |*** all *** |profile_tuz |

Специфика работы команды check с универсальными именами БД

В отличие от строк с обычными именами (не типа all), которые сопоставляются на предмет полного совпадения, работа команды check с универсальными именами включает в себя:

  1. Подключение к БД template1 с данными авторизации из строки - если подключение неуспешно, выводится сообщение Cannot connect to template database for 'all' database specified., а также возвращается значение exit_code=1.
  2. Получение списка доступных БД на сервере - если получение списка неудачно, выводится сообщение Cannot get DB list for 'all' database specified. и возвращается значение exit_code=1.
  3. Подключение ко всем БД, полученным на предыдущем шаге, кроме БД, для которых есть отдельные данные авторизации с явным указанием имени БД.

В ходе выполнения первых двух шагов обработка списка не прерывается.

Для обработки случаев, когда получение списка БД невозможно (например, при отсутствии у пользователя прав для подключения к template1), есть возможность задать имена БД для проверки непосредственно параметром:

pg_auth_config check --all db1,db2

При таких сценариях проверяются все строки из таблицы аутентификации, но для строк с отметкой all будет выполняться проверка подключения только к db1 и db2 (без попыток доступа к template1 и без получения фактического списка БД).

Дополнительно предлагается вариант игнорирования проверки универсальных строк (database=all):

pg_auth_config check --all -

При такой установке параметра строки с отметкой all проверяться не будут.

Функция добавления пароля в засекреченное хранилище

Возможны ситуации когда администратору АС требуется завести задание в pg_cron. Для выполнения задания, pg_cron должен подключаться к БД, используя параметры подключения из засекреченного хранилища. То есть засекреченное хранилище должно содержать запись для выполнения задания pg_cron. Администратор АС не может использовать утилиту pg_auth_config для самостоятельного добавления записи в засекреченное хранилище и не может раскрыть пароль администратору БД, чтобы последний добавил запись. Для решения данной ситуации в Pangolin добавлена функция - add_auth_record_to_storage.

Подробное описание функции в документе «Справочное руководство», раздел «Засекречивание и хранение параметров подключения».

Ввод новых значений для редактируемых полей

Ввод новых значений для редактируемых записей осуществляется в интерактивном режиме с помощью команды edit. Для всех полей будет предложено ввести новые значения. Например, предложение на ввод новых значений для поля port (номер порта):

enter port or leave empty to skip update:

Примечание:

Ввод нового пароля будет запрошен, если ключ поиска содержит имя пользователя.

Если новые значения получены, то утилита выведет список обновляемых записей.

Пример обновления двух записей. Обновляются поля port (номер порта) и username (имя пользователя»):

Going to update 2 records:

| host | port | database | username |
|-----------------------------------------------------|
| 127.0.0.1 |9000 -> 9001 | somedb1 |user1 -> user4 |
| 127.0.0.2 |9000 -> 9001 | somedb1 |user1 -> user4 |

В случае, если при запуске не указан ключ -s (--skip-confirm), то будет запрошено подтверждение операции редактирования записей:

Do you want to update auth records? (yes/no)?:

Для продолжения требуется ввести:

  • «y» или «yes» — для подтверждения операции редактирования;
  • «n» или «no» — для отмены операции редактирования.

Предупреждения и ошибки

В случае, если:

  • не ввести ни одного нового значения для запрашиваемых полей, то работа утилиты завершится, и будет выведено предупреждение:

    Nothing to update: no new values provided
  • новые значения совпадают со старыми (например, найдена одна запись), то работа утилиты завершится, и будет выведено предупреждение:

    Nothing to update: new values for the records are the same as the old ones
  • в процессе обновления полей возникают дублирующие друг друга записи, то такие записи будут удалены.

    Примечание:

    Если записи дублируют друг друга, то сохраняется первая запись в списке.

    Для удаляемых записей будет указан признак «< rm» в конце записи. Пример удаления двух дублирующих записей (обновляется поле «название базы данных», уже существуют записи, совпадающие с обновляемыми):

    Going to update 2 records:

    | host | port | database | username |
    |----------------------------------------------------------------------|
    | localhost | 5433 |replication -> postgres | patroni | < rm
    |srv-0-153 | 5433 |replication -> postgres | patroni | < rm

Описание процессов использования утилиты pg_auth_config

Процесс добавления пароля (параметров подключения к БД) в зашифрованное хранилище

Не имеет значения с какого узла кластера начинать изменение пароля. Файл конфигурации созданный на одном узле, например на лидере, не может быть расшифрован на реплике и наоборот.

  1. Выполняется проверка сотрудником сопровождения либо автоматически при первичной инсталляции Pangolin: будет настраиваться standalone или cluster. В случае типа конфигурации: standalone - переход к шагу 2; cluster - переход к шагу 3.

  2. Выполняется добавление параметров подключения к БД в зашифрованное хранилище через утилиту pg_auth_config на standalone:

    • вызывается утилита с параметрами подключения к БД: pg_auth_config add --h <host> – p <port> --U <user> --d <dbname>;
    • вводится пароль пользователя;
    • в результате параметры подключения добавлены в зашифрованное хранилище.
  3. Выполняется добавление параметров подключения к БД в зашифрованное хранилище через утилиту pg_auth_config на cluster:

    • вызывается утилита с параметрами подключения к БД: pg_auth_config add --h <host> – p <port> --U <user> --d <dbname> на первом узле кластера;
    • вводится пароль пользователя;
    • в результате параметры подключения добавлены в зашифрованное хранилище на первом узле кластера;
    • вызывается утилита с параметрами подключения к БД: pg_auth_config add --h <host> – p <port> --U <user> --d <dbname> на втором узле кластера;
    • вводится пароль пользователя;
    • в результате параметры подключения добавлены в зашифрованное хранилище на втором узле кластера.
  4. В случае ручного добавления параметров подключения к БД рекомендуется выполнить проверку актуальности данных в зашифрованном хранилище на корректность введенных паролей командой pg_auth_config check.

Процесс добавления пароля (параметров подключения к БД) в зашифрованное хранилище Администратором АС

Не имеет значения с какого узла кластера начинать добавление/изменение пароля. Пароль добавленный в зашифрованное хранилище с помощью функции add_auth_record_to_storage, не реплицируется на второй узел кластера.

  1. Выполняется проверка администратором АС: будет настраиваться standalone или cluster. В случае типа конфигурации: standalone — переход к шагу 2; cluster — переход к шагу 3.

  2. Выполняется добавление параметров подключения к БД в зашифрованное хранилище с помощью функции add_auth_record_to_storage на standalone:

    • вызывается функция add_auth_record_to_storage с указанием параметров подключения, например:

      select  add_auth_record_to_storage('127.0.0.1', 5433, 'db_name', 'user', 'password');
    • в результате параметры подключения добавлены в зашифрованное хранилище.

  3. Выполняется добавление параметров подключения к БД в зашифрованное хранилище через утилиту pg_auth_config на cluster:

    • вызывается функция add_auth_record_to_storage с указанием параметров подключения на первом узле кластера, например:

      select  add_auth_record_to_storage('127.0.0.1', 5433, 'db_name', 'user', 'password');
    • в результате параметры подключения добавлены в зашифрованное хранилище на первом узле кластера;

    • вызывается функция add_auth_record_to_storage с указанием параметров подключения на втором узле кластера, например:

      select  add_auth_record_to_storage('127.0.0.1', 5433, 'db_name', 'user', 'password');
    • в результате параметры подключения добавлены в зашифрованное хранилище на втором узле кластера.

  4. Рекомендуется выполнить проверку актуальности данных в зашифрованном хранилище на корректность введенных паролей командой pg_auth_config check.

Утилита шифрования паролей, представленных в открытом виде (pg_auth_password)

Для исключения хранения паролей в открытом виде и предотвращения компрометации паролей командой развития Pangolin разработана утилита для шифрования паролей pg_auth_password. Утилита pg_auth_password располагается в каталоге $PGHOME/bin, доступна только владельцу (postgres).

Утилита pg_auth_password выполняет только одно действие - шифрование паролей.

На вход утилита pg_auth_password принимает пароль, результат выполнения выводится в консоль. Зашифрованный пароль используется в конфигурационных файлах.

Формат зашифрованного пароля:

$enc$<encrypted_password_in_base64>

- $enc$ — признак зашифрованного пароля;
- <encrypted_password_in_base64> — зашифрованный пароль в формате base64.

Зашифрованный пароль используется:

  • Pangolin Manager для выполнения запросов по REST API и взаимодействия с etcd (прописывается в конфигурации Pangolin Manager);
  • postgre для выполнения ldap binding (прописывается в ldap записи pg_hba.conf файла).

Параметры использования

Запуск утилиты pg_auth_passwordс опцией --help отображает параметры использования:

$ pg_auth_password --help
Утилита 'pg_auth_password' предназначена для шифрования пароля.

Использование:
pg_auth_password enc -t [ОПЦИИ]

Опции:
-s или enc -t --skip-confirm ручной ввод без подтверждения
-W <пароль> или enc -t --password <пароль> пароль вводится в качестве аргумента

Другие опции:
-V или --version вывод информации о версии, затем выход
-h или --help вывод справки, затем выход

Информация о версии продукта Pangolin:
--product_version выводит название и версию продукта
--product_build_info выводит номер, дату и хеш сборки продукта
--product_component_hash выводит хеш-строку компонента

Внимание!

Для работы других опций и информации о версии продукта Pangolin ввод enc -t не требуется:

$ pg_auth_password -v

Утилита имеет одну команду enc -t и несколько опций (--skip-confirm, --password <password>), которые упрощают действия по шифрованию пароля.

  • enc -t — команда шифрует пароль, который может быть введен или передан в виде аргумента. По умолчанию утилита дважды просит ввести пароль. Результат выводится в консоль.

    Пример использования:

    $ pg_auth_password enc -t
    enter password:
    **********************
    enter password:
    **********************
    $enc${хеш}

Использование утилиты с опциями:

  • --skip-confirm / -s: подтверждение пароля не требуется. Данную опцию рекомендуется использовать в автоматизированных системах, когда ввод пароля автоматизирован.

    Пример использования:

    $ pg_auth_password enc -t -s
    enter password:
    ***************
    $enc${хеш}

    -- либо
    pg_auth_password enc -t --skip-confirm
    enter password:
    ***************
    $enc${хеш}
  • --password / -W: пароль передается в виде аргумента. При указании данной опции — запрос пароля из консоли не производится.

    Пример использования:

    $ pg_auth_password enc -t -W test
    $enc${хеш}

    -- либо
    $ pg_auth_password enc -t --password test
    $enc${хеш}

Описание процессов использования утилиты pg_auth_password

Процесс добавления зашифрованного пароля в конфигурационной файл

Примечание:

Параметры хранятся в файле в зависимости от типа конфигурации сервера: если тип конфигурации standalone: в файле $PGDATA/pg_hba.conf, в случае типа конфигурации cluster или standalone+Pangolin Manager: в файле /etc/pangolin-manager/postgres.yml в секции pg_hba.

  1. Выполняется проверка сотрудником сопровождения либо автоматически при первичной инсталляции Pangolin: будет настраиваться standalone или cluster. В случае типа конфигурации: standalone — переход к шагу 2; cluster — переход к шагу 3.

  2. Выполняется формирование зашифрованного пароля через утилиту pg_auth_password на standalone:

    • вызывается утилита pg_auth_password enc -t;
    • вводится пароль для получения его в зашифрованном виде;
    • полученный зашифрованный пароль в формате base64 копируется и вносится для нужного пользователя в конфигурационный файл путем редактирования;
    • для вступления в силу выполняется перечитывание конфигурации командой reload.
  3. Выполняется формирование зашифрованного пароля через утилиту pg_auth_password на первом узле кластера:

    • вызывается утилита pg_auth_password enc -t на первом узле кластера;
    • вводится пароль для получения его в зашифрованном виде;
    • полученный зашифрованный пароль в формате base64 копируется и вносится для нужного пользователя в конфигурационный файл путем редактирования;
    • для вступления в силу выполняется перечитывание конфигурации командой reload.
  4. Выполняется формирование зашифрованного пароля через утилиту pg_auth_password на втором узле кластера:

    • вызывается утилита pg_auth_password enc -t на втором узле кластера;
    • вводится пароль для получения его в зашифрованном виде;
    • полученный зашифрованный пароль в формате base64 копируется и вносится для нужного пользователя в конфигурационный файл путем редактирования;
    • для вступления в силу выполняется перечитывание конфигурации командой reload.

Включение/отключение функциональности шифрования паролей

Новая функциональность позволяет развернуть СУБД Pangolin без шифрованного хранилища.

Описание решения

Реализация решения в части инсталлятора

В скриптах развертывания и обновления создание шифрованного хранилища и шифрование паролей в конфигурационных файлах (postgres.yml и pg_hba.conf) определено под условие, которое контролируется параметром auth_encrypt в пользовательском конфигурационном файле. Значение по умолчанию: true. В конфигурационный файл Pangolin Manager (postgres.yml) добавлены следующие параметры: postgresql.pgpass - путь к файлу со строкой подключения, если шифрованное хранилище отсутствует. Значение по умолчанию: /home/postgres/.pgpass.

 postgres.yml
postgresql:
{%- if not auth_encrypt %}
pgpass: "{{ PGUSERHOME }}/.pgpass"
{%- endif %}

postgresql.authentication.replication.password - пароль суперпользователя для репликации. Значение по умолчанию: patroni_password.

postgres.yml
postgresql:
authentication:
replication:
{%- if not auth_encrypt %}
password: '{{ patroni_user_pass }}'
{%- endif %}

postgresql.authentication.superuser.password - пароль для суперпользователя. Значение по умолчанию: patroni_password.

postgres.yml
postgresql:
authentication:
superuser:
{%- if not auth_encrypt %}
password: '{{ patroni_user_pass }}'
{%- endif %}

Внесены изменения в конфигурацию службы pangolin_reencrypt. Следующий блок не будет записан, если файл /etc/postgres/enc_utils_auth_settings.cfg не был найден.

enc_util.cfg
{% if pgar_encrypt_config_exists.stat.exists -%}
{
"name" : "/etc/postgres/enc_utils_auth_settings.cfg",
"owner" : "postgres",
"domain" : "postgres"
},
{% endif -%}

Реализована возможность задать индивидуальный пароль для пользователя patroni в пользовательском конфигурационном файле. Регулируется параметром patroni_password(опциональный). Если пароль не задан, будет сгенерирован случайный. В процессе обновления была реализована проверка на наличие шифрованного хранилища. При наличии файла /etc/postgres/enc_utils_auth_settings.cfg параметр auth_encrypt выставляется в true.

Реализация решения в части Pangolin Manager

Pangolin Manager. автоматически создает файл .pgpass, если зашифрованное хранилище паролей отсутствует. Создание файла происходит, если не проинициализирован контекст(отсутствует плагин шифрования) или отсутствует файл /etc/postgres/enc_utils_auth_settings.cfg. Данные о том, где создать файл Pangolin Manager определяет из конфигурационного файла postgres.yml, секция postgresql.pgpass. Скорректирована запись в логе Pangolin Manager при работе без шифрованного хранилища. Сообщение лога «using password from encrypted store for ...» заменено на «using password from the config for ...». Утилита pg_auth_config создает файл /etc/postgres/enc_utils_auth_settings.cfg только при добавлении записи в файл(аргумент add). Если файл не существовал, аргументы remove, show, check и edit создавали файл нулевого размера. Логика работы этих команд изменена. При отсутствии файла они будут выдавать ошибку \x1B[0mCannot load auth config (file is not found), где \x1B[0m - спец. цветовой символ (белый).

Ограничения

Есть ограничения в работе службы pangolin_reencrypt. Отсутствие файла или пароля внутри файла, которые прописаны в конфигурации службы pangolin_reencrypt, приведет к ошибке в работе перешифрования. Поэтому служба включается в процессе инсталляции только тогда, когда auth_encrypt: true и auth_reencrypt: true. Перед стартом инсталляции нельзя задать перечень ролей, пароли которых будут включены в шифрование или блоки конфигурационных файлов, содержащие пароли, которые нужно зашифровать.

Включение функциональности

Автоматическая установка

Значение true для параметра auth_encrypt позволит включить использование решения.

Автоматическое обновление

Реализация решения в обновлении не предусмотрена. Включить функциональность шифрования нельзя, если на исходном стенде ее не было.

Ручное включение

Примечание:

Действия производятся на ранее установленном стенде без шифрованного хранилища паролей.

Процесс включения шифрованного хранилища можно условно разделить на два этапа:

  • перевод не зашифрованных паролей в конфигурационных файлах postgres.yml и pg_hba.conf в зашифрованный вид с помощью утилиты шифрования паролей pg_auth_password:

    1. Для стенда в кластерной конфигурации зашифруйте пароли следующих секций в файле postgres.yml:

      postgres.yml

      restapi:
      authentication:
      username: patroniyml
      password: '{{ patroniyml_pass }}'
      etcd:
      username: patronietcd
      password: '{{ patronietcd_pass }}'
      postgresql:
      pg_hba:
      ... ldapbindpasswd="{{ ldap_pass }}"...
    2. Действие по шифрованию нужно производить поочередно на каждом узле. Произведите шифрование паролей на лидере:

      {{ patroniyml_pass }}

      sudo su - postgres
      pg_auth_password enc -t
      *Ожидаемый результат:*

      enter password:
      ***************************
      enter password:
      ***************************
      $enc${хеш}
      {{ patronietcd_pass }}

      sudo su - postgres
      pg_auth_password enc -t
      *Ожидаемый результат:*

      enter password:
      ***************************
      enter password:
      ***************************
      $enc${хеш}

      {{ ldap_pass }}

      sudo su - postgres
      pg_auth_password enc -t
      *Ожидаемый результат:*

      enter password:
      ***************************
      enter password:
      ***************************
      $enc${хеш}
    3. Замените открытые пароли на лидере на полученный результат шифрования:

      *Ожидаемый результат:*
      postgres.yml

      restapi:
      authentication:
      username: patroniyml
      password: '$enc${хеш}'
      etcd:
      username: patronietcd
      password: '$enc${хеш}'
      postgresql:
      pg_hba:
      ... ldapbindpasswd="$enc${хеш}"...
    4. Перечитайте конфигурацию на лидере:

      sudo su - postgres
      reload
      *Ожидаемый результат:*

      + Cluster: clustername (7205282150766022368) ------+--------------+---------+----+-----------+
      | Member | Host | Role | State | TL | Lag in MB |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      | srv-0-172 | srv-0-172:5433 | Leader | running | 2 | |
      | srv-0-182 | srv-0-182:5433 | Sync Standby | running | 2 | 0 |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      Are you sure you want to reload members srv-0-182, srv-0-172? [y/N]: y
      Reload request received for member srv-0-182 and will be processed within 10 seconds
      Reload request received for member srv-0-172 and will be processed within 10 seconds
    5. Произведите действия с пункта 2 по 4 на реплике.

  • создание шифрованного хранилища паролей с помощью утилиты pg_auth_config:

    1. Для корректной работы компонента Pangolin Manager добавьте следующие строки в хранилище с помощью утилиты pg_auth_config, где -h - хост, для которого будет использоваться пароль; -p - порт, для которого будет использоваться пароль; -U - имя пользователя, для которого будет использоваться пароль; -d - база данных, для которой будет использоваться пароль. Действие нужно произвести на обоих узлах:

      sudo su - postgres
      pg_auth_config add -s -h localhost -p 5433 -U patroni -d postgres
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "localhost", port: "5433", database: "postgres"
      New record added
      sudo su - postgres
      pg_auth_config add -s -h localhost -p 5433 -U patroni -d replication
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "localhost", port: "5433", database: "replication"
      New record added
      sudo su - postgres
      pg_auth_config add -s -h srv-0-172 -p 5433 -U patroni -d postgres
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "srv-0-172", port: "5433", database: "postgres"
      New record added
      sudo su - postgres
      pg_auth_config add -s -h srv-0-172 -p 5433 -U patroni -d replication
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "srv-0-172", port: "5433", database: "replication"
      New record added
      sudo su - postgres
      pg_auth_config add -s -h srv-0-182 -p 5433 -U patroni -d postgres
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "srv-0-182", port: "5433", database: "postgres"
      New record added
      sudo su - postgres
      pg_auth_config add -s -h srv-0-182 -p 5433 -U patroni -d replication
      *Ожидаемый результат:*

      Enter password:
      *******************
      Going to add auth record for user: "patroni", host: "srv-0-182", port: "5433", database: "replication"
      New record added
    2. Проверьте работоспособность хранилища паролей:

      sudo su - postgres
      pg_auth_config check
      *Ожидаемый результат:*

      Connection settings for host: "localhost", port "5433", database "postgres", user "patroni" are OK
      Connection settings for host: "localhost", port "5433", database "replication", user "patroni" are OK
      Connection settings for host: "srv-0-172", port "5433", database "postgres", user "patroni" are OK
      Connection settings for host: "srv-0-172", port "5433", database "replication", user "patroni" are OK
      Connection settings for host: "srv-0-182", port "5433", database "postgres", user "patroni" are OK
      Connection settings for host: "srv-0-182", port "5433", database "replication", user "patroni" are OK
    3. Удалите из конфигурационного файла Pangolin Manager следующие параметры: postgresql.pgpass: /home/postgres/.pgpass, postgresql.authentication.replication.password: '<пароль>', postgresql.authentication.superuser.password: '<пароль>'.

    4. Удалите файл /home/postgres/.pgpass на обоих узлах.

    5. Перечитайте конфигурацию и перезапустите сервер на лидере:

      sudo su - postgres
      reload
      *Ожидаемый результат:*

      + Cluster: clustername (7205282150766022368) ------+--------------+---------+----+-----------+
      | Member | Host | Role | State | TL | Lag in MB |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      | srv-0-172 | srv-0-172:5433 | Leader | running | 2 | |
      | srv-0-182 | srv-0-182:5433 | Sync Standby | running | 2 | 0 |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      Are you sure you want to reload members srv-0-182, srv-0-172? [y/N]: y
      Reload request received for member srv-0-182 and will be processed within 10 seconds
      Reload request received for member srv-0-172 and will be processed within 10 seconds
      sudo su - postgres
      restart --force
      *Ожидаемый результат:*

      + Cluster: clustername (7205282150766022368) ------+--------------+---------+----+-----------+
      | Member | Host | Role | State | TL | Lag in MB |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      | srv-0-172 | srv-0-172:5433 | Leader | running | 2 | |
      | srv-0-182 | srv-0-182:5433 | Sync Standby | running | 2 | 0 |
      +----------------------+---------------------------+--------------+---------+----+-----------+
      Success: restart on member srv-0-172
      Success: restart on member srv-0-182
    6. Аналогичным образом производится добавление паролей для других пользователей БД в шифрованное хранилище паролей.

    7. Подключите службу перешифрования на обоих узлах:

      sudo su
      systemctl start pangolin_reencrypt@postgres.service
      systemctl status pangolin_reencrypt@postgres.service
      *Ожидаемый результат:*

      ● pangolin_reencrypt@postgres.service - Runners Pangolin reencrypt service (postgres)
      Loaded: loaded (/usr/lib/systemd/system/pangolin_reencrypt@.service; enabled; vendor preset: disabled)
      Active: active (running) since Tue 2023-01-31 11:30:43 MSK; 5h 48min ago
      Process: 3316 ExecStartPost=/bin/sleep 1 (code=exited, status=0/SUCCESS)
      Process: 3311 ExecStart=/opt/pangolin-common/bin/pangolin-auth-reencrypt -l2 -d (code=exited, status=0/SUCCESS)
      Process: 3310 ExecStartPre=/bin/chmod g+rw /var/run/pangolin_reencrypt (code=exited, status=0/SUCCESS)
      Process: 3305 ExecStartPre=/bin/chown postgres:kmadmin_pg /var/run/pangolin_reencrypt (code=exited, status=0/SUCCESS)
      Process: 3303 ExecStartPre=/bin/mkdir -p /var/run/pangolin_reencrypt (code=exited, status=0/SUCCESS)
      Main PID: 3315 (pg_auth_reencry)
      CGroup: /system.slice/system-pangolin_reencrypt.slice/pangolin_reencrypt@postgres.service
      └─3315 /opt/pangolin-common/bin/pangolin-auth-reencrypt -l2 -d

      Jan 31 11:30:42 srv-0-172 systemd[1]: Starting Runners Pangolin reencrypt service (postgres)...
      Jan 31 11:30:42 srv-0-172 pangolin-auth-reencrypt[3315]: Reencrypt daemon was started for postgres
      Jan 31 11:30:42 srv-0-172 pangolin-auth-reencrypt[3315]: Load configuration /etc/postgres/enc_util.cfg ok
      Jan 31 11:30:43 srv-0-172 systemd[1]: Started Runners Pangolin reencrypt service (postgres).
      Jan 31 11:30:47 srv-0-172 pangolin-auth-reencrypt[3315]: Start saving current encrypting params
      Jan 31 11:30:47 srv-0-172 pangolin-auth-reencrypt[3315]: Saving current encrypting params ok

Отключение функциональности

Автоматическая установка

Значение false для параметра auth_encrypt позволит отключить использование решения.

Автоматическое обновление

Отключение решения для стендов с шифрованым хранилищем не предусмотрено.

Ручное отключение

Примечание:

Действия производятся на ранее установленном стенде с шифрованным хранилищем паролей. Также необходимо заранее знать пароли пользователей БД, которые находятся в шифрованном хранилище паролей.

Произвести выключение шифрованного хранилища можно следующим образом:

  1. Создайте файл /home/postgres/.pgpass на реплике, назначьте права 0600 и владельца/группу postgres:

    sudo su - postgres
    mkdir /home/postgres/.pgpass
    chown postgres:postgres /home/postgres/.pgpass
    chmod 0600 /home/postgres/.pgpass
    ls -la /home/postgres/.pgpass
    *Ожидаемый результат:*

    -rw------- 1 postgres postgres 2152 Mar 1 17:40 .pgpass
  2. Добавьте строку подключения в файл /home/postgres/.pgpass для пользователя patroni:

    echo "srv-0-172:5433:*:patroni:TestPassword{passwotd}" > /home/postgres/.pgpass
  3. Получите список серверов расширения pg_profile, если оно используется:

    select pgse_profile.show_servers();
    *Ожидаемый результат:*
    show_servers
    ---------------------------------------------------------------------------------------------------------------------
    (master,"dbname=First_db host=srv-0-172 port=5433 user=profile_tuz",t,)
    (replica,"dbname=First_db host=srv-0-182 port=5433 user=profile_tuz",t,)
    (2 rows)
  4. Скорректируйте строки подключения/добавьте параметр password ко всем существующим серверам, полученным на предыдущем шаге, в расширении pg_profile, если используется:

    sudo su - postgres
    psql
    SELECT pgse_profile.set_server_connstr('master', 'dbname=First_db host=srv-0-172 pprb_dev port=5433 user=profile_tuz password=TestProfileUser56&*');
    SELECT pgse_profile.set_server_connstr('replica', 'dbname=First_db host=srv-0-182 pprb_dev port=5433 user=profile_tuz password=TestProfileUser56&*');
    *Ожидаемый результат:*

    set_server_connstr
    --------------------
    1
    (1 row)
  5. Скорректируйте конфигурационный файл Pangolin Manager, добавив следующие параметры: postgresql.pgpass: /home/postgres/.pgpass, postgresql.authentication.replication.password: '<пароль>', postgresql.authentication.superuser.password: '<пароль>' на обоих узлах.

  6. Остановите службу перешифрования на обоих узлах:

    sudo su
    systemctl stop pangolin_reencrypt@postgres.service
    systemctl status pangolin_reencrypt@postgres.service
    *Ожидаемый результат:*

    ● pangolin_reencrypt@postgres.service - Runners Pangolin reencrypt service (postgres)
    Loaded: loaded (/usr/lib/systemd/system/pangolin_reencrypt@.service; disabled; vendor preset: disabled)
    Active: inactive (dead)

    Feb 06 12:51:21 srv-1-7 systemd[1]: [/usr/lib/systemd/system/pangolin_reencrypt@.service:19] Unknown lvalue 'TimeoutStopFailureMode' in section 'Service'
    Feb 06 16:22:28 srv-1-7 systemd[1]: [/usr/lib/systemd/system/pangolin_reencrypt@.service:19] Unknown lvalue 'TimeoutStopFailureMode' in section 'Service'
  7. Удалите все записи из шифрованного хранилища паролей на обоих узлах:

    sudo su - postgres
    pg_auth_config reset
    pg_auth_config show
    *Ожидаемый результат:*

    Cannot load auth config (file is not found)
  8. Перечитайте конфигурацию и перезапустите сервер на лидере:

    sudo su - postgres
    reload
    *Ожидаемый результат:*

    + Cluster: clustername (7205282150766022368) ------+--------------+---------+----+-----------+
    | Member | Host | Role | State | TL | Lag in MB |
    +----------------------+---------------------------+--------------+---------+----+-----------+
    | srv-0-172 | srv-0-172:5433 | Leader | running | 2 | |
    | srv-0-182 | srv-0-182:5433 | Sync Standby | running | 2 | 0 |
    +----------------------+---------------------------+--------------+---------+----+-----------+
    Are you sure you want to reload members srv-0-182, srv-0-172? [y/N]: y
    Reload request received for member srv-0-182 and will be processed within 10 seconds
    Reload request received for member srv-0-172 and will be processed within 10 seconds
    sudo su - postgres
    restart --force
    *Ожидаемый результат:*

    + Cluster: clustername (7205282150766022368) ------+--------------+---------+----+-----------+
    | Member | Host | Role | State | TL | Lag in MB |
    +----------------------+---------------------------+--------------+---------+----+-----------+
    | srv-0-172 | srv-0-172:5433 | Leader | running | 2 | |
    | srv-0-182 | srv-0-182:5433 | Sync Standby | running | 2 | 0 |
    +----------------------+---------------------------+--------------+---------+----+-----------|
    Success: restart on member srv-0-172
    Success: restart on member srv-0-182