Настройки пула

Каждая запись в pool — это имя виртуальной базы данных, к которой может подключиться клиент pg-doorman.

[pools.exampledb] # Объявление базы данных 'exampledb'

server_host

Каталог с unix-сокетами или IPv4-адрес сервера PostgreSQL, обслуживающего этот пул.

Пример: "/var/run/postgresql" или "127.0.0.1".

По умолчанию: "127.0.0.1".

server_port

Порт, через который сервер PostgreSQL принимает входящие соединения.

По умолчанию: 5432.

server_database

Опциональный параметр, определяющий, к какой базе нужно подключаться на сервере PostgreSQL.

application_name

Параметр application_name, отправляемый серверу при открытии соединения с PostgreSQL. Может быть полезен при настройке sync_server_parameters = false.

connect_timeout

Максимальное время на установку нового серверного соединения для этого пула, в миллисекундах. Если не задано, используется глобальная настройка connect_timeout.

По умолчанию: None (uses global setting).

idle_timeout

Закрывать idle-соединения в этом пуле, открытые дольше указанного значения, в миллисекундах. Если не задано, используется глобальная настройка idle_timeout.

По умолчанию: None (uses global setting).

server_lifetime

Закрывать серверные соединения в этом пуле, открытые дольше указанного значения, в миллисекундах. Применяется только к idle-соединениям. Если не задано, используется глобальная настройка server_lifetime.

По умолчанию: None (uses global setting).

pool_mode

Когда бэкенд-соединение возвращается в пул. transaction: освобождается после каждой транзакции. session: удерживается до отключения клиента. То же, что pool_mode в PgBouncer.

По умолчанию: "transaction".

log_client_parameter_status_changes

Логировать информацию о любой команде SET в лог.

По умолчанию: false.

cleanup_server_connections

Управляет тем, сбрасывает ли pg_doorman состояние сессии при возврате соединения в пул. Когда параметр включён и сессия была изменена, pg_doorman отправляет: RESET ROLE, плюс при необходимости RESET ALL (если использовался SET), DEALLOCATE ALL (если использовался PREPARE), CLOSE ALL (если открывались курсоры). Замечание: ROLLBACK для открытых транзакций выполняется всегда, независимо от этой настройки. Отключайте только если ваше приложение никогда не использует SET, prepared statements или курсоры и вы хотите сэкономить roundtrip на очистке.

По умолчанию: true.

scaling_warm_pool_ratio

Переопределяет глобальный scaling_warm_pool_ratio для этого пула. Если не задано, используется глобальная настройка.

scaling_fast_retries

Переопределяет глобальный scaling_fast_retries для этого пула. Если не задано, используется глобальная настройка.

max_db_connections

Жёсткий потолок суммарного числа серверных соединений к этой базе, разделяемый между всеми пользовательскими пулами. При достижении лимита и запросе нового соединения координатор сначала пытается вытеснить idle-соединения у других пользователей (учитывая их min_pool_size), затем ждёт возврата соединения и наконец откатывается к резервному пулу. Установите 0 (или опустите), чтобы отключить координацию — каждый пользовательский пул работает независимо, ограниченный только своим pool_size. Аналог max_db_connections из PgBouncer.

По умолчанию: 0 (disabled).

min_connection_lifetime

Минимальный возраст (в миллисекундах), которого должно достичь соединение, прежде чем оно сможет быть вытеснено координатором пула. Предотвращает циклическое переподключение между пользовательскими пулами, разделяющими одну базу: без этого порога idle-слот одного пользователя становится доступен для вытеснения сразу же, как только сосед запрашивает разрешение, и под устойчивой многопользовательской нагрузкой каждый пул отбирает слот у соседа каждые несколько секунд. Имеет значение только при max_db_connections > 0.

По умолчанию: 30000 (30 seconds).

reserve_pool_size

Число дополнительных соединений, разрешённых сверх max_db_connections в качестве крайней меры. Когда вытеснение не удаётся и соединения не возвращаются за reserve_pool_timeout, резервное соединение выдаётся запрашивающему с наивысшим приоритетом. Пользователи ниже своего min_pool_size получают абсолютный приоритет. Имеет значение только при max_db_connections > 0.

По умолчанию: 0.

reserve_pool_timeout

Сколько времени (в миллисекундах) ждать освобождения обычного соединения, прежде чем обратиться к резервному пулу. В этом окне координатор слушает возвраты соединений. Имеет значение только при max_db_connections > 0 и reserve_pool_size > 0.

По умолчанию: 3000 (3 seconds).

min_guaranteed_pool_size

Дефолт уровня пула для минимального числа соединений на пользователя, защищённых от вытеснения координатором. Когда координатору нужно освободить слот соединения для другого пользователя, он не будет вытеснять соединения у пользователя, у которого их количество меньше или равно этому значению.

Это отличается от min_pool_size (уровня пользователя): min_pool_size управляет прогревом и пополнением (проактивное создание соединений), тогда как min_guaranteed_pool_size влияет только на решения о вытеснении (никогда не создаёт соединения).

Эффективная защита для пользователя — max(user.min_pool_size, pool.min_guaranteed_pool_size). Установите 0 (или опустите), чтобы отключить защиту от вытеснения. Имеет значение только при max_db_connections > 0.

По умолчанию: 0 (no protection).

Настройки auth_query

Секция auth_query включает динамическую аутентификацию пользователей через запрос учётных данных у базы PostgreSQL во время подключения. Это позволяет pg_doorman аутентифицировать пользователей без статического перечисления их в конфигурационном файле.

pools:
  mydb:
    auth_query:
      query: "SELECT passwd FROM pg_shadow WHERE usename = $1"
      user: "doorman_auth"
      password: "auth_password"

Существуют два режима работы:

  • Dedicated mode (задан server_user): все динамически аутентифицированные пользователи разделяют один пул соединений, который подключается к PostgreSQL как server_user. Это самая простая настройка, хорошо подходящая, когда всем пользователям нужен одинаковый бэкенд-доступ.
  • Passthrough mode (server_user не задан): каждый динамически аутентифицированный пользователь получает собственный пул соединений, подключающийся к PostgreSQL по его собственным учётным данным (MD5 pass-the-hash или SCRAM ClientKey passthrough). Это сохраняет идентичность каждого пользователя на бэкенде.

Статические пользователи (определённые в секции users) всегда проверяются первыми. auth_query используется только когда имя пользователя не найдено среди статических.

Рекомендация по безопасности

user, выполняющий auth-запросы, должен иметь доступ к хешам паролей (например, из pg_shadow). Не используйте суперпользователя для этой цели. Вместо этого создайте функцию SECURITY DEFINER, принадлежащую суперпользователю, и выделенную роль с минимальными привилегиями:

-- Создаём выделенную роль для auth-запросов
CREATE ROLE doorman_auth LOGIN PASSWORD 'strong_password';

-- Создаём функцию SECURITY DEFINER (выполняется с привилегиями владельца)
CREATE OR REPLACE FUNCTION pg_doorman_get_auth(p_usename TEXT)
RETURNS TABLE (usename name, passwd text)
LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog AS
$$
  SELECT usename, passwd FROM pg_shadow WHERE usename = p_usename;
$$;

-- Выдаём execute только выделенной роли
REVOKE ALL ON FUNCTION pg_doorman_get_auth(TEXT) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_doorman_get_auth(TEXT) TO doorman_auth;

Затем используйте эту функцию в параметре query:

auth_query:
  query: "SELECT * FROM pg_doorman_get_auth($1)"
  user: "doorman_auth"
  password: "strong_password"

query

SQL-запрос для получения учётных данных. Должен возвращать колонку с именем passwd или password, содержащую MD5- или SCRAM-хеш. Если запрос возвращает ровно одну колонку, она используется независимо от имени. Любые лишние колонки игнорируются. В качестве плейсхолдера для имени пользователя используйте $1.

Пример: "SELECT passwd FROM pg_shadow WHERE usename = $1"

user

Имя пользователя PostgreSQL для executor-соединения, выполняющего auth-запросы.

password

Пароль executor-пользователя (открытым текстом). Может быть пустым, если сервер PostgreSQL использует аутентификацию trust для этого пользователя.

По умолчанию: "".

database

База для executor-соединений. Если не задана, используется имя пула.

По умолчанию: None (uses pool name).

workers

Число постоянных соединений с PostgreSQL, выделенных под выполнение SQL auth_query. Эти соединения открываются при старте и поддерживаются живыми. Они обрабатывают только поиск учётных данных — клиентский трафик данных идёт через отдельные соединения пула данных (pool_size). Увеличьте, если видите всплески задержки auth при высокой частоте подключений.

По умолчанию: 2.

server_user

Бэкенд-пользователь PostgreSQL для соединений с данными в dedicated mode. Когда задан, все динамически аутентифицированные пользователи разделяют один пул соединений, подключающийся под этим пользователем. Когда не задан, используется passthrough mode.

По умолчанию: None (passthrough mode).

server_password

Пароль server_user открытым текстом. Имеет смысл только когда задан server_user.

По умолчанию: None.

pool_size

Максимальное число бэкенд-соединений на каждый пул данных, создаваемый auth_query. Та же концепция, что и users[].pool_size для статически заданных пользователей. Сколько пулов будет создано, зависит от режима: server_user определяет, разделяют ли все динамические пользователи один пул или у каждого свой.

По умолчанию: 40.

min_pool_size

Минимальное число бэкенд-соединений, поддерживаемое в каждом пуле динамического пользователя в passthrough mode. Соединения прогреваются при первом создании пула и пополняются циклом retain. Установите 0, чтобы отключить (по умолчанию). Замечание: пулы с min_pool_size > 0 никогда не подвергаются garbage collection, и общее число бэкенд-соединений масштабируется как active_users × min_pool_size.

По умолчанию: 0.

cache_ttl

Максимальное время жизни кеша для успешно полученных учётных данных. Принимает строки продолжительности вроде "1h", "30m", "300s".

По умолчанию: "1h".

cache_failure_ttl

TTL кеша для записей «пользователь не найден» (negative cache). Предотвращает повторные запросы для несуществующих пользователей.

По умолчанию: "30s".

min_interval

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

По умолчанию: "1s".

Настройки пользователей пула

[pools.exampledb.users.0]
username = "exampledb-user-0" # Виртуальный пользователь, который может подключаться к этой виртуальной базе.

username

Имя пользователя, под которым клиенты подключаются к этому пулу. Должно быть уникальным в рамках пула.

password

Верификатор пароля для аутентификации клиента. Поддерживает форматы MD5, SCRAM-SHA-256 и JWT. Хеши паролей можно скопировать напрямую из PostgreSQL: SELECT usename, passwd FROM pg_shadow.

auth_pam_service

PAM-сервис, отвечающий за авторизацию клиента. В этом случае pg_doorman игнорирует значение password.

server_username

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

По умолчанию PgDoorman использует одно и то же username и для аутентификации клиента, и для серверных соединений, применяя passthrough authentication: криптографический материал из аутентификации клиента (MD5-хеш или SCRAM ClientKey) переиспользуется для аутентификации на бэкенде. Это устраняет потребность в server_password открытым текстом.

Passthrough mode (рекомендуется для пользователей с совпадающей идентичностью):

  • Опустите и server_username, и server_password
  • pg_doorman переиспользует доказательство аутентификации клиента для подключения к PostgreSQL
  • Для MD5: хеш из password используется напрямую
  • Для SCRAM: ClientKey извлекается из первой SCRAM-аутентификации клиента и кешируется
  • Требование: верификатор password должен совпадать с pg_authid на бэкенде (та же соль/итерации для SCRAM, тот же хеш для MD5)

Explicit credentials mode (когда идентичности различаются):

  • Установите server_username и server_password в реальные учётные данные PostgreSQL
  • server_password требует, чтобы server_username был задан
  • server_username без server_password допустим для аутентификации trust

server_password

Пароль открытым текстом для серверного пользователя PostgreSQL, указанного в server_username.

Когда server_password не задан и пользователь имеет право на passthrough (нет server_username или server_username равен username), PgDoorman использует passthrough authentication: криптографический материал из аутентификации клиента переиспользуется для бэкенд-соединения. Это убирает пароли открытым текстом из конфигурационных файлов.

server_password требует, чтобы server_username был задан.

pool_size

Максимальное число бэкенд-соединений с PostgreSQL для этого пользователя. В transaction mode соединения разделяются между клиентами, поэтому это значение обычно намного меньше числа клиентов. Аналог default_pool_size из PgBouncer, но настраивается per-user, а не глобально.

По умолчанию: 40.

min_pool_size

Минимальное число соединений, поддерживаемое в пуле для этого пользователя. Соединения прогреваются при старте (до первого цикла retain) и затем поддерживаются периодическим пополнением. Если задано, должно быть меньше или равно pool_size.

По умолчанию: None.

server_lifetime

Закрывать серверные соединения для этого пользователя, открытые дольше указанного значения, в миллисекундах. Применяется только к idle-соединениям. Если не задано, используется настройка server_lifetime пула.

По умолчанию: None (uses pool setting).

Passthrough Authentication

По умолчанию PgDoorman использует passthrough authentication: криптографическое доказательство клиента (MD5-хеш или SCRAM ClientKey) автоматически переиспользуется для аутентификации в PostgreSQL. Пароли открытым текстом в конфиге не нужны.

Задавайте server_username и server_password только когда бэкенд-пользователь PostgreSQL отличается от имени пользователя пула (например, переопределение имени пользователя или JWT-аутентификация):

users:
  - username: "app_user"              # имя для клиента
    password: "md5..."                # хеш для аутентификации клиента
    server_username: "pg_app_user"    # другой бэкенд-пользователь PostgreSQL
    server_password: "plaintext_pwd"  # пароль открытым текстом для этого пользователя