empty static

Аутентификация в PostgreSQL

PostgreSQL авторизация и безопасность: SCRAM, LDAP, сертификаты, RADIUS.

PostgreSQL поддерживает несколько способов аутентификации — от простых паролей до безопасных проверок системного пользователя и шифрованных соединений. Разные методы применимы в разных сценариях: где-то важна простота, где-то — безопасность. Этот материал продолжает руководство по установке PostgreSQL на Ubuntu Server 24.04 LTS и представляет разбор самых популярных подходов: когда использовать, как настроить, и какие есть плюсы и минусы.


1. Аутентификация по паролю

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

bash
копировать
psql -h localhost -U postgres -d mydb

Но у этого способа есть два минуса:

  • пароль может утечь, если хранится прямо в коде;
  • если соединение не защищено (sslmode=disable), пароль передаётся в открытом виде.

Best practices

  • Всегда используй sslmode=require или sslmode=verify-full, чтобы шифровать соединение.
  • Не пиши пароли прямо в код — используй ~/.pgpass.
  • Создавай отдельного пользователя для каждого сервиса с ограниченными правами.

Плюсы

  • Простая реализация и поддержка во всех клиентах.
  • Подходит для удалённых подключений и автоматизации.

Минусы

  • Требует безопасного хранения пароля.
  • Уязвим без SSL.

Examples

bash
копировать
# Пример подключения с параметрами шифрования
psql "host=db.local user=reporter dbname=metrics sslmode=require"

# Пример подключения внутри скрипта с export
export PGPASSWORD='secret'
psql -h db.example.com -U service_user -d production

2. Файл ~/.pgpass

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

text
копировать
localhost:5432:mydb:postgres:secret123

Допустимы подстановки с *:

text
копировать
*:*:*:postgres:secret123

Важно: файл должен быть доступен только текущему пользователю. Установи права:

bash
копировать
chmod 600 ~/.pgpass

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

bash
копировать
export PGPASSFILE='/some/another/path/to/file/.pgpass'

Best practices

  • Никогда не публикуй .pgpass или его содержимое.
  • Храни файл в домашней директории и ограничь права до 600.
  • Используй разные пароли для разных баз.

Плюсы

  • Удобство в скриптах, CI/CD, cron.
  • Не нужно хранить пароли в коде.

Минусы

  • Пароль всё равно хранится в незашифрованном виде.
  • Работает только с psql и совместимыми клиентами.

3. peer-аутентификация (локальная через Unix-сокет)

peer — это метод локальной аутентификации PostgreSQL, при котором имя пользователя берётся из Unix-сокет-соединения, и сервер сверяет его с разрешёнными правилами в pg_hba.conf. Вопреки мифу, имена системного и PostgreSQL-пользователя не обязаны совпадать — это можно явно задать в pg_ident.conf.

Простой пример из pg_hba.conf:

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer

Это означает: всем локальным пользователям можно подключаться ко всем базам, если имя Linux-пользователя совпадает с именем PostgreSQL-пользователя.

Для более гибкой настройки используется map:

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             mydbuser                                peer map=my_map

А соответствие задаётся в pg_ident.conf:

text
копировать
# MAPNAME       SYSTEM-USERNAME       PG-USERNAME
my_map          linuxuser             mydbuser

Теперь linuxuser может подключаться как mydbuser — без пароля и без совпадения имён.

bash
копировать
psql -U mydbuser -d mydb

Этот способ работает только при подключении через Unix-сокет (по умолчанию это /run/postgresql). Если ты хочешь протестировать его от имени другого системного пользователя, можно использовать:

bash
копировать
sudo -u linuxuser psql -U mydbuser -d mydb

Best practices

  • Используй peer только для локальных сервисов и скриптов.
  • Чётко настраивай pg_ident.conf, чтобы избежать путаницы.
  • Убедись, что системные пользователи надёжны и изолированы.

Плюсы

  • Нет паролей вообще.
  • Безопасно и быстро внутри одного сервера.

Минусы

  • Не работает по сети.
  • Требует точной настройки маппинга имён.

4. scram-sha-256: безопасная аутентификация по паролю

scram-sha-256 — это современный механизм парольной аутентификации, пришедший на смену устаревшему md5. Он используется в PostgreSQL начиная с версии 10 и является рекомендуемым методом для всех подключений, использующих пароли.

В отличие от md5, scram-sha-256:

  • не передаёт хэш пароля напрямую;
  • защищён от атак с перехватом;
  • использует солёные хэши и challenge-response механизм;
  • поддерживает обновление секретов без необходимости менять пароль.

Настройка

Файл pg_hba.conf:

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             0.0.0.0/0               scram-sha-256

Создание пароля в нужном формате:

sql
копировать
ALTER ROLE myuser WITH PASSWORD 'new_secure_password';

Проверь, что password_encryption = 'scram-sha-256' в postgresql.conf, чтобы пароль сохранялся в нужном формате.

Проверка:

sql
копировать
SELECT rolname, rolpassword FROM pg_authid WHERE rolname = 'myuser';

Пароль в формате SCRAM будет начинаться с $scram-sha-256$.

scram-sha-256 рекомендуется использовать вместе с sslmode=require или verify-full, чтобы дополнительно защитить канал передачи.

Best practices

  • Используй SCRAM только вместе с шифрованием соединения (SSL).
  • Обнови старые роли с md5 на SCRAM через ALTER ROLE.
  • Проверь поддержку на стороне клиента (например, JDBC).

Плюсы

  • Современный и безопасный.
  • Хэш пароля невозможно использовать повторно.

Минусы

  • Не поддерживается в некоторых старых клиентах.
  • Сложнее отладка по сравнению с md5.

Важно: sslmode и pg_hba.conf

Чтобы аутентификация с sslmode=require действительно работала, PostgreSQL должен быть готов принять SSL-соединение. Это регулируется через файл pg_hba.conf.

Если в нём нет строки с типом подключения hostssl, соединение с TLS может быть отвергнуто, даже если клиент запрашивает его. То же самое касается обратной ситуации: если указано hostnossl, SSL-соединения не допускаются вовсе.

Пример корректной строки:

text
копировать
# TYPE     DATABASE   USER     ADDRESS           METHOD
hostssl    all        all      0.0.0.0/0         scram-sha-256

Эта запись разрешает только шифрованные подключения с использованием scram-sha-256.

Если такой строки нет, попытка клиента подключиться с sslmode=require или sslmode=verify-full может завершиться ошибкой:

text
копировать
FATAL:  no pg_hba.conf entry for host "x.x.x.x", user "y", database "z", SSL on

Рекомендации:

  • Добавляй hostssl-правила в pg_hba.conf, если ожидаешь SSL-соединения от клиента.
  • Проверяй, чтобы у сервера была включена поддержка SSL (ssl = on в postgresql.conf), и настроены ssl_cert_file / ssl_key_file.

5. cert: аутентификация по клиентскому сертификату

Метод cert использует TLS-сертификаты для подтверждения личности клиента. Это самый безопасный способ аутентификации в PostgreSQL — без паролей, без маппинга с системным пользователем, только с помощью криптографических ключей.

Файл pg_hba.conf:

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
hostssl all             myuser          0.0.0.0/0               cert clientcert=1

Чтобы PostgreSQL знал, с кем он говорит, имя пользователя должно совпадать с Common Name (CN) из сертификата. Или можно использовать map:

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
hostssl all             myuser          0.0.0.0/0               cert clientcert=1 map=certmap

pg_ident.conf:

text
копировать
# MAPNAME       SYSTEM-USERNAME       PG-USERNAME
certmap         CN=andrey             myuser

Использование самоподписанных сертификатов

Если нет желания покупать CA-сертификаты, можно использовать self-signed. Важно, чтобы клиент доверял серверному сертификату.

Сервер:

bash
копировать
openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key -subj "/CN=mydb.local"
chmod 600 server.key
cp server.crt server.key /var/lib/postgresql/data/

Клиент:

bash
копировать
openssl req -new -x509 -days 365 -nodes -out client.crt -keyout client.key -subj "/CN=myuser"
cp server.crt ~/.postgresql/root.crt
cp client.crt ~/.postgresql/postgresql.crt
cp client.key ~/.postgresql/postgresql.key
chmod 600 ~/.postgresql/*

Подключение:

bash
копировать
psql "host=mydb.local sslmode=verify-full dbname=mydb user=myuser"

Если всё настроено верно — соединение установится без пароля, по сертификату.

Best practices

  • Храни приватные ключи в защищённой директории.
  • Используй самоподписанные только внутри безопасной сети.
  • Применяй разные сертификаты для разных клиентов.

Плюсы

  • Максимальная защита.
  • Нет паролей — невозможно перехватить.

Минусы

  • Сложность генерации и обновления сертификатов.
  • Требует настройки доверенных центров и путей.

6. trust: безусловное доверие (и почему это почти всегда плохая идея)

Метод trust в PostgreSQL означает буквально: «доверять всем». Если в pg_hba.conf указано trust, сервер разрешит подключение любому пользователю без пароля, если соединение удовлетворяет остальным условиям (IP-адрес, база данных, имя пользователя и т.д.).

Это самый небезопасный метод аутентификации. Он может быть полезен только в строго изолированных средах (например, при разработке или в контейнере без выхода наружу). Но в боевой системе его использование — практически всегда ошибка.

Best practices

  • Использовать только в dev-средах или изолированных контейнерах.
  • Ограничивать до 127.0.0.1/32, если используется вообще.
  • Никогда не открывать наружу.

Плюсы

  • Максимально удобно при отладке.
  • Никаких паролей или дополнительных настроек.

Минусы

  • Полное отсутствие безопасности.
  • Легко пропустить в проде.

Примеры настройки

text
копировать
# Разрешить всем локальным пользователям подключаться без пароля
local all all trust

# Разрешить доступ только с localhost без пароля
host all all 127.0.0.1/32 trust

# Полный доступ с определённой подсети (небезопасно!)
host all all 192.168.0.0/16 trust

# Пример из pg_hba.conf: разрешить доступ с 192.168.1.0/24
host all all 192.168.1.0/24 trust

7. md5: устаревший, но до сих пор встречающийся способ аутентификации

Метод md5 долгое время был стандартным способом парольной аутентификации в PostgreSQL. Он основан на простом принципе: пароль клиента хешируется с солью и сравнивается с сохранённым значением.

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             0.0.0.0/0               md5

Best practices

  • Использовать только с sslmode=require.
  • Постепенно мигрировать пользователей на scram-sha-256.
  • Проверять, какие роли ещё используют md5 через pg_authid.

Плюсы

  • Простая реализация.
  • Широкая поддержка даже в старых клиентах.

Минусы

  • Хеш можно перехватить и переиграть (replay).
  • Слабая криптостойкость алгоритма.

Examples

text
копировать
# Разрешить подключение по md5 с любого IP
host all all 0.0.0.0/0 md5

# Ограничение подключения только с localhost
host all all 127.0.0.1/32 md5
sql
копировать
-- Установка пароля для пользователя в формате md5
ALTER ROLE legacy_user WITH ENCRYPTED PASSWORD 'old_password';
sql
копировать
-- Проверка, какие пользователи используют md5
SELECT rolname, rolpassword FROM pg_authid WHERE rolpassword LIKE 'md5%';

8. ldap: централизованная аутентификация через внешнюю директорию

Метод ldap позволяет PostgreSQL передавать имя пользователя и пароль на внешний LDAP-сервер (например, Active Directory, OpenLDAP) для проверки подлинности.

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             10.0.0.0/8              ldap ldapserver=ldap.company.local ldapbasedn="dc=company,dc=local"

Best practices

  • Всегда используй TLS (ldaps://) или sslmode=require.
  • Убедись, что LDAP-сервер доступен и защищён.
  • Совмещай с внутренними ролями PostgreSQL.

Плюсы

  • Централизованное управление пользователями.
  • Не нужно дублировать пароли.

Минусы

  • Требует внешнего LDAP-сервера.
  • Нет управления ролями в самой базе.

Примеры настройки

text
копировать
# Подключение PostgreSQL к Active Directory с указанием bindDN
host all all 10.1.0.0/16 ldap ldapserver=ad.corp.local ldapbasedn="dc=corp,dc=local" ldapbinddn="cn=ldap-reader,dc=corp,dc=local" ldapbindpasswd=StrongPassword123

# Подключение к OpenLDAP без привязки (анонимный поиск DN)
host all all 10.2.0.0/16 ldap ldapserver=ldap.internal ldapbasedn="ou=people,dc=internal,dc=net"

# Пример с безопасным LDAPS-подключением (через 636 порт)
hostssl all all 192.168.10.0/24 ldap ldapserver=ldaps://secure.ldap.net ldapbasedn="dc=secure,dc=ldap,dc=net"

9. pam: подключение PostgreSQL к системной аутентификации

Метод pam позволяет PostgreSQL делегировать проверку логина и пароля системному механизму PAM (Pluggable Authentication Modules) в Linux.

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             127.0.0.1/32            pam pamservice=postgresql

Best practices

  • Используй только с host или hostssl, никогда с local. Почему? local использует Unix-сокеты и может не передавать достаточного контекста PAM-модулям. Это приводит к зависаниям, ошибкам или нестабильному поведению аутентификации.
  • Ограничивай IP и подключай модули только из доверенных источников.
  • Храни pam.d-конфигурации отдельно от общесистемных.

Плюсы

  • Поддержка OTP, биометрии, ключей и других PAM-модулей.
  • Централизованный контроль через ОС.

Минусы

  • Ошибки в PAM могут заблокировать всех.
  • Требует синхронизации системных и PostgreSQL-пользователей.

Examples

text
копировать
# Пример настройки подключения через PAM-службу 'pg_auth'
hostssl all all 127.0.0.1/32 pam pamservice=pg_auth
text
копировать
# Содержимое /etc/pam.d/pg_auth
# Однофакторная аутентификация по системному паролю
auth    required    pam_unix.so
account required    pam_unix.so
text
копировать
# Пример с двухфакторной аутентификаций через Google Authenticator
auth    required    pam_google_authenticator.so
auth    required    pam_unix.so
account required    pam_permit.so

10. radius: внешняя аутентификация через сетевой сервис

Метод radius позволяет PostgreSQL делегировать проверку имени и пароля внешнему RADIUS-серверу.

text
копировать
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             0.0.0.0/0               radius radiusserver=10.0.0.10 radiussecret=supersecret

Best practices

  • Не используй RADIUS без шифрования.
  • Убедись, что radiussecret недоступен в логах и бэкапах.
  • Храни резервные учётки в PostgreSQL на случай сбоя.

Плюсы

  • Централизованный аудит и контроль.
  • Интеграция с сетевыми политиками доступа.

Минусы

  • Не шифрует трафик между PostgreSQL и RADIUS.
  • Требует настройки и поддержки внешней инфраструктуры.

Examples

text
копировать
# Подключение всех пользователей с подсети через RADIUS
host    all             all             172.16.0.0/12           radius radiusserver=auth.local radiussecret=topsecret

# Пример ограничения подключения только к одной БД через RADIUS
host    finance_db      staff           192.168.1.0/24          radius radiusserver=10.1.1.1 radiussecret=s3cr3t