PostgreSQL поддерживает несколько способов аутентификации — от простых паролей до безопасных проверок системного пользователя и шифрованных соединений. Разные методы применимы в разных сценариях: где-то важна простота, где-то — безопасность. Этот материал продолжает руководство по установке PostgreSQL на Ubuntu Server 24.04 LTS и представляет разбор самых популярных подходов: когда использовать, как настроить, и какие есть плюсы и минусы.
1. Аутентификация по паролю
Это базовый и самый распространённый способ. Клиент указывает имя пользователя и пароль при подключении. Такой метод удобен при подключении по сети или в случаях, когда база данных работает с внешними приложениями.
psql -h localhost -U postgres -d mydb
Но у этого способа есть два минуса:
- пароль может утечь, если хранится прямо в коде;
- если соединение не защищено (
sslmode=disable
), пароль передаётся в открытом виде.
Best practices
- Всегда используй
sslmode=require
илиsslmode=verify-full
, чтобы шифровать соединение. - Не пиши пароли прямо в код — используй
~/.pgpass
. - Создавай отдельного пользователя для каждого сервиса с ограниченными правами.
Плюсы
- Простая реализация и поддержка во всех клиентах.
- Подходит для удалённых подключений и автоматизации.
Минусы
- Требует безопасного хранения пароля.
- Уязвим без SSL.
Examples
# Пример подключения с параметрами шифрования
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 автоматически подставит оттуда пароль при подключении, если совпадают параметры хоста, порта, базы и пользователя.
localhost:5432:mydb:postgres:secret123
Допустимы подстановки с *
:
*:*:*:postgres:secret123
Важно: файл должен быть доступен только текущему пользователю. Установи права:
chmod 600 ~/.pgpass
Если вы не хотите размещать файл в домашней директории, то указать его расположение можно в системной переменной
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
:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
Это означает: всем локальным пользователям можно подключаться ко всем базам, если имя Linux-пользователя совпадает с именем PostgreSQL-пользователя.
Для более гибкой настройки используется map
:
# TYPE DATABASE USER ADDRESS METHOD
local all mydbuser peer map=my_map
А соответствие задаётся в pg_ident.conf
:
# MAPNAME SYSTEM-USERNAME PG-USERNAME
my_map linuxuser mydbuser
Теперь linuxuser
может подключаться как mydbuser
— без пароля и без совпадения имён.
psql -U mydbuser -d mydb
Этот способ работает только при подключении через Unix-сокет (по умолчанию это /run/postgresql
). Если ты хочешь протестировать его от имени другого системного пользователя, можно использовать:
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
:
# TYPE DATABASE USER ADDRESS METHOD
host all all 0.0.0.0/0 scram-sha-256
Создание пароля в нужном формате:
ALTER ROLE myuser WITH PASSWORD 'new_secure_password';
Проверь, что password_encryption = 'scram-sha-256'
в postgresql.conf
, чтобы пароль сохранялся в нужном формате.
Проверка:
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-соединения не допускаются вовсе.
Пример корректной строки:
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 0.0.0.0/0 scram-sha-256
Эта запись разрешает только шифрованные подключения с использованием scram-sha-256
.
Если такой строки нет, попытка клиента подключиться с sslmode=require
или sslmode=verify-full
может завершиться ошибкой:
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
:
# TYPE DATABASE USER ADDRESS METHOD
hostssl all myuser 0.0.0.0/0 cert clientcert=1
Чтобы PostgreSQL знал, с кем он говорит, имя пользователя должно совпадать с Common Name (CN) из сертификата. Или можно использовать map:
# TYPE DATABASE USER ADDRESS METHOD
hostssl all myuser 0.0.0.0/0 cert clientcert=1 map=certmap
pg_ident.conf
:
# MAPNAME SYSTEM-USERNAME PG-USERNAME
certmap CN=andrey myuser
Использование самоподписанных сертификатов
Если нет желания покупать CA-сертификаты, можно использовать self-signed. Важно, чтобы клиент доверял серверному сертификату.
Сервер:
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/
Клиент:
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/*
Подключение:
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
, если используется вообще. - Никогда не открывать наружу.
Плюсы
- Максимально удобно при отладке.
- Никаких паролей или дополнительных настроек.
Минусы
- Полное отсутствие безопасности.
- Легко пропустить в проде.
Примеры настройки
# Разрешить всем локальным пользователям подключаться без пароля
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. Он основан на простом принципе: пароль клиента хешируется с солью и сравнивается с сохранённым значением.
# 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
# Разрешить подключение по md5 с любого IP
host all all 0.0.0.0/0 md5
# Ограничение подключения только с localhost
host all all 127.0.0.1/32 md5
-- Установка пароля для пользователя в формате md5
ALTER ROLE legacy_user WITH ENCRYPTED PASSWORD 'old_password';
-- Проверка, какие пользователи используют md5
SELECT rolname, rolpassword FROM pg_authid WHERE rolpassword LIKE 'md5%';
8. ldap
: централизованная аутентификация через внешнюю директорию
Метод ldap
позволяет PostgreSQL передавать имя пользователя и пароль на внешний LDAP-сервер (например, Active Directory, OpenLDAP) для проверки подлинности.
# 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-сервера.
- Нет управления ролями в самой базе.
Примеры настройки
# Подключение 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.
# 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
# Пример настройки подключения через PAM-службу 'pg_auth'
hostssl all all 127.0.0.1/32 pam pamservice=pg_auth
# Содержимое /etc/pam.d/pg_auth
# Однофакторная аутентификация по системному паролю
auth required pam_unix.so
account required pam_unix.so
# Пример с двухфакторной аутентификаций через Google Authenticator
auth required pam_google_authenticator.so
auth required pam_unix.so
account required pam_permit.so
10. radius
: внешняя аутентификация через сетевой сервис
Метод radius
позволяет PostgreSQL делегировать проверку имени и пароля внешнему RADIUS-серверу.
# 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
# Подключение всех пользователей с подсети через 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