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

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

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

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

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

Метод аутентификации trast
Метод аутентификации trast (alex@deb:~$ psql -U postgres)

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

Конфигурационный файл отвечающий за настройки аутентификации — 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 - если - то
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;
 line_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:ffff:ffff:ffff:ffff:ffff:ffff: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:ffff:ffff:ffff:ffff:ffff:ffff: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- — —). Строки в нем просматриваются сверху вниз и используется первая найденная строка.

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

Когда вы используете метод аутентификации peer, cert, gss или 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. Таких сопоставлений (m2) две строчки, это означает что пользователь ОС student может подключиться только под ролью alice или bob.
  • Если идет подключение по сети, но с адреса сервера (samehost), то используется метод аутентификации md5 (по паролю).

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


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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *