Управление доступом
Подключение и аутентификация
13
Авторские права
© Postgres Professional, 2015‒2022
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Конфигурационные файлы
Простые методы аутентификации
Аутентификация по паролю
Внешняя аутентификация и сопоставление имен
3
Задачи при подключении
Идентификация
определение имени пользователя БД
имя может отличаться от указанного (при внешней аутентификации)
Аутентификация
действительно ли пользователь тот, за кого себя выдает?
обычно требуется подтверждение (например, пароль)
Авторизация
имеет ли право данный пользователь подключаться к серверу?
частично пересекается с функционалом привилегий
При подключении клиента сервер должен выполнить несколько задач.
Во-первых, идентифицировать пользователя, то есть определить его
имя. Для этого пользователь представляется, но указанное имя может
отличаться от имени пользователя БД (например, если пользователь
представляется своим именем в ОС).
Во-вторых, аутентифицировать пользователя, то есть проверить, что он
действительно тот, за кого себя выдает. Простой пример — ввод
пароля.
В-третьих, авторизовать пользователя, то есть определить, имеет ли он
право подключения (эта задача частично пересекается с функционалом
привилегий).
Иногда все три задачи называют общим словом «аутентификация».
PostgreSQL позволяет гибко настроить этот процесс.
До сих пор мы подключались к серверу, никак не подтверждая свое
имя. Дело в том, что в Ubuntu настройки по умолчанию позволяют
подключаться к локальному серверу без авторизации, если имена
пользователя базы данных и операционной системы совпадают.
А в виртуальной машине курса сделаны дополнительные настройки,
разрешающие вообще любые локальные подключения.
4
Основные настройки
pg_hba.conf
конфигурационный файл, при изменении нужно перечитать
строка — набор полей, разделитель — пробел или табуляция
пустые строки и текст после # игнорируются
Поля
тип подключения
имя базы данных
имя пользователя
адрес узла
метод аутентификации
необязательные дополнительные параметры в виде имя=значение
параметры подключения
Настройки аутентификации хранятся в конфигурационном файле,
который используется подобно postgresql.conf, но отличается от него по
формату. Файл называется pg_hba.conf (от «host-based authentication»),
его расположение определяется параметром hba_file . При изменении
этого файла необходимо перечитать настройки (как обычно, с помощью
pg_ctl reload или вызовом функции pg_reload_conf).
Файл pg_hba.conf состоит из строк, каждая из которых считается
отдельной записью. Пустые строки и комментарии (все после символа
#) игнорируются. Строка состоит из полей, разделенных пробелами или
табуляциями.
Количество полей может различаться в зависимости от их содержимого,
общий список приведен на слайде.
5
Схема обработки
Записи просматриваются сверху вниз
Применяется первая запись, которой соответствует
подключение (тип, база, пользователь и адрес)
выполняется аутентификация и проверка привилегии 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-адресу). Если подходит, то выполняется
аутентификация указанным в строке методом. Если результат успешен,
то подключение разрешается, иначе — запрещается (другие строки при
этом уже не рассматриваются).
Если ни одна из строк не подошла, то доступ запрещается.
Таким образом, записи в файле должны идти сверху вниз от частного
к общему.
Внизу слайда приведен фрагмент файла по умолчанию при сборке из
исходных кодов (при установке из пакета возможны другие настройки).
В этом примере видно три строки. Первая относится к локальным не-
TCP подключениям (local) для любых баз (all) и пользователей (all).
Вторая относится к удаленным подключениям (host) с адреса 127.0.0.1
(то есть localhost), третья — то же самое, но для IPv6.
Можно сделать вывод о том, что по умолчанию PostgreSQL допускает
только локальные соединения (как сетевые, так и нет).
Далее возможные значения полей рассматриваются более подробно.
7
Параметры подключения
Тип подключения
Имя базы данных
Адрес узла
Имя роли
8
Тип подключения
local
локальное подключение через unix-domain socket
host
подключение по TCP/IP
(обычно требуется изменение параметра listen_addresses)
hostssl
шифрованное SSL-подключение по TCP/IP
(сервер должен быть собран с поддержкой SSL,
также требуется установить параметр ssl)
hostnossl
нешифрованное подключение по TCP/IP
В поле типа подключения можно задать одно из значений,
перечисленных ниже.
Слово «local» — соответствует локальному подключению через
доменный сокет (без использования сетевого подключения).
Слово «host» — соответствует любому подключению по TCP/IP.
Поскольку по умолчанию PostgreSQL слушает соединения только
с локального адреса (localhost), скорее всего потребуется задать другой
адрес с помощью параметра сервера listen_address.
Слово «hostssl» — соответствует только шифрованному SSL-
подключению по TCP/IP. Для таких соединений сервер должен быть
собран с поддержкой SSL. Кроме того, требуется установить параметр
ssl = on.
Слово «hostnossl» — соответствует только нешифрованному
подключению по TCP/IP.
9
Имя базы данных
all
подключение к любой БД
sameuser
БД, совпадающая по имени с ролью
samerole
БД, совпадающая по имени с ролью или группой, в которую она входит
replication
специальное разрешение для протокола репликации
БД
БД с указанным именем (возможно, в кавычках)
имя[,имя...]
нескольких имен из вышеперечисленного
В поле базы данных можно задать одно из значений, перечисленных
ниже, или несколько таких значений через запятую.
Слово «all» — соответствует любой базе данных.
Слово sameuser — соответствует базе данных, совпадающей по имени
с пользователем.
Слово samerole — соответствует базе данных, совпадающей по имени
с какой-либо ролью, в которую входит пользователь (в том числе
совпадающей по имени с самим пользователем, поскольку
пользователь — та же роль).
Наконец, можно указать имя конкретной базы данных.
Вместо перечисления имен можно сослаться на файл с помощью @.
В файле имена могут быть разделены запятыми, пробелами,
табуляциями или переводами строк. Допускаются вложенные
подключения файлов (@) и комментарии (#).
10
Адрес узла
all
любой IP-адрес
IP-адрес/длина_маски
указанный диапазон IP-адресов (например, 172.20.143.0/24)
или альтернативная форма в два поля (172.20.143.0 255.255.255.0)
samehost
IP-адрес сервера
samenet
любой IP-адрес из любой подсети, к которой подключен сервер
доменное_имя
IP-адрес, соответствующий указанному имени (например, domain.com)
допускается указание части имени, начиная с точки (.com)
В поле адреса может быть указано одно из следующих значений.
Слово «all» — соответствует любому IP-адресу клиента.
IP-адрес с указанием длины маски подсети (CIDR) — определяет
диапазон допустимых IP-адресов. Альтернативно можно записать
отдельно IP-адрес и в следующем поле маску подсети. Также
поддерживаются IP-адреса в нотации IPv6.
Слово «samehost» — соответствует IP-адресу сервера (фактически,
аналог 127.0.0.1 для систем, где такой адрес не разрешен).
Слово «samenet» — соответствует любому IP-адресу из любой подсети,
к которой подключен сервер.
Наконец, адрес можно указать доменным именем (или частью
доменного имени, начиная с точки). PostgreSQL определит
принадлежность IP-адреса клиента указанному домену: для этого
сначала по IP-адресу определяется доменное имя (reverse lookup),
а затем проверяется, что такому домену действительно соответствует
исходный IP-адрес (forward lookup). Таким образом проверяется
соответствие владельца сети и владельца доменного имени для
отсечения скомпрометированных адресов:
11
Имя роли
all
любая роль
роль
роль с указанным именем (возможно, в кавычках)
+роль
роль, входящая в указанную роль
имя[,имя...]
несколько имен из вышеперечисленного
В поле имени пользователя можно указать одно из значений,
перечисленных ниже, или несколько таких значений через запятую.
Слово «all» — соответствует любому IP-адресу клиента.
Имя роли — соответствует пользователю (или роли, что то же самое)
с указанным именем. Если перед именем роли стоит знак +, то имя
соответствует любому пользователю, входящему в указанную роль.
Вместо перечисления имен можно сослаться на файл с помощью @.
В файле имена могут быть разделены запятыми, пробелами,
табуляциями или переводами строк. Допускаются вложенные
подключения файлов (@) и комментарии (#).
12
Простая аутентификация
Ничего не проверяет
13
Простая аутентификация
trust
допустить без аутентификации
reject
отказать без аутентификации
В поле метода аутентификации можно указать различные методы. Для
начала познакомимся с двумя самыми простыми, а остальные
рассмотрим ниже.
Метод «trust» безусловно доверяет пользователю и не выполняет
проверку. В реальной жизни имеет смысл применять разве что для
локальных соединений.
Метод «reject» безусловно отказывает в доступе. Можно использовать,
чтобы отсечь любые соединения определенного типа или
с определенных адресов (например, запретить нешифрованные
соединения).
14
Вопрос
Что обозначает приведенная ниже настройка?
# 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.
Обратите внимание, что первую строку нельзя сместить вниз — смысл
настройки изменится.
16
Аутентификация по паролю
Сервер запрашивает у клиента пароль
17
Пароль в СУБД
password
передается в незашифрованном виде
md5
передается MD5-хеш
scram-sha-256
используется протокол SCRAM
При парольной аутентификации сервер PostgreSQL запрашивает
у пользователя пароль и проверяют его на соответствие паролю,
который хранится либо в самой СУБД, либо во внешней службе.
Для паролей, хранящихся в СУБД, поддерживаются три метода.
Метод «md5» сравнивает MD5-дайджест пароля с MD5-дайджестом,
хранящимся в базе. При запросе сервер отправляет клиенту так
называемую «соль», клиент вычисляет MD5-хеш пароля, добавляет
«соль», еще раз вычисляет MD5-хеш и отправляет его на сервер для
сравнения с сохраненным хешем. Благодаря «соли» хеши одинаковых
паролей получаются разными. Однако в настоящее время алгоритм
MD5 считается недостаточно криптостойким.
Наиболее безопасный метод «scram-sha-256» использует при
аутентификации протокол SCRAM и задействует криптостойкий
алгоритм SHA-256. Метод реализует фреймворк SASL, отделяющий
механизм аутентификации от прикладного протокола.
Метод «password» предполагает передачу пароля в незашифрованном
виде. Его не следует применять, если соединение клиент-сервер не
зашифровано.
18
Пароль в СУБД
Установить пароль пользователя
[ CREATE | ALTER ] ROLE ...
PASSWORD 'пароль'
[ VALID UNTIL дата_время ];
пользователю с пустым паролем будет отказано в доступе
при аутентификации по паролю
Пароли хранятся в системном каталоге
pg_authid
метод шифрования определяется параметром password_encryption
метод аутентификации должен совпадать с методом шифрования
(md5 автоматически переключается на scram-sha-256)
До сих пор мы создавали роли без указания пароля. Если установить
метод аутентификации по паролю, таким пользователям будет отказано
в доступе.
Пароль хранится в базе данных в таблице pg_authid.
Чтобы установить пароль, надо указать его — либо сразу при создании
роли в команде CREATE ROLE, ли