Методы аутентификации в PostgreSQL

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

Процесс подключения

Процесс подключение можно разделить на три этапа:

  • Идентификация — определение имени роли базы данных.
  • Аутентификация — проверка того, что пользователь тот за кого себя выдаёт. Есть много разных методов аутентификации, например проверка пароля.
  • Авторизация — проверка прав этого пользователя. Например может ли этот пользователь подключаться к этой базе данных или нет.

Настройки по умолчанию используется метод аутентификации trast, который позволяет подключаться без аутентификации любым локальным пользователям.

Метод аутентификации trast

Основные настройки

Конфигурационный файл отвечающий за настройки аутентификации —  pg_hba.conf . Он находится в каталоге PGDATA:

postgres@s-pg13:~$ ls -l $PGDATA/pg_hba.conf
-rw------- 1 postgres postgres 4760 июн 21 15:15 /usr/local/pgsql/data/pg_hba.conf

Его местоположение можно изменить задав параметр hba_file в конфигурационном файле postgresql.conf:

postgres@s-pg13:~$ cat $PGDATA/postgresql.conf | grep hba
#hba_file = 'ConfigDir/pg_hba.conf'     # host-based authentication file

При изменении этого файла конфигурацию сервера нужно перечитать, выполнив:

  • pg_ctl reload — из операционной системы;
  • SELECT pg_reload_conf(); — если вы подключены к СУБД.

Если вы подключены к СУБД, то узнать местоположение файла можно таким способом:

postgres@s-pg13:~$ psql
Timing is on.
psql (13.3)
Type "help" for help.

postgres@postgres=# SHOW hba_file;
             hba_file
-----------------------------------
 /usr/local/pgsql/data/pg_hba.conf
(1 row)
Time: 0,740 ms

Файл pg_hba.conf состоит из строк, а строки состоят из следующих полей:

  • тип подключения;
  • имя БД;
  • имя пользователя;
  • адрес узла;
  • метод аутентификации;
  • необязательные дополнительные параметры в виде имя=значение. Эти параметры нужны некоторым методам аутентификации.

Эти строки обрабатываются сверху вниз и применяется первая найденная строка. Таким образом если тип подключенияимя БДимя пользователя и адрес сервера совпали, то применяется определённый метод аутентификации.

pg_hba - если-то

При подключении выполняется аутентификация и проверяется привилегия CONNECT. Если результат отрицательный, доступ запрещается и строки ниже не рассматриваются. Если ни одна запись не подошла, доступ запрещается. Таким образом записи должны идти сверху вниз от частного к общему.

Вот пример файла pg_hba.conf, который создаётся при сборке из исходников:

# TYPE  DATABASE      USER    ADDRESS          METHOD
local   all           all                      trust
host    all           all     127.0.0.1/32     trust
host    all           all     ::1/128          trust
local   replication   all                      trust
host    replication   all     127.0.0.1/32     trust
host    replication   all     ::1/128          trust

Первая строчка это тип подключения local, в котором используется локальный unix сокет, и не задействована сеть. При таком подключении все пользователи (all) могут подключаться методом trust. О методах поговорим позже.

Третья и четвёртая строки относятся к tcp подключениям (host). При таком подключении все пользователи могут подключаться только из локального хоста 127.0.0.1/32 или ::1/128 используя метод trust.

Последние три строки относятся к репликации. Репликация возможна по сокету (local) и по сети (host) но только с локального хоста 127.0.0.1/32 или ::1/128. Здесь тоже используется метод trust.

Если вы подключены к СУБД, то сможете посмотреть содержимое файла pg_hba.conf с помощью представления pg_hba_file_rules:

postgres@postgres=# SELECT * FROM pg_hba_file_rules;
number|type |database     |user_name|address  | netmask       |auth_method|options| error
------+-----+-------------+---------+---------+---------------+-----------+-------+-------
88    |local|{all}        |{all}    |         |               |trust      |       |
90    |host |{all}        |{all}    |127.0.0.1|255.255.255.255|trust      |       |
92    |host |{all}        |{all}    |::1      |ffff:...       |trust      |       |
95    |local|{replication}|{all}    |         |               |trust      |       |
96    |host |{replication}|{all}    |127.0.0.1|255.255.255.255|trust      |       |
97    |host |{replication}|{all}    |::1      |ffff:...       |trust      |       |
(6 rows)
Time: 2,006 ms

Если в строке допущена ошибка, то это представление в поле error покажет ошибку.

Параметры подключения

Теперь рассмотрим параметры подключений!

Типы подключений:

  • local — использует unix сокет;
  • host — использует TCP/IP, оно может быть шифрованным с помощью SSL или не шифрованным;
  • hostssl — только зашифрованный TCP/IP;
  • hostnossl — только не зашифрованный TCP/IP.

Имя базы данных:

  • all — подключение к любой БД;
  • sameuser — БД, совпадающая по имени с ролью;
  • samerole — БД, совпадающая по имени с ролью или группой, в которую она входит;
  • replication — специальное разрешение для протокола репликации;
  • имя базы данных — имя конкретной базы данных, или через запятую можно перечислить список баз данных.

Адрес узла:

  • all — любой IP-адрес;
  • ip-адресс — конкретный ip адрес, подсеть, или диапазон (172.20.143.0/24 или 172.20.143.0 255.255.255.0)
  • samehost — означает адрес сервера с которого ведётся подключение, аналог 127.0.0.1;
  • samenet — означает любой ip адрес из подсети сервера;
  • доменное имя (или часть доменного имени, начиная с точки) — при этом postgresql проверяет ip-адрес подключающегося клиента на принадлежность к этому домену.

Имя роли:

  • all — любая роль;
  • <имя роли> — роль с указанным именем, при этом можно перечислить роли через запятую;
  • +<имя роли> — групповая роль, в которую включены другие роли.

Тип аутентификации:

  • Аутентификация без проверок:
    • trust — разрешает подключение без аутентификации, то есть без проверки пароля или любых других проверок;
    • reject — запрещает подключение ничего не проверяя;
  • Аутентификация по паролю:
    • md5 — пароль хранится в СУБД и шифруется MD5;
    • scram-sha-256 — пароль хранится в СУБД, используется протокол SCRAM (более надёжно);
    • ldap [параметры] — пароль хранится на сервере LDAP;
    • radius [параметры] — пароль хранится на сервере RADIUS;
    • pam [параметры] — пароль хранится в подключаемом модуле PAM;
  • Внешняя аутентификация:
    • peer [map=…] — запрашивает имя пользователя у операционной системы (только для Linux и только для локальных подключений);
    • cert [map=…] — аутентификация с использованием клиентского SSL-сертификата;
    • gss [map=…] — аутентификация Kerberos по протоколу GSSAPI;
    • sspi** [map=…] — аутентификация Kerberos/NTLM для Windows.

Пароль в СУБД

Пароль хранится в СУБД в зашифрованном виде при использовании методов аутентификации md5 и scram-sha-256.

Задать пароль роли при её создании можно так:

CREATE ROLE ... PASSWORD '<пароль>';

Создать пароль для уже существующей роли можно так:

ALTER ROLE ... PASSWORD '<пароль>';

Пользователю с пустым паролем будет отказано в доступе при аутентификации по паролю.

Пароли в зашифрованном виде хранятся в системном каталоге, в таблице pg_authid.

При аутентификации пароль можно вводить вручную, но не всегда это удобно. Еще можно установить переменную $PGPASSWORD на клиенте, в неё нужно задать пароль, тогда утилита psql будет использовать пароль из этой переменной. Но это не очень удобно и не безопасно.

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

узел:порт:база_данных:имя_пользователя:пароль
например:
192.168.0.5:5432:postgres:alice:12345

Такой файл должен иметь права 600 (rw- --- ---). Строки в нем просматриваются сверху вниз и используется первая найденная строка.

Сопоставление имен

Когда вы используете метод аутентификации peercertgss или sspi вам нужно сопоставить имя пользователя в ОС и имя роли в СУБД. Это делается с помощью конфигурационного файла  pg_ident.conf . Этот файл также состоит из строчек, строчки состоят из полей.

Поля в этом файле такие:

  • Название соответствия — оно затем прописывается в параметре map в файле pg_hba.conf;
  • Внешнее имя, или регулярное выражение;
  • Внутреннее имя роли базы данных.

Вот пример:

pg_hba.conf
# TYPE  DATABASE  USER  ADDRESS   METHOD
hostssl sameuser  all   all       cert map=m1
local   all       all             peer map=m2
host    all       all   samehost  md5

pg_ident.conf
# MAPNAME SYSTEM-USERNAME       PG-USERNAME
m1        /^(.*)@domain\.com$   \1
m2        student               alice
m2        student               bob

В примере выше записано следующие настройки:

  • Если идет шифрованное соединение, то разрешается подключаться к одноименной базе с именем пользователя. При этом используется метод аутентификации по сертификату с сопоставлением имен m1. Это сопоставление вытаскивает имя из сертификата и если оно соответствует регулярному выражению /^(.*)@domain.com$, то первая часть имени (до @domain.com) будет именем роли.
  • Если идет локальное соединение по сокету, то разрешается подключаться всем с помощью метода идентификации peer. При этом используется сопоставление имён m2. Таких сопоставлений две строчки, это означает что пользователь ОС student может подключиться только под ролью alice или bob.
  • Если идет подключение по сети, но с адреса сервера (samehost), то используется метод аутентификации md5 (по паролю).

Подробнее про аутентификацию можете почитать  тут .


Если понравилась статья, подпишись на мой канал в  VK  или  Telegram .