Внешняя авторизация через 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

Включение и отключение внешней авторизации#

Для включения внешней авторизации:

  1. Настройте конфигурационный файл внешней авторизации.

  2. Добавьте external_authorize.filename в параметр shared_preload_libraries файла postgresql.conf. В качестве значения укажите путь к конфигурационному файлу внешней авторизации. Путь указывается относительно каталога PGDATA.

  3. Выполните перезагрузку СУБД:

    pg_ctl restart
    

Отключение внешней авторизации:

  1. Исключите external_authorize.filename из параметра shared_preload_libraries файла postgresql.conf.

  2. Выполните перезагрузку СУБД:

    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

string

Эта строка подставляется перед именем пользователя во время формирования DN (Distinguished Name, уникальное имя объекта) для связывания при аутентификации в режиме простого связывания

ldapsuffix

string

Эта строка размещается после имени пользователя во время формирования DN для связывания при аутентификации в режиме простого связывания

Параметры режима «поиск+связывание»

ldapbasedn

LDAP DN

Корневая папка DN для начала поиска пользователя при аутентификации в режиме «поиск+связывание»

ldapbinddn

LDAP DN

DN пользователя для связи с каталогом при выполнении поиска в ходе аутентификации в режиме «поиск+связывание»

ldapbindpasswd

string

Пароль пользователя для связывания с каталогом при выполнении поиска в ходе аутентификации в режиме «поиск+связывание»

ldapsearchattribute

string

Атрибут для соотнесения с именем пользователя в ходе аутентификации «поиск+связывание». Если атрибут не указан, будет использован атрибут uid

ldapsearchfilter

string

Фильтр поиска, используемый для аутентификации в режиме «поиск+связывание». Вложенность $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

string

Имя LDAP-атрибута, из которого извлекаются родительские роли в процессе внешней авторизации

createnewrole

true
yes
false
no
0
1

Задает, нужно ли создавать временную роль в БД, если ее нет в БД, но она задана в LDAP

ldaprolsuperattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolsuper

ldaprolinheritattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolinherit

ldaprolcreateroleattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcreaterole

ldaprolcreatedbattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcreatedb

ldaprolcanloginattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolcanlogin

ldaprolreplicationattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolreplication

ldaprolbypassrlsattribute

string

Имя булевого атрибута в узле LDAP. Этот атрибут задает значение модификатора прав rolbypassrls

rolsuperldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolsuper

rolinheritldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolinherit

rolcreateroleldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcreaterole

rolcreatedbldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcreatedb

rolcanloginldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolcanlogin

rolreplicationldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав rolreplication

rolbypassrlsldapparentrole

string

Имя роли, наличие которой среди непосредственных родительских ролей говорит о присутствии у роли модификатора прав 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

Управление протоколом LDAPS#

В Pangolin реализована возможность настроить засекречивание запросов от сервера СУБД к AD (Active Directory). Для этого нужно настроить протокол LDAPS, использующий LDAP поверх SSL с протоколом шифрования TLS.

Далее приведены шаги для включения TLS соединения с LDAP:

  1. Набор имеющихся корневых AD сертификатов скопируйте на сервер, где будет производиться установка (в случае кластера - и на мастер, и на реплику). Примером директории может быть: etc/pki/ca-trust/source/anchors.

  2. Выполните команду sudo update-ca-trust для обновления списка доверенных сертификатов.

  3. В файле конфигурации etc/openldap/ldap.conf укажите путь к сертификатам в параметре TLS_CACERTDIR. Также добавьте набор шифров, используемых сервером AD: TLS_CIPHER_SUITE TLSv1.2:!NULL.

  4. Отредактируйте раздел hba_rules конфигурационного файла инсталлятора custom_file_template.yml. В нем пропишите параметры подключения к серверу:

    ldapserver="{{ ldap_server }}" ldapport=3268 ldapbasedn="" ldapprefix="cn=" ldapsuffix=" OU=NPA OU=PAM OU=ALL DC=MustBeFilled dc=ru ldap_tls=1
    
  5. Запустите установку/обновление Pangolin. Ниже приведен пример строки pg_hba.conf при включенном ldaptls:

    host all +all-sa-pam-group 0.0.0.0/0 ldap ldaptls=1 ldapserver=X.XX.ru ldapport=389 ldapprefix="cn=" ldapsuffix=", OU=NPA, OU=PAM, OU=ALL, OU=XX, DC=X, dc=ru