Методы аутентификации
Подключение и аутентификация
16
Авторские права
© Postgres Professional, 2017–2026
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Алексей Береснев
Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Процедура подключения
Параметры подключения
Простая аутентификация
Аутентификация по паролю
Аутентификация средствами ОС
3
Процедура подключения
Процедура подключения
Задачи при подключении
Основные настройки
Схема обработки конфигурационного файла
4
Процедура подключения
клиент
PostgreSQL
PostgreSQL
postmaster
backend
При подключении к серверу клиент отправляет сообщение процессу
postmaster.
PostmasterVпринимает соединение и сразу же порождает для его
обслуживания отдельный процесс (backend). С этого момента клиент
обменивается сообщениями не с postmaster, а со своим
обслуживающим процессом. Таким образом, попытка соединения не
требует от postmaster много ресурсов, что снижает вероятность его
отказа.
5
Задачи при подключении
log_connections
log_hostname
log_line_prefix
PostgreSQL
PostgreSQL
postmaster
backend
клиент
идентификация
аутентификация
авторизация
Клиент направляет серверу стартовый пакет, содержащий параметры
соединения, после чего обслуживающий процесс выполняет несколько
задач.
Во-первых, он идентифицирует пользователя, то есть определяет его
имя в базе данных. Оно может отличаться от переданного клиентом
(например, если клиент представился именем в ОС).
Во-вторых, он аутентифицирует пользователя, то есть проверяет, что
он действительно тот, за кого себя выдает. Например, просит ввести
пароль.
В-третьих, он авторизует пользователя, то есть определяет, имеет ли
тот право подключения (эта задача пересекается с функционалом
привилегий).
Иногда все три задачи называют общим словом «аутентификация».
Принимая решение о возможности подключения, сервер при
необходимости обменивается с клиентом дополнительными
сообщениями. Если подключение разрешено, обслуживающий процесс
начинает сеанс, формирует структуры данных в локальной памяти
и т. д. Если же подключение запрещено, обслуживающий процесс
завершается.
Мониторинг процесса подключения возможен с помощью журнала
сообщений. Для этого рекомендуется настроить параметры, указанные
на слайде.
6
Основные настройки
pg_hba.conf
конфигурационный файл, при изменении нужно перечитать
строка — набор полей, разделитель — пробел или табуляция
пустые строки и текст после # игнорируются
Поля
тип подключения
имя базы данных
имя пользователя
адрес узла
метод аутентификации
необязательные дополнительные параметры в виде имя=значение
параметры подключения
Настройки аутентификации хранятся в конфигурационном файле,
который используется подобно postgresql.conf, но отличается от него по
формату. Файл называется pg_hba.conf (от «host-based authentication»),
его расположение определяется параметром hba_file. Он генерируется
при создании кластера баз данных командой initdb.
Файл pg_hba.conf содержит строки настройки аутентификации, каждая
из которых считается отдельной записью.
Пустые строки и комментарии (все после символа #) игнорируются.
Каждая запись состоит из полей, разделенных пробелами или
табуляциями. Количество полей может различаться в зависимости от их
содержимого, общий список приведен на слайде.
В случае, если запись в pg_hba.conf получается длинной и неудобной
для восприятия, ее можно разбить на несколько строк, вставляя
непосредственно перед переводом строки символ обратной косой
черты \. Такая запись, состоящая из нескольких строк, читается как
единое целое.
Также можно подключать дополнительные файлы настроек
аутентификации с помощью директив include, include_if_exists или
include_dir.
При изменении pg_hba.conf необходимо перечитать настройки
с помощью pg_ctl reload или вызовом функции pg_reload_conf.
7
Схема обработки
Записи просматриваются сверху вниз
Применяется первая запись, которой соответствует
подключение (тип, база, пользователь и адрес)
выполняется аутентификация и проверка привилегии CONNECT
если результат отрицательный, доступ запрещается
если ни одна запись не подошла, доступ запрещается
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
Когда клиент пытается установить соединение, серверу известны
параметры подключения: тип (локально или по сети), запрашиваемое
имя базы данных, имя пользователя, в случае подключения по сети —
IP-адрес клиента. Обслуживающий процесс последовательно
проверяет записи файла pg_hba.conf на соответствие этим параметрам.
Если подходящая запись нашлась, выполняется аутентификация
указанным в ней методом. При успешной аутентификации подключение
разрешается, иначе — запрещается (следующие записи при этом уже
не рассматриваются).
Если ни одна из записей не подошла, то доступ запрещается.
Записи в файле pg_hba.conf должны идти сверху вниз от частного
к общему. Иначе запись более общего вида сработает раньше и до
частного случая дело не дойдет.
В примере на слайде видно три строки:
●
первая относится к локальным подключениям (local) через Unix-сокет
для любых баз (all) и пользователей (all);
●
вторая и третья относятся к подключениям (host) через
закольцовывающий (loopback) сетевой интерфейс (которому
соответствует имя хоста localhost) по адресам IPv4 127.0.0.1/32 и
IPv6 ::1/128.
В такой конфигурации PostgreSQL допускает соединения только
с локального компьютера через Unix-сокет или loopback-интерфейс.
Далее возможные значения полей рассматриваются более подробно.
9
Параметры подключения
Тип подключения
Базы данных
Пользователи
Адреса узлов
10
Тип подключения
local
локальное подключение через Unix-сокет
host
сетевое подключение по TCP/IP
listen_addresses = localhost
hostssl, hostnossl
сетевое подключение по TCP/IP с SSL-шифрованием и без него
В поле типа подключения можно задать одно из значений:
●
local — подключение через Unix-сокет;
●
host — сетевое подключение через TCP/IP;
Параметр listen_addresses определяет сетевые адреса, которые
PostgreSQL прослушивает на предмет входящих соединений.
Значение по умолчанию — localhost — разрешает подключения
только с локального компьютера через loopback-интерфейс. Чтобы
подключаться к серверу удаленно, потребуется задать другие
адреса. В частности, при значении * запросы на соединение
принимаются со всех сетевых интерфейсов сервера.
●
hostssl — сетевое соединение с использованием SSL-шифрования
(сервер должен быть собран с поддержкой SSL и требуется
установить параметр конфигурации ssl = on);
●
hostnossl — сетевое соединение без использования SSL-
шифрования.
Можно указывать и другие типы подключений, мы рассмотрим их в
следующих темах курса.
11
Базы данных
БД
БД с указанным именем (возможно, в кавычках)
sameuser, samerole
БД, совпадающая по имени с пользователем
или с любой ролью, в которую он входит
all
подключение к любой БД
значение[, значение...]
несколько вариантов из вышеперечисленного
@имя-файла
ссылка на файл с именами
В поле баз данных можно задать одно из значений, перечисленных
ниже, или несколько таких значений через запятую:
●
имя конкретной базы данных;
Если значение начинается с косой черты /, то оно интерпретируется как
регулярное выражение.
●
sameuser — база данных, совпадающая по имени с пользователем;
●
samerole — база данных, совпадающая по имени с какой-либо
ролью, в которую входит пользователь (в том числе с самим именем
пользователя, поскольку пользователь — тоже роль);
●
all — любая база данных;
●
@ — ссылка на файл с именами баз данных. В файле имена могут
быть разделены запятыми, пробелами, табуляциями или переводами
строк. Допускаются вложенные подключения файлов (@) и
комментарии (#).
12
Пользователи
пользователь
пользователь с указанным именем (возможно, в кавычках)
+пользователь
пользователи, входящие в указанную роль
all
любой пользователь
значение[, значение...]
несколько вариантов из вышеперечисленного
@имя-файла
ссылка на файл с именами
В поле пользователей можно указать одно из значений, перечисленных
ниже, или несколько таких значений через запятую:
●
имя — пользователь с указанным именем, если значение начинается
с косой черты /, оно интерпретируется как регулярное выражение;
●
+имя — пользователь с указанным именем и все пользователи,
входящие в его роль;
●
all — любой пользователь;
●
@ — ссылка на файл с именами пользователей. В файле имена
могут быть разделены запятыми, пробелами, табуляциями или
переводами строк. Допускаются вложенные подключения файлов
(@) и комментарии (#).
При использовании записи +имя параметры членства не учитываются.
Это редкий пример ситуации, когда включение роли в роль вообще
без всяких параметров может иметь какой-то смысл.
13
Адреса клиентов
адрес
диапазон IP-адресов с длиной префикса (например, 172.20.143.0/24)
или IP-адрес подсети с маской (172.20.143.0 255.255.255.0)
samehost, samenet
любые IP-адреса интерфейсов сервера
или принадлежащие любым подсетям интерфейсов сервера
доменное_имя
IP-адреса, соответствующие указанному имени (например, domain.com)
или части имени (.com)
all
любой IP-адрес
В поле адресов может быть указано одно из следующих значений:
●
all — любой IP-адрес клиента;
●
IP-адрес с длиной префикса (CIDR-нотация) — диапазон допустимых
адресов IPv4 или IPv6 клиентов, например, ::1/128 — адрес localhost
для IPv6, а 127.0.0.1/32 — то же самое для IPv4;
●
IP-адрес и маска подсети — диапазон допустимых IPv4-адресов,
например, 192.168.1.0 255.255.255.128 — адрес подсети, которой
соответствует CIDR-нотация 192.168.1.0/25;
●
samehost — IP-адреса интерфейсов сервера;
●
samenet — IP-адреса из любой подсети, которой принадлежат
адреса интерфейсов сервера;
●
доменное имя (или часть доменного имени, начиная с точки) —
IP-адреса, соответствующие данному имени.
Принадлежность IP-адреса клиента указанному домену проверяется
в два шага. Сначала по IP-адресу определяется доменное имя
(reverse lookup), а затем проверяется, что такому домену
действительно соответствует исходный IP-адрес (forward lookup).
Таким образом проверяется соответствие владельца сети и
владельца доменного имени для отсечения скомпрометированных
адресов:
14
Простая аутентификация
Ничего не проверяет
15
Простая аутентификация
trust
допустить без аутентификации
reject
отказать без аутентификации
В поле метода аутентификации можно указать различные методы. Для
начала познакомимся с двумя самыми простыми, а остальные
рассмотрим ниже и в следующих темах.
Метод trust безусловно доверяет пользователю и не выполняет
проверку. В реальной жизни имеет смысл применять разве что для
локальных соединений.
Метод reject безусловно отказывает в доступе. Можно использовать,
чтобы отсечь любые соединения определенного типа или
с определенных адресов (например, запретить нешифрованные
соединения).
16
Вопрос
Что обозначает приведенная ниже настройка?
# TYPE DATABASE USER ADDRESS METHOD
hostnossl all all all reject
host sameuser all samenet trust
host pub +reader all trust
1. Запрещаются нешифрованные соединения.
2. Разрешается доступ пользователям из своей подсети
к одноименным базам данных.
3. Разрешается доступ пользователям, входящим в роль reader,
к базе данных pub.
Обратите внимание, что первую строку нельзя сместить вниз — смысл
настройки изменится.
18
Аутентификация по паролю
Сервер запрашивает у клиента пароль
19
Парольная аутентификация
password
передается в незашифрованном виде
md5
передается MD5-хеш
scram-sha-256
используется протокол SCRAM
При парольной аутентификации сервер PostgreSQL запрашивает
у пользователя пароль и проверяет его на соответствие паролю,
который хранится либо в самой СУБД, либо во внешней службе.
Для паролей, хранящихся в СУБД, поддерживаются три метода.
Метод md5 сравнивает MD5-дайджест пароля с MD5-дайджестом,
хранящимся в базе.
В настоящее время использовать этот метод не стоит: он недостаточно
криптостойкий и обладает несколькими серьезными недостатками, а в
PostgreSQL 19 его уже не будет.
Наиболее безопасный метод scram-sha-256 использует при
аутентификации протокол SCRAM и задействует криптостойкий
алгоритм SHA-256. Метод реализует фреймворк SASL, отделяющий
механизм аутентификации от прикладного протокола.
Метод password предполагает передачу пароля в незашифрованном
виде. Его не следует применять, если клиент-серверное соединение не
зашифровано.
Более подробная информация об этих методах аутентификации
приводится в статье Питера Эйзентраута:
20
Пароль в СУБД
Установить пароль пользователя
[ CREATE | ALTER ] ROLE ...
PASSWORD 'пароль'
[ VALID UNTIL дата_время ];
пользователю с пустым паролем будет отказано в доступе
при аутентификации по паролю
Пароли хранятся в системном каталоге
pg_authid
метод шифрования определяется параметром password_encryption
метод аутентификации должен совпадать с методом шифрования
(md5 автоматически переключается на scram-sha-256)
До сих пор мы создавали роли без указания пароля. Если установить
метод аутентификации по паролю, таким пользователям будет отказано
в доступе.
Пароль хранится в базе данных в таблице pg_authid.
Чтобы установить пароль, надо указать его — либо сразу при создании
роли в команде CREATE ROLE, либо впоследствии в ALTER ROLE.
Пароль хранится в зашифрованном виде, алгоритм шифрования (MD5
или SCRAM-SHA-256) определяется параметром password_encryption.
Также можно указать время действия пароля.
Если сохраненный пароль был зашифрован алгоритмом SCRAM-SHA-
256 и установлен метод аутентификации MD5, при обмене
сообщениями будет использован более надежный метод SCRAM-SHA-
256.
22
Ввод пароля
Вручную
Установить переменную PGPASSWORD
неудобно при подключении к разным базам
не рекомендуется из соображений безопасности
Файл с паролями
~/.pgpass на узле клиента
строки в формате узел:порт:база_данных:имя_пользователя:пароль
в качестве значения можно указать * (любое значение)
строки просматриваются сверху вниз, выбирается первая подходящая
файл должен иметь права доступа 600 (rw- - - - - - - )
Пользователь может вводить пароль вручную (или указывать в явном
виде в строке подключения, как мы видели в демонстрации), а может
автоматизировать ввод. Для этого есть две возможности.
Во-первых, можно задать пароль в переменной окружения
PGPASSWORD (на клиенте). Однако это неудобно, если приходится
подключаться к нескольким базам, и не рекомендуется из соображений
безопасности.
Во-вторых, можно задать пароли в файле ~/.pgpass, доступ к которому
должен иметь только владелец (иначе файл будет проигнорирован).
Расположение файла можно изменить, задав переменную окружения
PGPASSFILE.
24
Аутентификация ОС
Для локальных подключений
25
peer [map=...]
запрос имени пользователя у ядра ОС (для локальных подключений)
Операционная система
Аутентификация peer
PostgreSQL
клиент
alice
чей сеанс?
alice
Метод аутентификации peer запрашивает имя текущего пользователя
у ядра ОС. Поскольку ОС уже аутентифицировала этого пользователя
(скорее всего, запросив пароль), мы просто верим ей.
В простейшем случае подключение разрешается, если имена
пользователей в ОС и в PostgreSQL совпадают, но, как мы увидим
позже, есть возможность задать и более сложное соответствие
с помощью сопоставления имен.
27
Сопоставление имен
pg_ident.conf
еще один конфигурационный файл
строка — набор полей, разделитель — пробел или табуляция
пустые строки и текст после # игнорируются
Поля
название сопоставления
(указывается в параметре map в pg_hba.conf)
внешнее имя
внутреннее имя пользователя БД
Сопоставления имен определяются в отдельном файле pg_ident.conf;
его расположение задается параметром ident_file. Файл имеет такую же
структуру, как и pg_hba.conf, но записи состоят из трех полей: название
сопоставления, внешнее имя, внутреннее имя.
Название сопоставления необходимо, чтобы разграничивать разные
правила сопоставления внутри одного файла pg_ident.conf (которые
могут потребоваться для разных записей в pg_hba.conf).
Внешнее имя должно совпадать с именем, возвращаемым внешней
системой аутентификации (в нашем случае — ядром ОС).
Внутреннее имя должно совпадать с именем роли базы данных.
Запись, сопоставляющая внутреннее и внешнее имена, означает, что
внешнему пользователю разрешено подключаться к СУБД от имени
соответствующего внутреннего пользователя после успешной
аутентификации.
Как внешнее, так и внутреннее имя могут начинаться с косой черты.
В этом случае значение считается регулярным выражением. Это
позволяет обработать, например, ситуации, когда внешнее и
внутреннее имена отличаются только префиксами или суффиксами.
К pg_ident.conf можно подключать дополнительные файлы
конфигурации директивами include, include_if_exists или include_dir.
28
Вопрос
Что обозначает приведенная ниже настройка?
pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local sameuser all peer map=m1
local all all peer map=m2
host all all samehost scram-sha-256
pg_ident.conf
# MAPNAME SYSTEM-USERNAME PG-USERNAME
m1 student alice
m1 student bob
m2 /^a /b$
1. Для локальных соединений c базой данных, совпадающей по
имени с именем роли, PostgreSQL запрашивает имя пользователя
у операционной системы. Сопоставление m1 определяет, что
пользователь ОС student может подключаться под ролями alice и bob.
2. Правило m2, на которое ссылается вторая строка pg_hba.conf,
сопоставляет пользователей OC с именем, которое начинается на
букву «a», с ролями, которые заканчиваются на букву «b». Например,
пользователь OC alice сможет подключиться под ролью bob. Эта
строка будет использована, только если имя базы не совпадает
с именем роли: в противном случае первая строка сработает
раньше.
3. Сетевые соединения с локальным сервером аутентифицируются
с помощью пароля по протоколу SCRAM.
Другие сетевые соединения не допускаются.
30
Итоги
При подключении выполняется аутентификация
Настройки определяются конфигурационным файлом
pg_hba.conf
При парольной аутентификации шифрованные пароли
хранятся в системном каталоге и проверяются СУБД
Локальные подключения можно аутентифицировать
с помощью ОС
31
Практика
1. Разрешите локальные подключения суперпользователям
и сетевые подключения всем пользователям к любым базам
данных с аутентификацией MD5 по паролю. Любые другие
подключения должны быть запрещены.
2. Создайте роль alice с паролем, зашифрованным MD5,
и роль bob с паролем, зашифрованным SCRAM-SHA-256.
3. Проверьте возможность подключения под созданными
ролями.
4. Под суперпользовательской ролью посмотрите пароли
пользователей alice и bob в системном каталоге.
5. Восстановите исходную конфигурацию.
1. Перед тем как вносить изменения в конфигурационный файл
pg_hba.conf, сохраните его исходную версию, чтобы иметь возможность
вернуть начальное состояние в п. 5.
32
Практика+
Определенным пользователям, список которых время от
времени меняется, требуется разрешить локальный доступ без
авторизации. Сложность в том, что любое изменение списка
требует изменения файла pg_hba.conf.
1. Настройте аутентификацию, лишенную этого недостатка.
2. Убедитесь в правильности изменений.
3. Восстановите первоначальные настройки.
1. Используйте групповую роль.