Подключение приложения: pg_hba.conf, SSL, пулы соединений

Рейтинг: 48.7% · 7 голосов
Подробный курс по PostgreSQL: SQL по демобазе, типы данных и JSONB, индексы, транзакции и MVCC, VACUUM, EXPLAIN и планировщик, роли и привилегии, репликация, бэкап, настройка под нагрузку и под 1С. Актуально на 2026.
Ответить
Аватара пользователя
Egor_DBA
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Подключение приложения: pg_hba.conf, SSL, пулы соединений

Сообщение Egor_DBA »

Оглавление курса (47)
  1. Что такое PostgreSQL: история, философия, где применяется
  2. Урок 1. Что нового в PostgreSQL 15 и далее (15 -> 16 -> 17)
  3. Установка и первый запуск: Linux, Windows, Docker
  4. psql детально: метакоманды и работа в консоли
  5. Демобаза Авиаперевозки Postgres Pro: структура и развёртывание
  6. SELECT: проекция, фильтрация, сортировка
  7. Транзакции и ACID
  8. Уровни изоляции транзакций: Read Committed, Repeatable Read, Serializable
  9. Соединения таблиц (JOIN)
  10. Агрегация: GROUP BY, HAVING, GROUPING SETS
  11. Подзапросы и CTE (WITH), рекурсия
  12. Оконные функции
  13. Изменение данных: INSERT/UPDATE/DELETE, UPSERT, MERGE
  14. Числовые и булевы типы, NULL и трёхзначная логика
  15. Строки, текст, дата и время, таймзоны
  16. Массивы, диапазоны, enum, составные типы
  17. JSON и JSONB: операторы и индексация
  18. DDL: CREATE TABLE, схемы, ALTER
  19. Ограничения целостности
  20. Представления и материализованные представления
  21. Последовательности, IDENTITY, генерируемые столбцы
  22. Индексы: B-tree и когда индекс не используется
  23. Типы индексов: Hash, GiST, SP-GiST, GIN, BRIN
  24. Продвинутые индексы: частичные, по выражению, покрывающие
  25. Обслуживание индексов и таблиц: bloat, REINDEX, CONCURRENTLY
  26. Полнотекстовый поиск
  27. Роли и пользователи
  28. Привилегии: GRANT/REVOKE
  29. Row-Level Security и безопасность данных
  30. Подключение приложения: pg_hba.conf, SSL, пулы соединений (вы здесь)
  31. Серверное программирование: функции и процедуры
  32. Триггеры и события
  33. Архитектура PostgreSQL: процессы и память
  34. MVCC: версии строк и видимость
  35. VACUUM, autovacuum, freeze и wraparound
  36. WAL, контрольные точки и долговечность
  37. Блокировки и взаимоблокировки
  38. Планировщик запросов
  39. EXPLAIN и EXPLAIN ANALYZE: чтение планов
  40. Конфигурация сервера: ключевые параметры
  41. Настройка под нагрузку и под 1С
  42. Параллельные запросы и партиционирование
  43. Резервное копирование и восстановление
  44. Репликация: потоковая и hot standby
  45. Логическая репликация и кластерные решения
  46. Внешние данные, расширения и сертификация
  47. Разбор планов запросов на explain.tensor.ru: глубокое чтение EXPLAIN ANALYZE
Урок 29. Подключение приложения: pg_hba.conf, SSL, пулы соединений

До этого урока мы сидели внутри базы и говорили SQL. Теперь смотрим снаружи: как приложение вообще попадает на сервер postgresql, кого пускать, по какому каналу и сколько коннектов держать открытыми. Тут три отдельных слоя, которые путают: на каком адресе сервер слушает (listen_addresses), кого и каким методом он пускает (pg_hba.conf), и как это шифруется (TLS/SSL). А поверх всего этого - пул соединений, без которого боевой бэкенд под нагрузкой просто положит базу. Разберём прод-подключение целиком, от сокета до PgBouncer.

Изображение

Как это работает

Когда клиент стучится в postgres, проверка идёт в два этапа, и их легко перепутать. Сначала надо физически дойти до порта - за это отвечает параметр listen_addresses в postgresql.conf. По умолчанию там localhost, то есть сервер слушает только себя, и удалённое приложение получит connection refused, даже не дойдя до пароля. Ставят listen_addresses = '*' (слушать все интерфейсы) и перезапускают сервер - этот параметр на лету не подхватывается.

Дальше начинается pg_hba.conf - host-based authentication, файл правил доступа. Каждая строка это запись вида: тип соединения, база, пользователь, адрес клиента, метод аутентификации. Сервер читает файл сверху вниз и применяет ПЕРВУЮ подходящую строку. Это ключевой момент: не самую точную, а первую совпавшую. Если она отказала - всё, второго шанса нет, до следующих строк дело не дойдёт.

Тип соединения определяет канал. local - это Unix-сокет (только с той же машины), host - TCP по обычному или шифрованному каналу, hostssl - только зашифрованный TLS, hostnossl - наоборот, только нешифрованный. На проде для внешних клиентов используют hostssl, чтобы пароль и данные не шли открытым текстом.

Метод аутентификации - самое важное поле. scram-sha-256 это современный стандарт: пароль не передаётся по сети даже в хешированном виде, идёт обмен вызов-ответ (challenge-response), и подслушанный трафик не даёт злоумышленнику войти. md5 - старый метод, его постепенно выкидывают, держите только для совместимости. peer работает лишь для local: postgres спрашивает у операционной системы, под каким юзером запущен процесс, и сверяет с именем роли - удобно для локального обслуживания без пароля. cert требует, чтобы клиент предъявил свой TLS-сертификат, которому доверяет сервер - аутентификация вообще без паролей. И помните про trust (пускать без проверки) и reject (всегда отказывать) - trust на сетевом интерфейсе это дыра, через которую входят без пароля.

SQL и примеры

Посмотреть, как сервер РАЗОБРАЛ свой pg_hba.conf, можно не открывая файл - есть системное представление:

Код: Выделить всё

SELECT line_number, type, database, user_name, address, auth_method
FROM pg_hba_file_rules
ORDER BY line_number;
Этот запрос показывает действующие правила так, как их видит сервер, и подсветит синтаксические ошибки в колонке error - очень помогает, когда клиент не пускает, а почему - непонятно.

Типичный боевой pg_hba.conf для приложения выглядит так (это содержимое файла, не SQL):

Код: Выделить всё

# TYPE  DATABASE   USER      ADDRESS          METHOD
local   all        postgres                   peer
hostssl bookings   app_user  10.0.0.0/24      scram-sha-256
hostssl bookings   readonly  10.0.0.0/24      scram-sha-256
host    all        all       0.0.0.0/0        reject
Локальное обслуживание идёт через peer без пароля, приложение из подсети 10.0.0.x ходит только по TLS со scram, а последняя строка явно отвергает всех остальных. Порядок важен: reject стоит в конце, иначе он перекрыл бы всё выше.

После правки файла перезапуск НЕ нужен - достаточно перечитать конфигурацию:

Код: Выделить всё

SELECT pg_reload_conf();
То же самое делают командой pg_ctl reload или сигналом SIGHUP процессу postgres. А вот listen_addresses, ssl и max_connections требуют именно рестарта сервера.

Проверить, что вы сидите внутри по шифрованному каналу:

Код: Выделить всё

SELECT ssl, version, cipher
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();
Запрос смотрит на текущее соединение и говорит, поднят ли TLS, какая версия протокола и шифр. Если ssl = false на проде - канал открыт, чините hostssl и sslmode.

Со стороны клиента шифрование требуют параметром sslmode. Строка подключения для приложения:

Код: Выделить всё

host=db.internal port=5432 dbname=bookings user=app_user sslmode=verify-full sslrootcert=/etc/ssl/ca.crt
Режим verify-full самый строгий: проверяет и сертификат сервера, и совпадение имени хоста - защита от подмены сервера (MITM). Слабые prefer и require шифруют, но не проверяют, кому вы отдаёте пароль.

Частые грабли
  • Поправили pg_hba.conf, но не перечитали конфиг - правила старые. reload, а не просто сохранить файл.
  • Забыли про порядок строк: широкое правило стоит выше узкого и перехватывает соединение раньше. Первая совпавшая строка - финальная.
  • listen_addresses оставили localhost и удивляются connection refused снаружи. Это не про пароль, это про сетевой доступ.
  • Открыли host all all 0.0.0.0/0 trust для удобства тестов и забыли убрать - вход без пароля из любой точки.
  • sslmode=require вместо verify-full: канал шифрован, но сервер никто не проверяет, MITM проходит.
  • Подняли max_connections до 2000 вместо пула. Каждый коннект postgres это отдельный процесс с памятью - сервер захлебнётся на переключениях контекста.
  • PgBouncer в transaction pooling, а приложение использует SET, подготовленные выражения на сессию или advisory-блокировки - они утекают между клиентами и ломаются.
Мини-лаба
  • Выполните SELECT * FROM pg_hba_file_rules; и найдите строку, по которой пускают вас сейчас.
  • Командой SHOW listen_addresses; и SHOW ssl; посмотрите, на каких адресах сервер слушает и включён ли TLS.
  • Создайте роль: CREATE ROLE app_user LOGIN PASSWORD 'secret'; и добавьте в pg_hba.conf строку host bookings app_user 127.0.0.1/32 scram-sha-256.
  • Перечитайте конфиг: SELECT pg_reload_conf(); - и снова загляните в pg_hba_file_rules, убедитесь, что ошибок нет.
  • Подключитесь новым пользователем: psql 'host=127.0.0.1 dbname=bookings user=app_user' и введите пароль.
  • Внутри проверьте канал: SELECT ssl FROM pg_stat_ssl WHERE pid = pg_backend_pid();
  • Замените метод на reject, сделайте reload и убедитесь, что вход теперь отклоняется - а потом верните scram-sha-256.
Контрольные вопросы
  • Чем отличаются listen_addresses и pg_hba.conf - за что отвечает каждый и в каком порядке срабатывают?
  • Почему scram-sha-256 безопаснее md5, если в обоих случаях пользователь вводит пароль?
  • По какому правилу сервер выбирает строку в pg_hba.conf, если подходят несколько?
  • Чем sslmode=require отличается от verify-full и почему второй важен на проде?
  • Зачем нужен пул соединений и в чём разница между transaction и session pooling в PgBouncer?
  • Какие изменения конфигурации применяются через reload, а какие требуют рестарта сервера?
👍4 ❤️3 🔥1 😄 🤔3
Аватара пользователя
nikita123
Сообщения: 1
Зарегистрирован: 29 май 2026, 23:27

Re: Подключение приложения: pg_hba.conf, SSL, пулы соединений

Сообщение nikita123 »

А если у меня приложение на 1С через ODBC - там sslmode тоже в строке подключения задаётся или это в самом драйвере крутить надо? Боюсь канал открытый окажется.
👍 ❤️ 🔥 😄 🤔3
Аватара пользователя
postgrespro
Сообщения: 1
Зарегистрирован: 13 май 2026, 03:26

Re: Подключение приложения: pg_hba.conf, SSL, пулы соединений

Сообщение postgrespro »

На своём опыте: словил баг с PgBouncer в transaction режиме - приложение делало SET search_path один раз на коннект, а оно слетало между запросами. Перевёл нужные сессии в session pooling и отпустило.
👍3 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Row-Level Security и безопасность данных
Следующая глава →
Серверное программирование: функции и процедуры

Все главы курса «PostgreSQL: от первого запроса до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «PostgreSQL: от первого запроса до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость