Если PostgreSQL «вдруг не пускает», в большинстве случаев всё упирается в pg_hba.conf. Это файл правил Host-Based Authentication, который решает: кому, откуда, к какой базе и каким способом можно подключаться. Именно здесь рождаются и победы, и классика жанра: no pg_hba.conf entry, «пускает локально, но не по сети», «md5 не работает», «как включить scram-sha-256».
Ниже — практичный разбор синтаксиса, порядка применения правил, актуальных методов аутентификации и набор рецептов для админов/DevOps, чтобы быстро привести доступ в порядок и не открыть базу «на весь интернет».
Где лежит pg_hba.conf и как понять, какой файл используется
Сначала убедитесь, что вы правите тот самый файл. Узнать путь можно из самой базы:
psql -U postgres -d postgres -c "SHOW hba_file;"
Заодно полезно посмотреть основной конфиг и каталог данных:
psql -U postgres -d postgres -c "SHOW config_file;"
psql -U postgres -d postgres -c "SHOW data_directory;"
На Debian/Ubuntu часто встречаются пути вида /etc/postgresql/<version>/main/pg_hba.conf, а на RHEL-подобных — /var/lib/pgsql/<version>/data/pg_hba.conf. Но полагаться на «обычно» не стоит: контейнеры, кастомные инсталляции и managed-окружения легко меняют расположение.
Как PostgreSQL читает правила: главное, что ломает ожидания
pg_hba.conf — это список правил сверху вниз. Срабатывает первое подходящее правило, дальше PostgreSQL не идёт. Поэтому порядок строк критичен: «широкие» разрешения, поставленные выше «узких», будут перехватывать трафик.
Правило «разрешить всё» в начале файла почти всегда означает, что все последующие ограничения не работают. В
pg_hba.confбезопасность начинается с порядка строк.
Ещё два частых источника сюрпризов:
- Тип подключения:
local(через Unix-сокет) иhost/hostssl(TCP) — это разные «миры». Настроилиlocalи удивились, что по сети не пускает — это нормально. - Локальное подключение по TCP: если клиент подключается к
127.0.0.1илиlocalhost(и реально использует TCP), правилоlocalне сработает; нуженhostдля127.0.0.1/32или::1/128.

Синтаксис pg_hba.conf: разбор колонок на человеческом
Упрощённо строка выглядит так:
<type> <database> <user> <address> <auth-method> [auth-options]
Ключевые поля:
type— тип соединения:local,host,hostssl,hostnossl.database— к каким БД применимо: имя базы,all,replication, иногдаsameuser/samerole(зависит от версии и контекста).user— пользователь/роль: конкретное имя,all, группы ролей (через+).address— источник: CIDR-сеть (10.0.0.0/24), одиночный IP (10.0.0.5/32),samehost,samenet. Дляlocalадреса нет.auth-method— метод аутентификации:peer,md5,scram-sha-256и др.
Комментарии начинаются с #. Пустые строки игнорируются.
Методы аутентификации: peer, md5 и scram-sha-256 — что выбирать
peer: удобно и безопасно для локального администрирования
peer работает только для local-подключений через Unix-сокет и сопоставляет системного пользователя Linux с ролью PostgreSQL. Типичный сценарий: пользователь postgres в системе может зайти в psql как роль postgres без пароля.
Пример (локальный сокет):
local all postgres peer
Плюсы: нет паролей в скриптах, минимальная поверхность атаки. Минусы: не подходит для удалённых подключений.
md5: «старый стандарт», но не лучший выбор для новых установок
md5 — это challenge-response на основе MD5. Работает почти со всеми клиентами, но считается устаревшим по криптографическим причинам. На новых кластерах лучше не закладываться на md5, если нет жёсткой необходимости (например, очень старые драйверы).
Важно: параметр password_encryption влияет на то, как будут храниться новые пароли. Если у вас включён scram-sha-256, а в pg_hba.conf стоит md5, это обычно всё равно работает, но в миграциях и смешанных средах может создавать путаницу. Лучше держать метод единообразным.
scram-sha-256: актуальный вариант для TCP-доступа
scram-sha-256 — современный механизм аутентификации (SCRAM), который устойчивее к ряду атак и является рекомендуемым вариантом для TCP-доступа в новых версиях PostgreSQL.
Пример (доступ к конкретной базе из подсети):
host appdb appuser 10.10.0.0/16 scram-sha-256
Чтобы новые пароли создавались в SCRAM-формате, проверьте:
psql -U postgres -d postgres -c "SHOW password_encryption;"
Если нужно изменить (и вы понимаете последствия), делают в postgresql.conf:
password_encryption = 'scram-sha-256'
После смены способа хранения паролей старые пароли не «перешифруются» автоматически: их нужно переустановить (например, ALTER ROLE ... PASSWORD ...), чтобы они сохранились в новом формате.
Типовые рецепты: безопасные правила для реальной жизни
1) Локально: админ через peer, остальные — по паролю
Частый подход: роль postgres — только peer, остальные локальные пользователи — по паролю.
local all postgres peer
local all all scram-sha-256
Так вы не храните пароль суперпользователя в истории команд, но разработческие утилиты всё равно смогут подключаться локально с паролем.
2) Доступ приложений по сети только из подсети
Для продакшена старайтесь «сужать» правила: конкретная база, конкретная роль, конкретная подсеть.
host appdb appuser 10.20.30.0/24 scram-sha-256
Если приложение работает на том же сервере, но подключается по TCP, добавьте loopback:
host appdb appuser 127.0.0.1/32 scram-sha-256
host appdb appuser ::1/128 scram-sha-256
3) Запрет «по умолчанию» в конце файла
Явный запрет в конце помогает диагностике: вы сразу видите в логах, что сработало правило отказа, а не «не нашлось подходящей строки».
host all all 0.0.0.0/0 reject
host all all ::/0 reject
Но это работает только если выше есть нужные разрешающие строки.
Ошибка no pg_hba.conf entry: что она означает и как чинить быстро
Сообщение no pg_hba.conf entry означает, что сервер не нашёл ни одного правила, подходящего под комбинацию:
- тип подключения (local/TCP/SSL);
- IP клиента;
- имя базы;
- пользователь.
Это не «неверный пароль». Это «для вас не описано правило доступа».
Шаг 1. Смотрите точную причину в логах PostgreSQL
Обычно в логах будет строка с деталями, например с IP и именем пользователя. На systemd-системах удобно так:
journalctl -u postgresql -n 200 --no-pager
Либо смотрите файл логов, если настроено файловое логирование (через log_directory, log_filename).
Шаг 2. Проверьте, тем ли протоколом идёт подключение (local vs host)
Если вы ожидаете, что сработает local, но клиент соединяется по TCP (например, указали -h 127.0.0.1), нужна строка host.
Шаг 3. Проверьте порядок правил
Очень частая ситуация: вы добавили разрешение, но выше стоит более раннее правило reject или правило для той же сети/пользователя с неподходящим методом. Помните: первое совпадение решает.
Шаг 4. Перезагрузите конфиг правильно
pg_hba.conf читается при reload, перезапуск сервиса обычно не нужен:
psql -U postgres -d postgres -c "SELECT pg_reload_conf();"
Или через systemd:
systemctl reload postgresql
Проверяйте логи после reload: если в файле ошибка синтаксиса, PostgreSQL может оставить старую конфигурацию.

Когда «пароль неверный», хотя вы уверены: md5 vs scram-sha-256
Путаница вокруг md5 и scram-sha-256 обычно проявляется так: клиент пишет «password authentication failed», а вы «точно вводите правильно».
Что проверить:
- Какой метод реально применяется: опирайтесь на IP/пользователя из лога ошибки и сопоставляйте с конкретной строкой HBA. Если у вас включено логирование с указанием HBA-строки в сообщениях, диагностика ещё проще.
- Формат пароля роли: посмотрите, каким алгоритмом хранится пароль (доступно суперпользователю):
psql -U postgres -d postgres -c "SELECT rolname, rolpassword FROM pg_authid WHERE rolname IN ('appuser');"
Если значение начинается с SCRAM-SHA-256$ — это SCRAM. Если с md5 — MD5. В смешанных средах обычно проще привести к единообразию: выбрать scram-sha-256 в pg_hba.conf и переустановить пароли ролям.
host, hostssl и TLS: почему правило не срабатывает
Если вы используете hostssl, правило применится только к TLS-соединениям. Если клиент подключается без шифрования, вы получите отказ или no pg_hba.conf entry (если нет подходящего hostnossl/host).
Практический шаблон: принудить TLS для удалённой сети и закрыть «нешифрованный» вариант:
hostssl appdb appuser 10.20.30.0/24 scram-sha-256
host all all 10.20.30.0/24 reject
Если вы только планируете включать TLS на PostgreSQL, заранее продумайте выпуск и установку сертификатов. Для инфраструктуры, где важна совместимость и доверенная цепочка, часто удобнее использовать коммерческие SSL-сертификаты и дальше уже настраивать ssl_cert_file и ssl_key_file на сервере.
Отладка как у взрослого: тестируем доступ без угадываний
Понять, слушает ли PostgreSQL сеть
Даже идеальный pg_hba.conf не поможет, если PostgreSQL не слушает внешний интерфейс. Быстро проверяем:
psql -U postgres -d postgres -c "SHOW listen_addresses;"
psql -U postgres -d postgres -c "SHOW port;"
И на уровне ОС:
ss -lntp | grep 5432
Проверить, какое соединение использует psql
Сравните:
psql -U appuser -d appdb
psql -U appuser -d appdb -h 127.0.0.1
psql -U appuser -d appdb -h ::1
Первый вариант обычно идёт через Unix-сокет (значит работают правила local), второй и третий — TCP (нужны правила host).
Если подключений много: проверьте, не вмешивается пулер
Когда между приложением и базой стоит пулер (например, PgBouncer), IP «клиента» для PostgreSQL может оказаться IP самого пулера, а не приложения. В таком случае правки нужно делать под фактический источник соединений, а схему аутентификации согласовать с пулером.
Если тема актуальна, держите шпаргалку по настройке: настройка PgBouncer и пуллинга соединений PostgreSQL.
Мини-чеклист: как не сделать «дырку» в доступе
- Не используйте широкие правила
host all all 0.0.0.0/0без крайней необходимости. - Сужайте по трём измерениям: база, роль, сеть.
- Выбирайте
scram-sha-256как дефолт для удалённого доступа;md5— только ради совместимости. - Держите
peerдля локального администрирования, если у вас нормальная дисциплина доступа к серверу. - После правок делайте reload и сразу проверяйте логи на ошибки синтаксиса.
Пример «здорового» pg_hba.conf для небольшого сервера
Ниже — пример, который часто подходит под «одна база под приложение + админка». Подстройте под свои роли/сети:
# Локальный суперпользователь — только peer
local all postgres peer
# Локальные подключения приложений/утилит — по SCRAM
local all all scram-sha-256
# Приложение по TCP (например, с backend-сети)
host appdb appuser 10.20.30.0/24 scram-sha-256
# Локальный TCP (если приложение соединяется через 127.0.0.1)
host appdb appuser 127.0.0.1/32 scram-sha-256
host appdb appuser ::1/128 scram-sha-256
# Явный запрет всего остального
host all all 0.0.0.0/0 reject
host all all ::/0 reject
Эта схема делает поведение предсказуемым: либо есть явное разрешение, либо явный отказ, и вы быстро понимаете, куда смотреть.
Итоги
pg_hba.conf — главный маршрутизатор политик доступа PostgreSQL. Держите в голове три вещи: первое подходящее правило выигрывает, local не равно host, а scram-sha-256 — современная база для аутентификации по сети. Если видите no pg_hba.conf entry, это почти всегда означает: не тот тип подключения, не та сеть или не тот порядок правил.
Когда приведёте файл к аккуратной структуре (узкие разрешения сверху, явный запрет снизу), проблемы с доступом начинают решаться за минуты, а не за часы.


