Внешняя авторизация через LDAP
Функциональность позволяет настраивать в централизованном LDAP-хранилище атрибуты прав пользователей (SUPERUSER, LOGIN, REPLICATION и т.д.) и вхождение ролей в другие роли. После чего атрибуты и связи ролей можно получать из централизованного хранилища для всех экземпляров СУБД.
В LDAP-хранилище для каждой роли так же хранится список родительских ролей, в которые она входит (по аналогии с pg_auth_members
), но конкретные полномочия всех этих ролей хранятся в СУБД. При этом из хранилища можно получать роли, которые не заведены в самой СУБД, и выполнять операции от их имени.
Функциональность не позволяет управлять через LDAP полномочиями отдельных ролей — только вхождением ролей друг в друга.
Любая нетривиальная команда UPDATE
также требует привилегии SELECT
, поскольку она должна ссылаться на столбцы таблицы, чтобы определить, какие строки обновить, и/или вычислить новые значения для столбцов
Кеширование ответов LDAP-сервера
Решение позволяет получать из LDAP модификаторы прав роли: флаги rolcanlogin
, rolsuper
и другие, перечисленные в системном каталоге pg_authid
. Чтобы не устанавливать сетевое соединение с LDAP при каждом обращении к этим флагам, они кешируются.
Кеширование ответов LDAP позволяет не тратить время на походы в LDAP при частой инвалидации кеша системного каталога. Но возможен и другой случай: создается сессия, в которой роль оказывается очень долго подключенной к СУБД и выполняет только операции чтения. В таком случае результаты выполнения авторизации и чтения модификаторов прав пользователей фиксируются в кешах более высокого уровня, что не позволяет в таком случае получать обновления из LDAP без разрыва сессии. Для такого случая при каждом выполнении операции в БД происходит специальная проверка — если в течение заданного промежутка времени не было ни одного похода в LDAP, то выполняется инвалидация кеша системного каталога, чтобы при последующем обращении к нему произошел поход в LDAP.
Защита от привилегированного пользователя
Конфигурационный файл сопоставления имен ролей БД и узлов в LDAP может быть уязвимостью в защите от привилегированного пользователя. Пользователь со слишком большими полномочиями на сервере может так настроить файл сопоставления, чтобы роль с малыми полномочиями отображалась в LDAP-узел, задающий большие полномочия. Чтобы такого не происходило, файл сопоставления имен добавлен в систему защиты от привилегированного пользователя. Если она включена, то файл сопоставления получается из защищенного хранилища, а содержимое файла сопоставления игнорируется.
Получение модификаторов прав роли из стандартных атрибутов LDAP
Если LDAP-хранилище располагает только стандартными классами объектов, то получение модификаторов прав осуществляется через проверку принадлежности к ролям, заданным в конфигурационном файле. Например, чтобы проверить, является ли пользователь суперпользователем, производится проверка, задана ли в LDAP для него специальная роль. Имя этой роли задается в конфигурационном файле внешней авторизации.
Определение модификаторов прав через вхождение в родительскую роль проходит без обращения к pg_authid
. Поэтому неважно, заведены эти родительские роли в базе или нет. Алгоритм устроен просто: он составляет список всех значений, которые хранятся в атрибуте, заданном параметром ldapparentroleattribute
, и ищет, содержится ли в нем строка, заданная в параметре файла конфигурации внешней авторизации для того или иного модификатора прав.
Значения по умолчанию в этом случае не используются. Если роль, членство в которой определяет модификатор прав, не задана в конфигурационном файле, соответствующий модификатор прав не изменяется.
Получение модификаторов прав роли из булевых атрибутов LDAP
Если есть возможность настроить дополнительные LDAP-атрибуты, то можно задать в конфигурационном файле внешней авторизации имена булевых атрибутов, из которых расширение будет брать значения модификаторов прав роли. Значения по умолчанию в этом случае не используются. Если имя атрибута, соответствующего модификатору прав, не задано в конфигурационном файле, соответствующий модификатор прав не изменяется.
Создание временных ролей, которых нет в pg_authid
Хук в SearchCatCacheMiss
принимает HeapTuple и возвращает HeapTuple. Вполне возможна ситуация, когда на вход поступает пустой HeapTuple (то есть запись не была найдена в системном каталоге), а возвращается валидный HeapTuple. Таким образом реализуется возможность выполнять операции с БД только из под УЗ LDAP. Это позволяет администраторам СУБД заводить пользователей только в LDAP и не дублировать их имена во всех СУБД, которые подключены к этому LDAP.
Cопоставление имен ролей в БД и узлов в LDAP
Имя роли в БД, для которой выполняется внешняя авторизация, может не совпадать с именем узла в LDAP. В этом случае можно применить сопоставление имен, чтобы сменить имя УЗ на имя узла в LDAP при обращении к LDAP-хранилищу. Сопоставление имен задается в отдельном конфигурационном файле, похожем на pg_ident.conf
, который определяет правила, позволяющие устанавливать связь между именами ролей базы данных (Pangolin) и узлами LDAP. Эта функциональность обеспечивает возможность задания однонаправленных и двунаправленных отображений между этими сущностями, что делает процесс аутентификации и авторизации более гибким и управляемым.
Файл сопоставления имен имеет структуру:
имя-сопоставления pg_role операция ldap_name
Где:
-
имя-сопоставления
– произвольное имя, используемое для обозначения набора правил сопоставления; -
pg_role
– имя роли базы данных Pangolin; -
операция
– одна из трех операций:->
– задает отображение роли БД в узел LDAP (однонаправленное);<-
– задает отображение узла LDAP в роль БД (однонаправленное);<->
– задает взаимно-однозначное отображение между узлом LDAP и ролью БД (двунаправленное);
-
ldap_name
– имя узла в хранилище LDAP.
После внесения изменений в файл сопоставления имен, необходимо перезапустить сервер Pangolin (restart) или отправить сигнал SIGHUP
для обновления настроек (reload).
Особенности параметров:
-
Однонаправленные отображения:
- Операция
->
позволяет задать отображение роли БД в узел LDAP. - Операция
<-
позволяет задать отображение узла LDAP в роль БД.
- Операция
-
Двунаправленное отображение. Операция
<->
устанавливает взаимно-однозначную связь между ролью БД и узлом LDAP, что означает, что оба направления (БД → LDAP и LDAP → БД) будут работать одновременно. -
Использование регулярных выражений:
- В полях
pg_role
иldap_name
можно использовать регулярные выражения с одной группой захвата. Регулярные выражения начинаются со знака/
. - Если используется регулярное выражение, оно должно содержать не более одной группы захвата (
\1
), которую можно использовать в соответствующем направлении.
- В полях
-
Ограничения. Двунаправленная операция
<->
несовместима с регулярными выражениями. Для таких случаев необходимо задавать два отдельных отображения. Пример с регулярными выражениями:mymap /(\w+)_pg_role -> \1_ldap_node
mymap \1_pg_role <- /(\w+)_ldap_node
Пример файла сопоставления
Однонаправленные отображения:
mymap2 db_admin -> ldap_admin
mymap2 ldap_guest <- db_guest
Двунаправленное отображение:
mymap3 developer <-> ldap_developer
С использованием регулярных выражений:
mymap4 /(\w+)_role -> \1_ldap_unit
mymap4 \1_role <- /(\w+)_ldap_unit
Включение и отключение внешней авторизации
Для включения внешней авторизации:
-
Настройте конфигурационный файл внешней авторизации.
-
Добавьте
external_authorize.filename
в параметрshared_preload_libraries
файлаpostgresql.conf
. В качестве значения укажите путь к конфигурационному файлу внешней авторизации. Путь указывается относительно каталогаPGDATA
. -
Выполните перезагрузку СУБД:
pg_ctl restart
Отключение внешней авторизации:
-
Исключите
external_authorize.filename
из параметраshared_preload_libraries
файлаpostgresql.conf
. -
Выполните перезагрузку СУБД:
pg_ctl restart
Конфигурационный файл внешней авторизации
Конфигурационный файл внешней авторизации (путь к нему задается параметром external_authorize.filename
) сделан по аналогии с pg_hba.conf
. Этот файл задает, для каких ролей выполнять внешнюю авторизацию. При попытке выполнить внешнюю авторизацию происходит сканирование его строк сверху вниз. Первая строка, которая подошла под текущие роль, метод подключения или базу, будет использоваться.
Файл состоит из строк формата:
local база пользователь [параметры]
host база пользователь адрес [параметры]
hostssl база пользователь адрес [параметры]
hostnossl база пользователь адрес [параметры]
hostgssenc база пользователь адрес [параметры]
hostnogssenc база пользователь адрес [параметры]
host база пользователь IP-адрес IP-маска [параметры]
hostssl база пользователь IP-адрес IP-маска [параметры]
hostnossl база пользователь IP-адрес IP-маска [параметры]
hostgssenc база пользователь IP-адрес IP-маска [параметры]
hostnogssenc база пользователь IP-адрес IP-маска [параметры]
Метод подключения, база, пользователь и адрес аналогичны тому, как они задаются в pg_hba.conf
. В таблице ниже перечислены параметры, которые могут быть указаны в блоке [параметры]
.
Название | Допустимые значения | Описание параметра |
---|---|---|
ldapserver | Доменное имя или IP-адрес | Имена и IP-адреса LDAP-серверов для связи. Можно указать несколько серверов, разделяя их пробелами |
ldapport | Целое число от 1 до 65535 | Номер порта для связи с LDAP-сервером. Если порт не указан, используется установленный по умолчанию порт библиотеки LDAP |
ldapscheme | ldaps | Значение ldaps выбирает протокол LDAPS. Это нестандартный способ использования LDAP поверх SSL, поддерживаемый некоторыми серверами LDAP. Альтернативную возможность предоставляет параметр ldaptls |
ldaptls | 0 или 1 | Значение 1 включает TLS-шифрование для защиты соединения Pangolin с LDAP-сервером. При этом используется операция StartTLS, описанная в RFC 4513. Альтернативную возможность предоставляет параметр ldapscheme. Заметьте, что при использовании ldapscheme или ldaptls шифруется только трафик между сервером Pangolin и сервером LDAP. Соединение между сервером Pangolin и клиентом остается незашифрованным, если только для него не включен SSL |
Параметры режима простого связывания | ||
ldapprefix | Строка | Эта строка подставляется перед именем пользователя во время формирования DN (Distinguished Name, уникальное имя объекта) для связывания при аутентификации в режиме простого связывания |
ldapsuffix | Строка | Эта строка размещается после имени пользователя во время формирования DN для связывания, при аутентификации в режиме простого связывания |
Параметры режима поиск+связывание | ||
ldapbasedn | LDAP DN | Корневая папка DN для начала поиска пользователя при аутентификации в режиме поиск+связывание |
ldapbinddn | LDAP DN | DN пользователя для связи с каталогом при выполнении поиска в ходе аутентификации в режиме поиск+связывание |
ldapbindpasswd | Строка | Пароль пользователя для связывания с каталогом при выполнении поиска в ходе аутентификации в режиме поиск+связывание |
ldapsearchattribute | Строка | Атрибут для соотнесения с именем пользователя в ходе аутентификации поиск+связывание. Если атрибут не указан, будет использован атрибут uid |
ldapsearchfilter | Строка | Фильтр поиска, используемый для аутентификации в режиме поиск+связывание. Вхождения $username в нем будут заменяться именем пользователя. Это позволяет задавать более гибкие фильтры поиска, чем ldapsearchattribute |
ldapurl | Адрес LDAP по стандарту RFC 4516 | Альтернативный способ записи некоторых других параметров LDAP в более компактном и стандартном виде. Формат адреса: ldap[s]://сервер[:порт]/basedn[?[атрибут][?[scope][?[фильтр]]]] Здесь scope принимает значение base, one или sub (обычно последнее). По умолчанию подразумевается base, что не очень полезно при таком применении. В качестве атрибута может указываться один атрибут, в этом случае он используется как значение параметра ldapsearchattribute. Если атрибут не указан, в качестве значения ldapsearchfilter может использоваться фильтр. Схема адреса ldaps выбирает для установления LDAP-подключений поверх SSL метод LDAPS, что равнозначно указанию ldapscheme=ldaps. Для применения шифрования LDAP с использованием операции StartTLS используйте обычную схему URL ldap и укажите параметр ldaptls в дополнение к ldapurl. Для неанонимного связывания ldapbinddn и ldapbindpasswd должны быть указаны как раздельные параметры. В настоящее время URL-адреса LDAP поддерживаются только с OpenLDAP и не поддерживаются в Windows |
ldapparentroleattribute | Строка | Имя LDAP-атрибута, из которого извлекаются родительские роли в процессе внешней авторизации |
createnewrole | true yes false no 0 1 | Задает, нужно ли создавать временную роль в БД, если ее нет в БД, но она задана в LDAP |
ldaprolsuperattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolsuper |
ldaprolinheritattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolinherit |
ldaprolcreateroleattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcreaterole |
ldaprolcreatedbattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcreatedb |
ldaprolcanloginattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcanlogin |
ldaprolreplicationattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolreplication |
ldaprolbypassrlsattribute | Строка | Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolbypassrls |
rolsuperldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolsuper |
rolinheritldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolinherit |
rolcreateroleldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcreaterole |
rolcreatedbldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcreatedb |
rolcanloginldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcanlogin |
rolreplicationldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolreplication |
rolbypassrlsldapparentrole | Строка | Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolbypassrls |
Новые конфигурационные параметры в postgresql.conf
Имя параметра | Допустимые значения | Значение по умолчанию | Установка параметра | Описание параметра |
---|---|---|---|---|
external_authorize.filename | Путь к файлу в каталоге PGDATA | external_authorize.conf | Требуется перезагрузка Pangolin | Путь к конфигурационному файлу внешней авторизации |
external_authorize.ldap_network_timeout | 1-60000 мс | 500 мс | Требуется перезагрузка Pangolin | Тайм-аут подключения к LDAP-хранилищу |
external_authorize.role_mapping_filename | Путь к файлу в каталоге PGDATA | Пустая строка | Требуется перезагрузка Pangolin | Путь к файлу с описанием сопоставления имен ролей в БД и узлов в LDAP |
external_authorize.role_mapping | Набор строк — содержимое конфига сопоставления имен | Пустая строка | В случае защищенного конфигурирования смена параметров возможна только через сервер KMS | Описание сопоставления имен ролей в БД и узлов в LDAP |
external_authorize.ldap_cache_ttl | 1-86400 сек | 1800 секунд | Требуется перезагрузка Pangolin | TTL (Time To Live, время жизни) данных в кеше содержимого LDAP |