Рассмотрим процесс подключения к базам данных, методы подключения и аутентификации в PostgreSQL, а также сопоставление пользователей ОС и ролей БД.
Процесс подключения
Процесс подключение можно разделить на три этапа:
- Идентификация — определение имени роли базы данных.
- Аутентификация — проверка того, что пользователь тот за кого себя выдаёт. Есть много разных методов аутентификации, например проверка пароля.
- Авторизация — проверка прав этого пользователя. Например может ли этот пользователь подключаться к этой базе данных или нет.
Настройки по умолчанию используется метод аутентификации 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 состоит из строк, а строки состоят из следующих полей:
- тип подключения;
- имя БД;
- имя пользователя;
- адрес узла;
- метод аутентификации;
- необязательные дополнительные параметры в виде имя=значение. Эти параметры нужны некоторым методам аутентификации.
Эти строки обрабатываются сверху вниз и применяется первая найденная строка. Таким образом если тип подключения, имя БД, имя пользователя и адрес сервера совпали, то применяется определённый метод аутентификации.
При подключении выполняется аутентификация и проверяется привилегия 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 (по паролю).
Подробнее про аутентификацию можете почитать тут.
Добрый день. У Вас в предложении «Настройки по умолчанию используется метод аутентификации trast…» и далее по тексту, опечатка. Правильно trust.
Вдруг Вы надумаете обновить курс до более поздней версии PostgreSQL, заодно опечатку исправите )