ldap2pg

ldap2pg — автоматизирует процесс создания, обновления и удаления ролей и пользователей Postgres Pro из корпоративного каталога

Синтаксис

ldap2pg [параметр...] [имя_БД]

Описание #

Встроенный функционал Postgres Pro включает проверку пароля существующей роли через протокол LDAP. ldap2pg позволяет автоматизировать процесс создания, обновления и удаления ролей и пользователей Postgres Pro из корпоративного каталога.

С задачами по управлению ролями связаны задачи по управлению правами пользователей, поскольку каждой роли должны быть предоставлены надлежащие права по умолчанию. Postgres Pro также может предоставлять и отзывать права.

Утилита ldap2pg поставляется вместе с Postgres Pro Standard в отдельном пакете ldap2pg (подробные инструкции по установке приведены в Главе 16).

ldap2pg может работать с Samba DC, OpenLDAP, FreeIPA, Oracle Internet Directory и Microsoft Active Directory.

Для ldap2pg требуется файл конфигурации с именем ldap2pg.yaml.

Возможности #

  • Чтение настроек из файла конфигурации в формате YAML.

  • Создание, изменение и удаление ролей Postgres Pro через поисковые запросы LDAP.

  • Создание статических ролей в YAML-файле конфигурации для заполнения записей LDAP.

  • Управление родительскими ролями (псевдоним группы).

  • Предоставление и отзыв прав статически или через записи LDAP.

  • Пробный режим, режим проверки.

  • Регистрация поисковых запросов LDAP в журнале в качестве команд ldapsearch(1).

  • Регистрация в журнале всех SQL-операторов.

Требования #

ldap2pg выпускается как отдельный бинарный файл без зависимостей.

Для запуска утилиты ldap2pg требуется доступ суперпользователя или роли без прав суперпользователя, но с правами CREATEDB и CREATEROLE.

Необязательно запускать ldap2pg на том же компьютере, что и синхронизированный кластер Postgres Pro Standard.

Двух MиБ ОЗУ и одного виртуального процессора достаточно, чтобы утилита ldap2pg за секунды могла синхронизировать несколько тысяч ролей. Время синхронизации зависит от экземпляра Postgres Pro Standard и скорости отклика каталога LDAP.

Справка по командной строке #

Расширение ldap2pg предоставляет гибкие возможности конфигурации, оно совместимо с psql и утилитами OpenLDAP и соответствует принципам Twelve-Factor App. ldap2pg читает конфигурацию из разных источников в следующем порядке (первый источник из списка читается последним):

  1. параметры командной строки;

  2. переменные окружения;

  3. файл конфигурации;

  4. ldaprc, ldap.conf и т. д.

Синтаксис командной строки выглядит следующим образом:

ldap2pg [OPTIONS] [dbname]

. Можно использовать следующие параметры:

--check

Устанавливает режим проверки: осуществляется выход с кодом 1, если экземпляр Postgres Pro не синхронизирован.

--color

Включает цветной вывод.

-c string
--config string

Задаёт путь до YAML-файла конфигурации. Используйте - для stdin.

--directory string

Задаёт путь до каталога, который содержит файлы конфигурации.

--help

Выводит справку и завершает работу (значение по умолчанию: true).

--ldappassword-file string

Задаёт путь к файлу c паролем LDAP.

--quiet count

Уменьшает уровень детализации журнала.

--real

Режим действия. Применяет изменения к экземпляру Postgres Pro.

-skip-privileges

Выключает синхронизацию прав.

--verbose count

Увеличивает уровень детализации журнала.

--version

Выводит информацию о версии и завершает работу (значение по умолчанию: true).

В необязательном параметре dbname можно передать имя базы данных, строку conninfo или URI. За дополнительными сведениями обратитесь к странице man psql(1).

По умолчанию ldap2pg работает в пробном режиме. Для описания поисковых запросов LDAP и сопоставлений ldap2pg требуется файл конфигурации.

Параметры можно определять несколько раз. В случае конфликта используется последний аргумент.

Переменные окружения #

Для расширения ldap2pg в интерфейсе командной строки нет параметра, позволяющего настроить соединение с Postgres Pro. Однако, ldap2pg поддерживает переменные окружения PG* , используемые библиотекой libpq.

За подробной информацией о переменных окружения, используемых библиотекой libpq, обратитесь к psql(1).

По такому же принципу устанавливается соединение с сервером LDAP: ldap2pg поддерживает стандартные переменные окружения LDAP* и файлы .ldaprc. За подробной информацией о конфигурации обратитесь к странице man ldap.conf(5). ldap2pg принимает две дополнительные переменные: LDAPPASSWORD и LDAPPASSWORD_FILE.

ldap2pg загружает файл .env из родительского каталога lda2pg.yml, если такой файл существует.

Для переменных окружения используйте логические значения true или false, например LDAP2PG_SKIPPRIVILEGES=true.

Подсказка

Проверьте соединение с Postgres Pro, используя страницу man psql(1), и с сервером LDAP, используя страницу man ldapwhoami(1). Таким образом можно будет удостовериться, что ldap2pg работает правильно, и в дальнейшем будет легче отладить настройки и конфигурацию.

Настройка регистрации событий #

У расширения ldap2pg есть несколько уровней регистрации событий:

  • ERROR: информация о возникшей ошибке. При возникновении ошибки происходит сбой в работе ldap2pg.

  • WARNING: предупреждение ldap2pg о вариантах, о которых должен знать пользователь.

  • CHANGE: только изменения, которые применяются к кластеру Postgres Pro>.

  • INFO (по умолчанию): информация о том, что делает ldap2pg, в особенности, перед длинной задачей.

  • DEBUG: всё, включая обычные SQL-запросы и поисковые запросы LDAP.

Флаги командной строки --quiet и --verbose соответственно уменьшают и увеличивают уровень детализации журнала.

Самый высокий уровень детализации можно выбрать с помощью переменной окружения LDAP2PG_VERBOSITY. Например:

$ LDAP2PG_VERBOSITY=DEBUG ldap2pg

12:23:45 INFO   Starting ldap2pg                                 version=v6.0-alpha5 runtime=go1.21.0 commit=<none>

12:23:45 WARN   Running a prerelease! Use at your own risks!

12:23:45 DEBUG  Searching configuration file in standard locations.

12:23:45 DEBUG  Found configuration file.                        path=./ldap2pg.yml

$

Формат вывода ldap2pg зависит от того, используется ли терминал TTY. Если стандартный поток ошибок выводится на терминал TTY, записи цветные и их легко прочитать пользователю. Во всех остальных случаях записи выводятся в формате logfmt для машинной обработки. Получить вывод в удобном для чтения пользователем формате можно с помощью флага командной строки --color.

Справка по файлу ldap2pg.yml #

Для ldap2pg требуется файл конфигурации в формате YAML, которому обычно дают имя ldap2pg.yml и который помещают в рабочий каталог. Через этот файл можно настроить все необходимые параметры: запросы для проверки Postgres Pro, поисковые запросы LDAP, права и карта синхронизации.

Предупреждение

Для ldap2pg требуется файл конфигурации, где будет описана карта синхронизации.

За основу можно взять содержание протестированного файла ldap2pg.yml:

#
#
#       П Р И М Е Р   К О Н Ф И Г У Р А Ц И И   L D A P 2 P G
#
#
# Это пример файла конфигурации ldap2pg.yml, включающего определение статических 
# ролей и групп, предоставление прав и настройку поиска LDAP.
#
# Предполагается, что выполнены следующие требования:
#
# - Все пользователи LDAP должны быть помещены в группу `ldap_roles`.
# - Права для чтения данных должны быть предоставлены пользователям в группе `readers`.
# - Права для записи данных должны быть предоставлены пользователям в группе `writers`.
# - Права для выполнения DDL-запросов должны быть предоставлены пользователям в группе `owners`.
# - Должна существовать одна или несколько баз данных со схемой public и, возможно, ещё какой-то схемой.
# - Права не должны быть ограничены схемой. То есть если у пользователя есть права для записи данных в базу, то они 
#   распространяются на все схемы.
#
# Содержание каталога LDAP описано в test/fixtures/openldap-data.ldif
#
# Используйте информацию в соответствии с вашими потребностями! 
#
#
# Версия формата файла. Позволяет ldap2pg проверить, поддерживается ли файл.
#
version: 6

#
#       1.   П Р О В Е Р К А   P O S T G R E S
#
#  За подробностями обратитесь к Разделу «Проверка кластера Postgres Pro».
#
postgres:
  roles_blacklist_query: [nominal, postgres, pg_*]
  databases_query: [nominal]

#
#       2.   О П Р Е Д Е Л Е Н И Е   П Р А В
#
# За подробностями обратитесь к Разделу «Управление правами». Права, обрамлённые
# двойным нижним подчёркиванием, относятся к встроенным профилям прав. За подробностями обратитесь к соответствующей документации
# в Разделе «Встроенные права»
# .
#

privileges:
  # Определить группу `ro` только с правами для чтения данных
  ro:
  - __connect__
  - __select_on_tables__
  - __select_on_sequences__
  - __usage_on_schemas__
  - __usage_on_types__

  # Определить группу `rw` только с правами для записи данных
  rw:
  - __temporary__
  - __all_on_tables__
  - __all_on_sequences__

  # Определить группу `ddl` только с правами для выполнения DDL-команд.
  ddl:
  - __create_on_schemas__


#
#       3.   К А Р Т А    С И Н Х Р О Н И З А Ц И И
#
# Ниже приведён список правил для назначения ролей и предоставления прав. Каждое правило
# можно превратить в шаблон с помощью атрибутов из записей LDAP, которые возвращает поисковой
# запрос.
#
# Все роли, найденные в кластере, но созданные не в соответствии с правилами, будут удалены. Все
# права, найденные в кластере, но созданные не в соответствии с правилами, будут отозваны. 
#

rules:
- description: "Setup static roles and grants."
  roles:
  - names:
    - readers
    options: NOLOGIN
  - name: writers
    # Предоставить права для чтения пользователям с правами для записи данных
    parent: readers
    options: NOLOGIN
  - name: owners
    # Предоставить права для чтения и записи данных пользователю с ролью владельца
    parent: writers
    options: NOLOGIN

  grant:
  - privilege: ro
    role: readers
    # Привязать к конкретной схеме
    schemas: nominal
  - privilege: rw
    role: writers
  - privilege: ddl
    role: owners

- description: "Search LDAP to create readers, writers and owners."
  ldapsearch:
    base: cn=users,dc=bridoulou,dc=fr
    filter: "
    (|
      (cn=owners)
      (cn=readers)
      (cn=writers)
    )
    "
  role:
    name: '{member.cn}'
    options: LOGIN
    parent: "{cn}"

Расположение файла #

ldap2pg ищет файл конфигурации в следующем порядке:

  1. ldap2pg.yml в текущем рабочем каталоге;

  2. ~/.config/ldap2pg.yml;

  3. /etc/ldap2pg.yml;

  4. /etc/ldap2pg/ldap2pg.yml.

При заданном LDAP2PG_CONFIG или --config ldap2pg пропускает поиск файла конфигурации в стандартных местах расположения. Передавая -, можно указать, что файл необходимо прочитать из стандартного ввода. Этот способ полезен, если нужно изменить конфигурацию ldap2pg динамически.

Структура файла #

В файле ldap2pg.yml есть несколько разделов:

  • postgres: настройка соединения с Postgres Pro> и запросов для проверки.

  • ldap: конфигурация для клиента LDAP.

  • privileges: определение профилей прав.

  • rules: список поисковых запросов LDAP и связанные с ними сопоставления ролей и прав.

Если у вас нет чёткого понимания, с чего начать, возьмите за основу протестированный файл ldap2pg.yml с подробными комментариями.

О YAML #

YAML — это расширенный JSON. Документ в формате JSON является корректным YAML-документом. YAML — довольно свободный формат, где отступы имеют значение. Для примера можно посмотреть шпаргалку по формату YAML.

В файле ldap2pg.yaml будут использоваться звездочки для глобальных шаблонов и фигурные скобки для внедрения атрибутов LDAP. Обратите внимание, что эти значения должны быть заключены в кавычки.

rules:

  - role: {cn}  # Неправильный YAML-словарь

  - role: "{cn}"  # Строка с внедрённым атрибутом LDAP

Раздел postgres #

В разделе postgres определяются пользовательские SQL-запросы для проверок в Postgres Pro.

Раздел postgres содержит несколько параметров *_query. Они могут представлять собой строку, содержащую SQL-запрос, или YAML-список для получения статического списка значений без выполнения запроса в кластере Postgres Pro.

databases_query #

SQL-запрос для получения списка имён баз данных в кластере. По умолчанию ldap2pg ищет те базы данных, с которыми может установить соединение и объекты которых может переназначить владельцу. ldap2pg циклично просматривает базы данных, чтобы переназначить объекты перед удалением роли. ldap2pg управляет правом доступа к каждой базе данных.

postgres:

  databases_query: "SELECT datname FROM pg_catalog.pg_databases;"

  # ИЛИ

  databases_query: [mydb]

Примечание

Если параметр _query задан как YAML-список, запрос для проверки в кластер не отправляется, а ldap2pg использует статическое значение.

fallback_owner #

Имя роли, которая получает права владения базой данных вместо удалённой из базы роли.

Перед удалением роли ldap2pg переназначает объекты и очищает список управления доступом (access control list, ACL). Сначала целевой пользователь ldap2pg переназначает владельца базы данных. Новый владелец — это так называемый запасной владелец (fallback owner). Затем другие объекты базы данных переназначаются каждому владельцу.

managed_roles_query #

SQL-запрос для получения списка имён управляемых ролей.

ldap2pg может производить удаление ролей или изменение прав только для управляемых ролей. Как правило, в результате выполнения такого запроса возвращается список дочерних ролей, входящих в определённую группу, например, роли из группы ldap_roles. По умолчанию ldap2pg управляет всеми ролями, к которым имеет доступ.

public — это специальная роль, встроенная в Postgres Pro. Если в результатах запроса managed_roles_query появляется роль public, ldap2pg будет управлять правами в схеме public. ldap2pg управляет правами в схеме public по умолчанию.

Ниже приведён пример того, как настроить ldap2pg для управления ролью public, родительской ролью ldap_roles и любой дочерней ролью из группы ldap_roles:

postgres:

  managed_roles_query: |

    VALUES

      ('public'),

      ('ldap_roles')

    UNION

    SELECT DISTINCT role.rolname

    FROM pg_roles AS role

    JOIN pg_auth_members AS ms ON ms.member = role.oid

    JOIN pg_roles AS parent

      ON parent.rolname = 'ldap_roles' AND parent.oid = ms.roleid

    ORDER BY 1;
roles_blacklist_query #

SQL-запрос, который возвращает имя роли и глобальный шаблон для добавления роли в черный список. ldap2pg не будет рассматривать эти роли. Значение по умолчанию: [postgres, pg_*]. ldap2pg добавляет в черный список своего пользователя.

postgres:
  roles_blacklist_query:
  - postgres
  - "pg_*"
  - "rds_*"

Предупреждение

Обратите внимание, что '*foo' — элемент в формате YAML. Шаблон, который вводится с помощью '*', необходимо заключать в кавычки.

schemas_query #

SQL-запрос, который возвращает имена управляемых схем базы данных. ldap2pg выполняет этот запрос для баз данных, список которых был получен в результате запроса databases_query, только есть ldap2pg управляет правами в них. ldap2pg циклично просматривает все объекты в этих схемах, когда проверяет предоставленные права в кластере.

  postgres:
    schemas_query: |
      SELECT nspname FROM pg_catalog.pg_namespace

Раздел ldap #

Раздел ldap необходим для настройки поведения клиента LDAP. Настройте соединение, используя файл ldap.conf и переменные окружения LDAP*.

known_rdns #

Список атрибутов, которые являются частью уникального имени (distinguished name, DN).

ldap2pg пропускает поиск для атрибутов из этого списка. Например, {member.cn} не приведёт к вложенному поиску среди всех членов (member), если атрибут cn включён в список known_rdns. Значения по умолчанию: [n, l, st, o, ou, c, street, dc, uid]. Расширьте список, чтобы ускорить синхронизацию. Удалите значение, если оно не является частью уникального имени.

ldap:
  known_rdns: [cn, uid]

Раздел privileges #

В разделе верхнего уровня privileges определяются права в Postgres Pro. Он представляет собой сопоставление, определяющее профили прав, на которые в дальнейшем даётся ссылка в правиле для предоставления права в карте синхронизации. Профиль прав — список ссылок на типы прав из ACL Postgres Pro или других профилей. Профиль прав может включать другой профиль рекурсивно. За подробностями обратитесь к разделу Управление правами.

privileges:
  reading:
  - on: GLOBAL DEFAULT
    type: SELECT
    object: TABLES
  writing:
  - reading
  - on: GLOBAL
    type: SELECT
    object: TABLES

Профиль прав, имя который начинается с _, неактивен, если он не включён в активный профиль.

object #

Определяет целевой объект в ACL, где права предоставляются на уровне объектов.

Полезен только для ACL GLOBAL DEFAULT и SCHEMA DEFAULT, где объекты представляют собой классы целевых объектов, такие как TABLES, SEQUENCES и т. д. Правило предоставления прав определяет целевую схему в случае ACL SCHEMA DEFAULT.

privileges:
  reading:
  - type: SELECT
    on: GLOBAL DEFAULT
    object: TABLES
type #

Тип права в соответствии с описанием в Разделе 5.7. Например, право SELECT, REFERENCES, USAGE и т. д.

Значение может быть задано одной строкой или списком строк. Форма множественного числа types допустима. Когда определяется несколько типов, для каждого типа определяется новое право, используя одинаковые атрибуты, такие как on.

privileges:
  reading:
  - type: USAGE
    on: SCHEMAS
  
on #

Целевой ACL для типа права, например, TABLES, SEQUENCES, SCHEMAS и т. д. Обратите внимание на особые случаи ALL TABLES, ALL SEQUENCES и т. д. За подробностями обратитесь к разделу Управление правами.

privileges:
  reading:
  - type: SELECT
    on: ALL TABLES

Раздел rules #

В разделе верхнего уровня rules определяются правила синхронизации. Он содержит список в формате YAML. Это единственный обязательный параметр в файле ldap2pg.yaml. Каждый элемент rules называется сопоставлением. Сопоставление — YAML-словарь с подразделом для любой роли или права. Сопоставление также может включать поле description и раздел ldapsearch.

rules:
- description: "Define DBA roles"
  ldapsearch:
    base: ...
  roles:
  - name: "{cn}"
    options: LOGIN SUPERUSER

Подраздел ldapsearch необязательный. Определить роли и предоставить права можно без запросов к каталогу.

description #

Свободная строка, которая используется для регистрации событий в журнале. В этот параметр нельзя внедрить параметр mustache.

ldapsearch #

Директива определяет параметры поисковых запросов LDAP. Она названа вслед за утилитой командной строки ldapsearch, входящей в дистрибутив OpenLDAP. Поведение директивы в целом должно совпадать с поведением утилиты.

Примечание

В тексте документации запрос LDAP (LDAP query) называется поисковым запросом LDAP, а термин «запрос» относится к SQL.

В директивах ldapsearch в правила назначения ролей (правила role) и правила представления прав (правила grant) можно и нужно внедрять атрибуты LDAP в фигурных скобках. За подробностями обратитесь к разделу Запрос к каталогу через LDAP.

base, scope and filter

Эти параметры имеют тот же смысл, определение и значение по умолчанию, что и соответствующие параметры утилиты командной строки ldapsearch.

rules:
- ldapsearch:
    base: ou=people,dc=acme,dc=tld
    scope: sub
    filter: >
      (&f
         (member=*)
         (cn=group_*)
      )
joins

Позволяет настроить вложенный поиск LDAP. Раздел joins — словарь с именем атрибута в качестве ключа и параметрами поискового запроса LDAP в качестве значения. В этом случае параметры поискового запроса LDAP такие же, как и для изначального полноценного поиска LDAP. Вложенный поиск в рамках другого вложенного поиска не поддерживается.

rules:
- ldapsearch:
    joins:
      member:
        filter: ...
        scope: ...
  role:
  - name: "{member.sAMAccountName}"

Основа вложенного поиска — значение ссылающегося атрибута, например, каждое значение member. Настроить атрибут base для вложенного поиска невозможно. Также ldap2pg извлекает атрибуты для вложенных поисков из правил role и grant. В рамках полноценного поиска доступен только один уровень вложенного поиска. Запустить вложенный поиск внутри другого вложенного поиска невозможно.

За подробностями обратитесь к разделу Запрос к каталогу через LDAP.

Примечание

Выполнить вложенный поиск среди всех записей, полученных в результате полноценного поиска, иногда очень сложно. Запрос можно уточнить с помощью фильтров поиска, таких как memberOf. За подробностями обратитесь к вашему администратору каталога LDAP и документации.

role #

Задаёт правило для описания одной или нескольких ролей, которые требуются в целевом кластере Postgres Pro. Описание включает имя (name), атрибуты (options), конфигурацию (config), членство (membership) роли и комментарий (comment). Форма множественного числа roles допустима. Значение может включать как одно правило, так и список правил.

rules:
- role:
    name: dba
    options: SUPERUSER LOGIN
- roles:
  - name: group0
    options: NOLOGIN
  - name: group1
    options: NOLOGIN
comment #

Определяет SQL-комментарий к роли. Значение по умолчанию: Managed by ldap2pg. В параметр можно внедрять атрибуты LDAP.

При внедрении атрибутов LDAP нужно обращать внимание на количество создаваемых комбинаций. Если шаблон генерирует один комментарий, ldap2pg скопирует комментарий для каждой роли, созданной по правилу для назначения ролей. Если шаблон генерирует несколько комментариев, то ldap2pg связывает имя роли и комментарий. Если сгенерированных комментариев больше или меньше, чем ролей, возникнет сбой в работе ldap2pg.

Пример определения статического комментария, общего для всех созданных ролей:

rules:
- roles:
    names:
    - alice
    - bob
    comment: "Static roles from YAML."

Пример генерации единого комментария из уникального имени записи LDAP, который копируется для всех созданных ролей:

rules:
- ldapsearch:
    ...
  role:
    name: "{cn}"
    comment: "Generated from LDAP entry {dn}."

Пример генерации уникального комментария для каждой созданной роли:

rules:
- ldapsearch:
    ...
  role:
    name: "{member.cn}"
    comment: "Generated from LDAP entry {member}."

Подсказка

Если роль определяется несколько раз, родительские роли объединяются. Другие поля остаются такими же, как в первом определении роли.

name #

Имя роли, которая требуется в кластере. Значение может включать одну строку или список строк. Форма множественного числа names допустима. В параметр можно внедрять атрибуты LDAP в фигурных скобках. Если определяется несколько имён, для каждого имени определяется отдельная роль, используя одинаковые атрибуты, такие как options и parents. Параметр comment подчиняется отдельным правилам, за подробностями обратитесь к пункту comment.

rules:
- roles:
    name: "my-role-name"

При внедрении атрибута LDAP в имя каждое значение атрибута LDAP каждой записи LDAP будет определять новую роль. Если в формате определены несколько атрибутов LDAP, будет сгенерированы все комбинации атрибутов.

ldap2pg заключает имя роли в двойные кавычки в целевом кластере Postgres Pro. Капитализация сохраняется, пробелы допускаются (даже если содержательно они неуместны).

К этому параметру ldap2pg применяет ограничение roles_blacklist_query.

options #

Определяет атрибуты роли Postgres Pro. Параметр может представлять собой строку, похожую на SQL-строку, или YAML-словарь. Допустимые варианты: BYPASSRLS, CONNECTION LIMIT, LOGIN, CREATEDB, CREATEROLE, INHERIT, REPLICATION и SUPERUSER. Доступные значения зависят от версии целевого кластера Postgres Pro и прав пользователя ldap2pg.

- roles:
  - name: my-dba
    options: LOGIN SUPERUSER
  - name: my-group
    options:
      LOGIN: no
      INHERIT: yes
config #

Определяет конфигурационные параметры Postgres Pro, которые будут заданы для роли. Должен быть YAML-словарем. Доступные конфигурационные параметры зависят от версии целевого кластера Postgres Pro. Чтобы задать некоторые параметры, требуются права суперпользователя. Отсутствие прав для установки значений конфигурационного параметра приведёт к сбою в работе ldap2pg.

- roles:
  - name: my-db-writer
    config:
      log_statement: mod
      log_min_duration_sample: 100

Если задать параметру config значение null (значение по умолчанию), функционал для роли будет отключён. Если в параметре config словарь, ldap2pg удалит параметры, заданные в кластере, но не определённые в YAML-файле конфигурации ldap2pg. Чтобы сбросить все параметры, задайте в параметре config пустой словарь, как в примере ниже.

- roles:
  - name: reset-my-configuration
    config: {}

Обратите внимание, что атрибуты LDAP не раскрываются в значениях конфигурационных параметров.

parent #

Имя родительской роли. Допускается список имён. Форма множественного числа parents также допустима. Родительская роль назначается с помощью команды GRANT ROLE parent TO role;. В параметр parent можно внедрять атрибуты LDAP в фигурных скобках. К этому параметру ldap2pg применяет ограничение roles_blacklist_query. Родительской ссылкой могут быть локальные роли, которыми не управляет ldap2pg.

rules:
- role:
    name: myrole
    parent: myparent
before_create #

SQL-фрагмент, который необходимо выполнить перед созданием роли. В before_create можно внедрять атрибуты LDAP в фигурных скобках. Экранирование атрибута с помощью .identifier() или .string() — ответственность пользователя.

rules:
- ldapsearch: ...
  role:
    name: "{cn}"
    before_create: "INSERT INTO log VALUES ({cn.string()})"
after_create #

SQL-фрагмент, который необходимо выполнить после создания роли. В after_create можно внедрять атрибуты LDAP в фигурных скобках. Экранирование атрибута с помощью .identifier() или .string() — ответственность пользователя.

rules:
- ldapsearch: ...
  role:
    name: "{sAMAccountName}"
    after_create: "CREATE SCHEMA {sAMAccountName.identifier()} AUTHORIZATION {sAMAccountName.identifier()}"
grant #

Отвечает за предоставление прав роли с соответствующими параметрами. Может быть сопоставлением или списком сопоставлений. Форма множественного числа grants также допустима.

rules:
- grant:
    privilege: reader
    databases: __all__
    schema: public
    role: myrole
database

Ограничивает предоставление прав одной или несколькими базами данных. Может быть списком имён. Форма множественного числа databases допустима. Специальное значение __all__ позволяет распространить настройку на все управляемые базы данных, список которых был получен с помощью databases_query. Значение по умолчанию: __all__. Предоставленные права, найденные в других базах данных, будут отозваны. В параметр можно внедрять атрибуты LDAP в фигурных скобках.

Этот параметр игнорируется, если речь идёт о правах, которые действуют на уровне экземпляра (например, права для настройки LANGUAGE).

privilege

Имя права из списка прав, определённого в разделе privileges YAML-файла конфигурации. Может быть списком имён. Форма множественного числа privileges допустима. Параметр обязательный, значение по умолчанию отсутствует. В параметр можно внедрять атрибуты LDAP в фигурных скобках.

role

Имя целевой роли предоставляемого права (роль с предоставленным правом (granted role) или правообладатель (grantee)). Должно быть указано в списке managed_roles_query. Может быть списком имён. Форма множественного числа roles доступна. В параметр можно внедрять атрибуты LDAP в фигурных скобках. К этому параметру ldap2pg применяет ограничение roles_blacklist_query.

schema

Имя схемы из списка схем, полученного с помощью schemas_query. Специальное значение __all__ включает все управляемые схемы баз данных. Может быть списком имён. Форма множественного числа schemas допустима. В параметр можно внедрять атрибуты LDAP в фигурных скобках.

Этот параметр игнорируется для прав доступа к DATABASE или для других прав, которые действуют на уровне экземпляра или базы данных.

owner

Имя роли, для которой необходимо настроить права по умолчанию. Специальное значение __auto__ сводит настройку к управляемым ролям с правом CREATE в целевой схеме. Может быть списком имён. Форма множественного числа owners допустима. В параметр можно внедрять атрибуты LDAP в фигурных скобках.

Раздел acls #

Определяет списки Postgres Pro ACL. ACL — это набор запросов, которые позволяют отображать список предоставленных прав в кластере и управлять правами, предоставляя и отзывая их для элементов списка. Действие ACL ограничено экземпляром или базой данных. Параметр добавляется в профили прав для ссылки на ACL. Написать пользовательский ACL — непростая задача. Для её выполнения необходимо понимание PostgreSQL и ldap2pg.

acls

Раздел верхнего уровня acls — сопоставление, определяющее списки ACL. Все поля являются обязательными.

acls:
  PROCEDURE:
    scope: database
    inspect: |
      WITH ...
    grant: GRANT ...
    revoke: REVOKE ...
scope #

Область действия ACL. Параметр может принимать значение instance или database.

inspect #

SQL-запрос, который выдаёт список предоставленных прав в кластере. Сигнатура запроса зависит от области действия ACL. За подробностями обратитесь к описанию пользовательского ACL.

grant #

SQL-запрос для предоставления права. В запрос можно добавить шаблон в угловых скобках. Некоторые параметры внедряются как ключевые слова, то есть как в обычных SQL-запросах. Некоторые заключают в кавычки как идентификаторы.

Доступные параметры:

  • <acl> имя ACL. Обычный SQL-запрос.

  • <database> имя базы данных, к которой предоставляют доступ. Идентификатор в кавычках.

  • <grantee> имя роли, которой предоставляют права. Идентификатор в кавычках.

  • <object> имя объекта, к которому нужно предоставить доступ. Идентификатор в кавычках.

  • <owner> имя роли, которой необходимо предоставить права. Идентификатор в кавычках.

  • <privilege> тип права. Обычный SQL-запрос.

  • <schema> имя схемы, к которой нужно предоставить доступ. Идентификатор в кавычках.

revoke #

SQL-запрос, чтобы отозвать право. Как и в запрос grant, в этот запрос можно добавить шаблон в угловых скобках. Принимает те же параметры, что и запрос для предоставления прав. Добавление других параметров между GRANT и REVOKE даёт непредсказуемый результат.

Проверка кластера Postgres Pro #

Работа ldap2pg подчиняется принципам явного создания/неявного удаления и явного назначения/неявного отзыва. По этой причине проверять кластер на предмет того, что необходимо удалить/отозвать, очень важно для успешной синхронизации.

ldap2pg проверяет базы данных, схемы, роли, владельцев и предоставленные права через SQL-запросы. В разделе postgres YAML-файла конфигурации можно настроить такие запросы при помощи параметров, которые заканчиваются _query. За подробностями обратитесь к Подразделу «Раздел postgres».

Какие базы данных необходимо синхронизировать? #

Запрос databases_query возвращает плоский список баз данных для управления. В результате выполнения запроса databases_query в список должна попасть база данных по умолчанию, определённая в PGDATABASE. При удалении ролей ldap2pg циклично просматривает список баз данных, чтобы переназначить объекты и отозвать права, предоставленные ролям, которые будут удалены. Список баз данных также позволяет сузить рамки проверки предоставленных прав. ldap2pg будет отзывать предоставленные права только в базах данных из списка. За подробностями обратитесь к Подразделу «Раздел postgres».

postgres:
  databases_query: |
    SELECT datname
    FROM pg_catalog.pg_database
    WHERE datallowconn IS TRUE;

Синхронизация подмножества ролей #

По умолчанию ldap2pg управляет всеми ролями Postgres Pro, к которым имеет доступ, кроме ролей, добавленных в чёрный список по умолчанию. Чтобы ldap2pg синхронизировало только подмножество ролей, необходимо настроить выборку внутри postgres:managed_roles_query. Пример запроса ниже позволяет исключить суперпользователей из объектов для синхронизации.

postgres:
  managed_roles_query: |
    SELECT 'public'
    UNION
    SELECT rolname
    FROM pg_catalog.pg_roles
    WHERE rolsuper IS FALSE
    ORDER BY 1;

ldap2pg будет выполнять операции по удалению, отзыву и предоставлению прав только для тех ролей, которые будут получены в результате этого запроса.

Часто подобный запрос ограничивает выборку одной группой, например, ldap_roles. Таким образом ldap2pg работает только с подмножеством ролей в кластере.

Роли public нет в системном каталоге. Поэтому чтобы ldap2pg управляло правами public, необходимо явно включить роль public в список управляемых ролей. Это настройки по умолчанию. Но даже если роль public управляемая, ldap2pg не будет удалять или менять её, если её нет в каталоге.

Чтобы полностью исключить некоторые роли из выборки, можно использовать roles_blacklist_query.

postgres:
  roles_blacklist_query: [postgres, pg_*]  # Это значение по умолчанию.

Примечание

Элементы, которые вводятся '*', необходимо заключать в кавычки. В противном случае произойдёт ошибка при обработке YAML, например, «found undefined alias (найдены неопределённые псевдонимы)».

Проверка схем #

Для управления правами, которые действуют на уровне схем, ldap2pg необходимо знать, какими схемами оно может управлять в рамках каждой базы данных. Для этого используется запрос schemas_query.

Настройка прав по умолчанию для роли владельца #

Чтобы настроить права по умолчанию, ссылаясь на право, используйте ключевое слово default:

privileges:
  reading:
  - default: global
    type: SELECT
    on: TABLES

Затем предоставьте право, используя правило предоставления прав:

rules:
- grant:
  - privilege: reading
    role: readers
    schema: public
    owner: ownerrole

В качестве владельца можно использовать роль __auto__. Для каждой схемы ldap2pg настроит все управляемые роли, которые имеют право CREATE в схеме.

rules:
- grant:
  - privilege: reading
    role: readers
    schema: public
    owner __auto__

ldap2pg настраивает права по умолчанию в последнюю очередь после всех действующих прав. Таким образом право CREATE в схеме предоставляется до того, как ldap2pg проверит роли создателей в схемах.

Статические запросы #

Все запросы можно заменить статическим списком в формате YAML. Этот список будет использоваться, как будто он получен от Postgres Pro. Это очень удобно, если нужно заморозить какое-то значение, например, указание на базы данных или схемы.

postgres:
  databases_query: [postgres]
  schemas_query: [public]

Управление ролями #

ldap2pg выполняет синхронизацию ролей Postgres Pro в три этапа:

  1. Циклично просматривает rules и генерирует список с необходимыми ролями из правил role.

  2. Проверяет в Postgres Pro существующие роли, их атрибуты и членство.

  3. Сравнивает два набора ролей и применяет необходимые изменения к кластеру Postgres Pro с помощью команд CREATE, DROP и ALTER.

Каждая запись role в rules является правилом, по которому роль не создаётся или создаётся одна или несколько ролей с соответствующими параметрами. role — это своеобразный шаблон. Правила role позволяют избежать дублирования членства и атрибутов роли с помощью заданного списка имён.

В одном файле можно использовать и статические, и динамические правила.

Запуск без прав суперпользователя #

Расширение ldap2pg предназначено для работы от имени не суперпользователя. Пользователь, который будет выполнять синхронизацию, должен иметь атрибут CREATEROLE, чтобы управлять другими ролями не суперпользователя. Атрибут CREATEDB позволяют такому пользователю управлять владельцами баз данных.

Чтобы пользователь ldap2pg мог правильно управлять группами, параметру createrole_self_grant должно быть задано значение inherit,set.

CREATE ROLE ldap2pg LOGIN CREATEDB CREATEROLE;
ALTER ROLE ldap2pg SET createrole_self_grant TO 'inherit,set;

Запуск без прав суперпользователя до версии PostgreSQL 16 реализован некорректно. В таких случаях в целях безопасности рекомендуется запускать ldap2pg с правами суперпользователя.

Игнорирование ролей #

ldap2pg полностью игнорирует роли, которые соответствуют одному из глобальных шаблонов, определённых в roles_blacklist_query:

    postgres:
      # Это значение по умолчанию.
      roles_blacklist_query: [postgres, pg_*]
    

Черный список ролей также влияет на предоставление прав. ldap2pg не будет выполнять команды grant и revoke для роли, которая соответствует одному из элементов черного списка.

ldap2pg помещает в чёрный список своего пользователя.

Членство #

ldap2pg управляет родительскими ролями. К ним ldap2pg применяет ограничение roles_blacklist_query. Однако ldap2pg может предоставлять права неуправляемым родительским ролям. Таким образом можно создавать группу вручную и управлять её членами с помощью ldap2pg.

Запрос из каталога через LDAP #

ldap2pg читает поисковые запросы LDAP через записи в ldapsearch в порядке, определённом в rules.

Поисковой запрос LDAP не является обязательным. ldap2pg может создавать роли, определённые статически из YAML-файла конфигурации. Каждый поисковой запрос LDAP выполняется только один раз. Цикличное выполнение или устранение дубликатов для поисковых запросов LDAP невозможно.

Подсказка

ldap2pg регистрирует поисковые запросы LDAP в журнале как команды ldapsearch. Чтобы увидеть записи, включите подробные сообщения.

Чтобы поправить неправильный поисковой запрос, скопируйте команду в вашу оболочку и обновите параметры. Если всё работает, отправьте верные параметры обратно в YAML.

Конфигурация доступа к каталогу #

ldap2pg читает конфигурацию каталога из файла ldaprc и через переменные окружения LDAP*. Доступные параметры LDAP:

  • BASE

  • BINDDN

  • PASSWORD

  • REFERRALS

  • SASL_AUTHCID

  • SASL_AUTHZID

  • SASL_MECH

  • TIMEOUT

  • TLS_REQCERT

  • NETWORK_TIMEOUT

  • URI

За подробностями о значении и формате каждого параметра обращайтесь к странице man ldap.conf(5).

Внедрение атрибутов LDAP #

В ряд параметров можно внедрить атрибуты LDAP в фигурных скобках. Для этого заключите имя атрибута в фигурные скобки. Например, {cn} или {sAMAccountName}. ldap2pg расширяется до всех значений атрибута для каждой записи, найденной в результате поиска.

Если в параметре несколько атрибутов LDAP, ldap2pg получает все комбинации атрибутов для каждой записи.

Рассмотрим следующие записи LDAP:

dn: uid=dimitri,cn=Users,dc=bridoulou,dc=fr
objectClass: inetOrgPerson
uid: dimitri
sn: Dimitri
cn: dimitri
mail: dimitri@bridoulou.fr
company: external
dn: cn=domitille,cn=Users,dc=bridoulou,dc=fr
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
cn: domitille
sn: Domitille
company: acme
company: external

Формат {company}_{cn} с приведёнными выше записями LDAP сгенерирует следующие строки:

  • acme_domitille

  • external_domitille

  • external_dimitri

Псевдоатрибут dn всегда доступен и ссылается на уникальное имя (DN) исходной записи LDAP.

Регистр атрибутов LDAP #

При внедрении атрибута LDAP в фигурных скобках можно задать регистр с помощью методов .lower() или .upper().

- ldapsearch: ...
  role: "{cn.lower()}"

Управление правами #

Управлять правами довольно сложно. ldap2pg пытается сделать этот процесс легче и безопаснее.

Основы #

Основной принцип работы ldap2pg таков: вместо того, чтобы отзывать все права и роли и переназначать их, ldap2pg идёт по пути «проверить и изменить». Процесс аналогичен тому, как происходит синхронизация ролей, включая следующие три этапа:

  1. Циклично просмотреть rules и сгенерировать набор необходимых назначений.

  2. Проверить в кластере Postgres Pro назначенные права.

  3. Сравнить два набора и обновить значения в кластере Postgres Pro с помощью команд grant и revoke.

ldap2pg оперирует следующими основными объектами при управлении правами:

  • Privilege: действие, которое разрешается выполнять с объектом, например, CONNECT ON DATABASE.

  • grant: право, предоставленное роли в отношении объекта.

  • ACL: список назначений (grant).

  • profile: список прав.

  • rule: шаблон для предоставления необходимого права.

В файле ldap2pg.yml содержатся профили прав и правила назначения прав. ldap2pg синхронизирует ACL по одному, базу данных за базой данных. В последнюю очередь ldap2pg синхронизирует права по умолчанию.

По умолчанию ldap2pg не управляет правами. Чтобы включить управление правами, сначала необходимо определить хотя бы один активный профиль в разделе privileges. Проще всего переиспользовать в активном пользовательском профиле встроенные профили прав, входящие в дистрибутив ldap2pg.

Определение профилей прав #

Профиль прав — список ссылок на типы прав, связанные с ACL, или другие профили.ldap2pg устанавливает несколько предопределённых ACL, таких как DATABASE, LANGUAGE и т. д. Тип права может иметь значение USAGE, CONNECT и т.д, в соответствии с описанием в Разделе 5.7. За подробностями о формате профиля прав обратитесь к документации, посвященной YAML-разделу privileges.

ldap2pg загружает ACL, на который даётся ссылка, через проверку в кластере Postgres Pro с помощью детально прописанных запросов. ldap2pg проверяет только ACL, на которые даётся ссылка хотя бы в одном профиле. Найденные в кластере назначения прав отзываются, если иное явно не прописано в правиле grant.

Предупреждение

Если назначение не подпадает под правило, права отзываются!

После проверки ACL ldap2pg отзывает все назначенные права, найденные в экземпляре Postgres Pro и не требуемые ни в одном правиле grant в разделе rules.

Расширенная проверка экземпляра #

При управлении ролями ldap2pg проводит более глубокую проверку экземпляра Postgres Pro. После синхронизации ролей и перед синхронизацией прав ldap2pg проверяет схемы. После синхронизации прав и перед синхронизацией прав по умолчанию ldap2pg проверяет владельца объектов. Владелец объекта — это роль, у которой есть право CREATE в схеме.

Назначение профиля прав #

Проверка миллионов прав отнимает у экземпляра Postgres Pro много ресурсов. Известно, что процесс отзыва прав в Postgres Pro медленный. Лучше всего назначать права группе ролей, чтобы пользователи наследовали права. ldap2pg позволяет определять статические группы в YAML и наследовать их при создании роли из каталога.

Используйте grant rule, чтобы назначить профиль прав одной или нескольким ролям. При назначении прав необходимо определить правообладателя. Назначение можно ограничить одной или несколькими базами данных, а также одной или несколькими схемами. Если профиль прав включает права по умолчанию, можно определить владельцев, которым будут назначены права по умолчанию.

По умолчанию назначение применяется ко всем управляемым базам данных, список которых возвращается databases_query, а также ко всем схемам каждой базы данных, список которых возвращается schemas_query.

Пример #

В примере ниже определён профиль с тремя правами. В rules определяются три группы ролей, и им назначается соответствующий профиль прав:

privileges:
  reading:
  - __connect__
  - __usage_on_schemas__
  - __select_on_tables__
  writing:
  - reading  # включает права чтения
  - __insert_on_tables__
  - __update_on_tables__
  owning:
  - writing
  - __create_on_schemas__
  - __truncate_on_tables__
rules:
- role:
  - names:
    - readers
    - writers
    - owners
    options: NOLOGIN
- grant:
  - privilege: reading
    role: readers
  - privilege: writing
    role: writers
  - privilege: owning
    role: owners

Ещё один способ включить права чтения данных в права записи — сделать так, чтобы группа ролей с правами записи (writers) наследовала группу ролей с правами чтения (readers).

Управление правами public #

В Postgres Pro есть псевдороль с именем public. Это универсальная роль, которая включает всех пользователей. Все роли в Postgres Pro неявно наследуют от роли public. При назначении права роли public это право также назначается всем существующим ролям и ролям, которые будут созданы в дальнейшем.

У Postgres Pro также есть схема public. Схема public — это существующая схема, которая доступна во всех базах данных.

В Postgres Pro есть несколько встроенных прав для роли public и особенно для схемы public. Например, у public есть право CONNECT ко всем базам данных по умолчанию. Это означает, что для конфигурации доступа к базам данных можно использовать только файл pg_hba.conf, что требует прав администратора для доступа к кластеру и вызова функции pg_reload_conf().

По умолчанию ldap2pg включает роль public в список управляемых ролей. Предопределённый ACL знает, как проверять встроенные права, назначенные роли public. Если роль public нужно сохранить, исключите роль public из managed_roles_query.

Управление правами по умолчанию #

Если права SELECT предоставляются роли на все таблицы в схеме, права не будут распространяться на новые таблицы, созданные после предоставления прав. Вместо того, чтобы после создания каждого нового объекта выполнять ldap2pg заново, в Postgres Pro предусмотрено определение прав по умолчанию для объектов, которые будут созданы в дальнейшем.

Postgres Pro привязывает права по умолчанию к роли создателя (creator). Когда пользователь с этой ролью создаёт объект, Postgres Pro предоставляет соответствующие права по умолчанию новому объекту. Например, благодаря команде ALTER DEFAULT PRIVILEGES FOR ROLE bob GRANT SELECT ON TABLES TO alice; в каждой новой таблице, создаваемой пользователем с ролью bob у пользователя с ролью alice будет право SELECT:

Если ldap2pg создаёт или удаляет роли создателя, права по умолчанию для этих ролей в ldap2pg должны быть правильно настроены. При управлении правами через ldap2pg обязательно настраивать права по умолчанию для роли создателя.

ldap2pg проверяет создателей в Postgres Pro, по схемам, не в каталоге LDAP. Создатель — это роль с атрибутом LOGIN и правом CREATE в схеме. Вручную для любой управляемой роли можно назначить целевого владельца предоставляемых прав.

В ldap2pg нельзя настроить права на схемы с атрибутом __all__. Вместо этого используйте список ACL GLOBAL DEFAULT. Если предоставление и отзыв прав по умолчанию необходимо ограничить схемой, используйте список ACL SCHEMA DEFAULT.

В примере ниже для роли alice настраиваются права по умолчанию, благодаря которым у роли bob будет право SELECT для всех таблиц, которые alice будет создавать в дальнейшем.

privileges:
  reading:
  - type: SELECT
    on: SCHEMA DEFAULT
    object: TABLES
  owning:
  - type: CREATE
    on: SCHEMAS

rules:
- roles:
    names:
    - alice
    - bob
    options: LOGIN
- grant:
    privilege: owning
    role: alice
- grant:
    privilege: reading
    role: bob

В Postgres Pro есть жёстко заданные глобальные права по умолчанию. Если у роли не настроены глобальные права по умолчанию, Postgres Pro подразумевает некоторые права. По умолчанию Postgres Pro предоставляет права только роли владельца (owner). Их можно посмотреть при изменении прав по умолчанию. Postgres Pro скопирует жёстко заданные значения вместе с предоставленными вами правами.

Если явно повторно не предоставить жёстко заданные права в файле ldap2pg.yml, ldap2pg отзовет их. Обратите внимание, что владельцу таблицы не нужно предоставлять право SELECT для принадлежащих ему таблиц. Поэтому в жёстко заданных правах по умолчанию нет необходимости. Так что можно разрешить ldap2pg убрать эти ненужные права по умолчанию.

Встроенные права #

ldap2pg предоставляет несколько встроенных списков ACL и предопределённых профилей прав для множественного использования. Эти права предоставляются не гарантированно. Их настройку в ваших базах данных необходимо проверять точно так же, как и при работе со своим кодом.

Использование предопределённых профилей прав #

Профиль прав — список ссылок на тип права в ACL. В ldap2pg ACL — набор запросов для проверки, предоставления и отзыва прав на классы объектов. Запрос на проверку расширяет тип aclitem Postgres Pro для отображения всех предоставленных прав из системного каталога. Профиль прав может включать другой профиль.

Имя встроенного профиля обрамляется двойным нижним подчёркиванием (__). ldap2pg отключает профиль прав, который начинается с _. Чтобы включить такие профили, необходимо добавить встроенный профиль прав в другой профиль. Если два профиля ссылаются на одно и то же право, ldap2pg проверит его один раз.

privileges:
  ro:
  - __connect__
  - __usage_on_schemas__
  - __select_on_tables__

  rw:
  - ro
  - __insert__

  ddl:
  - rw
  - __all_on_schemas__

rules:
- grant:
    privilege: ddl
    database: mydb
    role: admins

Имя встроенного профиля подчиняется следующим нестрогим правилам:

  • ..._on_all_tables__ ссылается на список ACL ALL TABLES IN SCHEMA. Аналогично для последовательностей и функций.

  • __default_...__ ссылается на права по умолчанию, которые действуют на глобальном уровне и на уровне схемы.

  • __..._on_tables__ объединяет __..._on_all_tables__ и __default_..._on_tables__.

  • Группа, чьё имя начинается с __all_on_...__, приравнивается к разрешению ALL PRIVILEGES в SQL. Однако каждое право будет предоставляться отдельно.

  • В имени права, относящегося к одному типу объектов, нет суффикса _on_<type>. Например, __delete_on_tables__ — псевдоним __delete__.

В этом разделе не описан стандарт SQL и значение каждого права SQL. За подробностями о правах SQL обратитесь к документации команд GRANT и ALTER DEFAULT PRIVILEGES.

Справка по ACL #

Ниже приведён список встроенных списков ACL.

Для действующих прав:

DATABASE

Права в базе данных, такие как CONNECT, CREATE и т. д.

SCHEMA

Управление правами USAGE и CREATE в схеме.

LANGUAGE

Управление правом USAGE для процедурных языков.

ALL FUNCTIONS IN SCHEMA

Управление правом EXECUTE для всех функций в рамках схемы.

ALL SEQUENCES IN SCHEMA

То же самое, но для последовательностей.

ALL TABLES IN SCHEMA

То же самое, но для таблиц и представлений.

GLOBAL DEFAULT

Управление правами по умолчанию в базе данных.

SCHEMA DEFAULT

Управление правами по умолчанию в рамках схемы.

Список ACL ALL ... IN SCHEMA проверяет, предоставлено ли право только подмножеству объектов. Это называется частичное предоставление права (partial grant). Частично предоставленное право или отзывается, если оно не нужно, или предоставляется заново, если ожидается.

Дать ссылку на эти списки ACL можно, используя параметр privileges: on в YAML. Пример:

privileges:
  myprofile:
  - type: SELECT
    on: ALL TABLES IN SCHEMA

Права по умолчанию ссылаются на тип права и класс объектов. ldap2pg проверяет права по умолчанию для следующих классов объектов:

  • SEQUENCES

  • FUNCTIONS

  • TABLES

В профиле прав необходимо дать ссылку на класс объектов с помощью параметра object в YAML.

Настроить пользовательский ACL пока невозможно.

Справка по правам #

Ниже приведён список предопределённых прав:

ИмяПраво
__connect__CONNECT ON DATABASE
__create_on_schemas__CREATE ON SCHEMA
__delete_on_all_tables__DELETE ON ALL TABLES IN SCHEMA
__execute_on_all_functions__EXECUTE ON ALL FUNCTIONS IN SCHEMA
__insert_on_all_tables__INSERT ON ALL TABLES IN SCHEMA
__references_on_all_tables__REFERENCES ON ALL TABLES IN SCHEMA
__select_on_all_sequences__SELECT ON ALL SEQUENCES IN SCHEMA
__select_on_all_tables__SELECT ON ALL TABLES IN SCHEMA
TEMPORARY ON DATABASE
__trigger_on_all_tables__TRIGGER ON ALL TABLES IN SCHEMA
__truncate_on_all_tables__TRUNCATE ON ALL TABLES IN SCHEMA
__update_on_all_sequences__UPDATE ON ALL SEQUENCES IN SCHEMA
__update_on_all_tables__UPDATE ON ALL TABLES IN SCHEMA
__usage_on_all_sequences__USAGE ON ALL SEQUENCES IN SCHEMA
__usage_on_schemas__USAGE ON SCHEMA

Справка по правам по умолчанию #

Ниже приведён список предопределённых прав по умолчанию. В профиле прав по умолчанию даётся ссылка на права по умолчанию, которые действуют на глобальном уровне и на уровне схемы.

ИмяПраво
__default_delete_on_tables__DELETE ON TABLES
__default_execute_on_functions__EXECUTE ON FUNCTIONS
__default_insert_on_tables__INSERT ON TABLES
__default_references_on_tables__REFERENCES ON TABLES
__default_select_on_sequences__SELECT ON SEQUENCES
__default_select_on_tables__SELECT ON TABLES
__default_trigger_on_tables__TRIGGER ON TABLES
__default_truncate_on_tables__TRUNCATE ON TABLES
__default_update_on_sequences__UPDATE ON SEQUENCES
__default_update_on_tables__UPDATE ON TABLES
__default_usage_on_sequences__USAGE ON SEQUENCES

Подсказки по использованию #

В этом разделе даются некоторые рецепты для различных пользовательских сценариев работы с ldap2pg.

Конфигурирование pg_hba.conf через LDAP #

ldap2pg НЕ настраивает Postgres Pro за пользователя. Для конфигурирования Postgres Pro внимательно прочитайте Раздел 19.10. Перед написанием ldap2pg.yaml стоит надлежащим образом настроить Postgres Pro. Ниже приведёны шаги для настройки Postgres Pro через LDAP в рекомендуемом порядке:

  1. Напишите поисковой запрос LDAP и проверьте его с помощью ldapsearch(1). Это также позволяет проверить соединение с вашим каталогом LDAP.

  2. В кластере Postgres Pro вручную создайте единственную роль, поместив пароль от неё в каталог LDAP.

  3. Внесите изменения в файл pg_hba.conf, следуя Разделу 19.10, чтобы успешно авторизоваться с паролем из LDAP в созданной роли.

После настройки аутентификации LDAP в кластере Postgres Pro можно переходить к автоматизации процесса создания ролей из каталога LDAP с помощью ldap2pg:

  1. Напишите простой файл ldap2pg.yaml с одним поисковым запросом LDAP, чтобы настроить параметры соединения ldap2pg с Postgres Pro и сервером LDAP. По умолчанию ldap2pg работает в пробном режиме, поэтому можно без опасений циклично запускать ldap2pg, пока расширение не будет настроено корректно.

  2. Затем дополните файл ldap2pg.yaml в соответствии с вашими потребностями, следуя Разделу «Справка по командной строке». Запустите ldap2pg в режиме действия и проверьте, что ldap2pg поддерживает созданную вами единственную тестовую роль и что через неё можно установить соединение с кластером.

  3. Наконец определите, когда и как будет запускаться синхронизация: регулярно с помощью файла crontab/через задачу Ansible/вручную/ по-другому. Убедитесь, что ldap2pg запускается регулярно, целенаправленно и с уведомлениями.

Поиск в каталоге LDAP #

Первый шаг — выполнить поиск в вашем сервере LDAP с помощью ldapsearch(1), утилиты командной строки из дистрибутива OpenLDAP. Пример:

$ ldapsearch -H ldaps://ldap.ldap2pg.docker -U testsasl -W
Enter LDAP Password:
SASL/DIGEST-MD5 authentication started
SASL username: testsasl
SASL SSF: 128
SASL data security layer installed.
# extended LDIF
#
# LDAPv3
...
# search result
search: 4
result: 0 Success

# numResponses: 16
# numEntries: 15
$

Сохраните настройки в файле ldaprc:

LDAPURI ldaps://ldap.ldap2pg.docker
LDAPSASL_AUTHCID testsasl

И в окружении: LDAPPASSWORD=secret

Затем обновите ldapsearch, чтобы правильно сопоставить записи ролей на сервере LDAP:

$ ldapsearch -H ldaps://ldap.ldap2pg.docker -U testsasl -W -b cn=dba,ou=groups,dc=ldap,dc=ldap2pg,dc=docker '' member
...
# dba, groups, ldap.ldap2pg.docker
dn: cn=dba,ou=groups,dc=ldap,dc=ldap2pg,dc=docker
member: cn=Alan,ou=people,dc=ldap,dc=ldap2pg,dc=docker
member: cn=albert,ou=people,dc=ldap,dc=ldap2pg,dc=docker
member: cn=ALICE,ou=people,dc=ldap,dc=ldap2pg,dc=docker

# search result
search: 4
result: 0 Success

...
$

Теперь перенесите запрос в ldap2pg.yaml и установите сопоставление ролей, чтобы создавать роли из каждого значения каждой записи, которую возвращает поисковой запрос LDAP:

- ldapsearch:
    base: cn=dba,ou=groups,dc=ldap,dc=ldap2pg,dc=docker
  role:
    name: '{member.cn}'
    options: LOGIN SUPERUSER

Выполните проверку:

$ ldap2pg
...
Querying LDAP cn=dba,ou=groups,dc=ldap,dc=ldap2pg,dc=docker...
Would create alan.
Would create albert.
Would update options of alice.
...
Comparison complete.
$

За подробностями о том, как управлять созданием ролей из записи LDAP, обратитесь к разделу Конфигурация. Когда результат сравнения будет удовлетворительным, перейдите в режим действия с помощью --real.

Использование отказоустойчивости LDAP #

Встроенный функционал ldap2pg включает поддержку отказоустойчивости LDAP точно так же, как расширение поддерживает любого клиента OpenLDAP. Чтобы указать все серверы, перечислите их URI через пробел.

$ LDAPURI="ldaps://ldap1 ldaps://ldap2" ldap2pg

За подробностями обратитесь к ldap.conf(5).

Запуск не от имени суперпользователя #

Поскольку у ролей в Postgres Pro> есть атрибут CREATEROLE, управлять ролями можно без прав суперпользователя. С точки зрения безопасности лучше управлять ролями без прав суперпользователя.

Предупреждение

До версии Postgres Pro 15 пользователь с правом CREATEROLE почти приравнивался к суперпользователю. Такой пользователь мог предоставить себе самому практически любое право. Поэтому ldap2pg поддерживает запуск не от имени суперпользователя только с версиями Postgres Pro 16 и выше.

ldap2pg поддерживает такой сценарий. Однако стоит внимательно относиться к ограничениям. Назовем роль не суперпользователя, которая даёт возможность создавать другие роли, creator.

  • Невозможно управлять такими атрибутами ролей, как SUPERUSER, BYPASSRLS и REPLICATION. Поэтому обнаружить ложных суперпользователей не получится.

  • Убедитесь, что creator может отзывать все права, предоставляемые управляемым пользователям.

Удаление всех ролей #

Если в какой-то момент потребуется удалить все роли в кластере Postgres Pro, использовать расширение ldap2pg будет эффективно. Для удаления ролей явно определите пустые правила (rules).

$ echo '{version: 6, rules: []}' | ldap2pg --config -
...
Empty synchronization map. All roles will be dropped!
...

В этом примере применяется чёрный список по умолчанию. ldap2pg никогда не удаляет свою роль, которую использует для установки соединения.

ldap2pg как Docker-контейнер #

Предполагается, что это не первая встреча пользователя с Docker, поэтому в этом разделе настройки описаны не будут.

Чтобы запустить контейнер, используйте следующую команду:

$ docker run --rm dalibo/ldap2pg --help

В образе Docker для ldap2pg используются те же конфигурационные параметры, которые описаны в разделах Интерфейс командной строки и ldap2pg.yml. Можно подключить файл конфигурации ldap2pg.yml.

$ docker run --rm -v ${PWD}/ldap2pg.yml:/workspace/ldap2pg.yml dalibo/ldap2pg

Можно также экспортировать некоторые переменные окружения с помощью параметра -e:

$ docker run --rm -v ${PWD}/ldap2pg.yml:/workspace/ldap2pg.yml -e PGDSN=postgres://postgres@localhost:5432/ -e LDAPURI=ldaps://localhost -e LDAPBINDDN=cn=you,dc=entreprise,dc=fr -e LDAPPASSWORD=pasglop dalibo/ldap2pg

Убедитесь, что контейнер может разрешить имя компьютера, на который даётся указание. При использовании внутренних разрешений имени не забудьте добавить к вашей команде параметр -dns=, который указывает на ваш внутренний DNS-сервер. За подробностями обратитесь сюда.

Пользовательский ACL #

В ldap2pg встроены списки ACL для общих объектов, таких как DATABASE, SCHEMA, TABLE, FUNCTION и т. д. В Postgres Pro есть много других объектов, таких как FOREIGN DATA WRAPPER, FOREIGN SERVER, FOREIGN TABLE, TYPE и т. д. В такой ситуации может возникнуть потребность в управлении пользовательским ACL. Для этого можно написать пользовательский ACL.

Примечание

Чтобы написать пользовательский ACL, требуются навыки продвинутого пользователя. Необходимо разбираться в списках ACL Postgres Pro и конфигурации ldap2pg. Перед началом прочитайте разделы Управление правами и Справка по файлу ldap2pg.yml, убедитесь, что вы хорошо понимаете документацию по ACL Postgres Pro и что права успешно синхронизированы с ldap2pg.

Определите пользовательский ACL в YAML-файле конфигурации.

Вариант использования #

Предположим, в вашей базе данных есть пользовательский тип enum myenum.

CREATE TYPE public.myenum AS ENUM ('toto', 'titi', 'tata');

Нам нужно получить доступ к управлению правами для этого объекта, в конечном итоге для других типов, через пользовательский ACL.

Определение имени #

Назовите ваш ACL по ключевому слову в операторе GRANT или REVOKE. Из GRANT USAGE ON TYPE mytype TO myrole определите имя для TYPE вашего ACL.

acls:
  TYPE:
    ...

Область действия #

Postgres Pro определяет типы пользователей в рамках схемы. Поскольку схема будет чётко задана, ограничим действие ACL базой данных.

acls:
  TYPE:
    scope: database

Предоставление и отзыв прав #

Написать операторы GRANT и REVOKE легче всего. За подробностями о формате запроса обратитесь к описанию предоставления прав. Используем поле object в параметре grant, чтобы поместить туда имя типа. Схема public жёстко задана, о чём было сказано выше.

acls:
  TYPE:
    scope: database
    grant: GRANT <privilege> ON TYPE public.<object> TO <grantee>;
    revoke: REVOKE <privilege> ON TYPE public.<object> FROM <grantee>;

Проверка #

Запрос на проверку — это самая сложная часть. Нужно уметь работать со встроенным системным типом Postgres Pro aclitem и встроенными системными функциями aclexplode и acldefault. Сигнатура запроса на проверку зависит от области действия ACL.

Для области действия instance:

  • type: строка, описывающая тип права как ключевое слово SQL.

  • object: строка, описывающая имя объекта как SQL-идентификатор.

  • grantee: строка, описывающая имя роли как SQL-идентификатор.

Для области действия database:

  • type: строка, описывающая тип права как ключевое слово SQL.

  • object: строка, описывающая имя объекта как SQL-идентификатор.

  • grantee: строка, описывающая имя роли как SQL-идентификатор.

  • partial: логическое значение, указывающее, является ли предоставление права частичным.

Параметр partial указывает ldap2pg, что нужно снова предоставить права ALL ... IN SCHEMA. Поскольку наш ACL обрабатывает объекты по одному, значение partial всегда будет false.

ldap2pg отправляет один параметр в запросе на проверку — актуальный список типов прав, управляемых конфигурацией. Список представляет собой массив текста. Ожидается, что в результате запроса права, не включённые в список, не попадут в выборку.

Для списка ACL TYPE проверим права для доступа к системному каталогу pg_type.

acls:
  TYPE:
    scope: database
    grant: GRANT <privilege> ON <acl> public.<object> TO <grantee>;
    revoke: REVOKE <privilege> ON <acl> public.<object> FROM <grantee>;
    inspect: |
      WITH grants AS (
        SELECT typname,
               (aclexplode(COALESCE(typacl, acldefault('T', typowner)))).privilege_type AS priv,
               (aclexplode(COALESCE(typacl, acldefault('T', typowner)))).grantee::regrole::text AS grantee
          FROM pg_catalog.pg_type
        WHERE typnamespace::regnamespace = 'public'::regnamespace
          AND typtype <> 'b'  -- exclude base type.
      )
      SELECT grants.priv AS "privilege",
            grants.typname AS "object",
            CASE grants.grantee WHEN '-' THEN 'public' ELSE grants.grantee END AS grantee,
            FALSE AS partial
        FROM grants
      WHERE "priv" = ANY ($1)
      ORDER BY 2, 3, 1
      ;

Видно, что это не простой запрос. Он поддерживается в версии Postgres Pro 17.

Использование #

Теперь можно переходить к использованию вашего пользовательского ACL в профиле. Ссылайтесь на объект в профиле, а не в правиле предоставлении права.

privileges:
  custom:
  - type: USAGE
    on: TYPE
    object: myenum

rules:
- roles:
    names:
    - alice
  grant:
    privilege: custom
    role: alice

В профиле необходимо дать ссылку на все типы вручную. При запуске ldap2pg изменения должны быть внесены в вашу базу данных:

$ ldap2pg
...
16:52:02 CHANGE Would Revoke privileges.                         grant="USAGE ON TYPE myenum TO public" database=db0
16:52:02 CHANGE Would Grant privileges.                          grant="USAGE ON TYPE myenum TO alice" database=db0
16:52:02 INFO   Comparison complete.                             searches=0 roles=1 queries=5 grants=1
16:52:02 INFO   Use --real option to apply changes.
16:52:02 INFO   Done.                                            elapsed=44.345229ms mempeak=1.6MiB ldap=0s inspect=28.992071ms sync=0s

На этом всё.

Отладка #

Если возникла проблема, изолируйте её. Ограничьте конфигурацию вашим пользовательским ACL. Синхронизируйте единственную роль, предоставьте ей права. Не используйте поисковые запросы LDAP, используйте только статические правила. Синхронизируйте единственную базу данных. Включите вывод отладочных сообщений с помощью параметра --verbose.

ldap2pg просматривает по очереди базы данных, затем списки ACL. Для каждого ACL выводится следующее сообщение:

В первой строке с информацией о вашем ACL присутствует атрибут записей acl=TYPE.

    17:13:35 DEBUG  Inspecting grants.                               acl=TYPE scope=database database=db0
    

Затем идут сообщения для проверки: запрос и аргументы. Для каждого предоставленного права появляется сообщение Found grant (найденное предоставленное право)..

17:13:35 DEBUG  Executing SQL query:
WITH grants AS (
...
WHERE "priv" = ANY ($1)
ORDER BY 2, 3, 1
;
 arg=[USAGE]
17:13:35 DEBUG  Found grant in Postgres instance.                grant="USAGE ON TYPE myenum TO public" database=db0

После этого ldap2pg расширяет предоставленные права, сгенерированные правилом. Для каждого сгенерированного предоставленного права выводится сообщение Wants grant (требуется предоставить право )..

17:13:35 DEBUG  Wants grant.                                     grant="USAGE ON TYPE myenum TO alice" database=db0

В конце ldap2pg выводит изменения, которые будут применены.

17:13:35 CHANGE Would Revoke privileges.                         grant="USAGE ON TYPE myenum TO public" database=db0
17:13:35 DEBUG  Would Execute SQL query:
REVOKE USAGE ON TYPE public."myenum" FROM "public";
17:13:35 CHANGE Would Grant privileges.                          grant="USAGE ON TYPE myenum TO alice" database=db0
17:13:35 DEBUG  Would Execute SQL query:
GRANT USAGE ON TYPE public."myenum" TO "alice";

По завершении операции ldap2pg выводит сообщении с заключением, даже если не требуется никаких изменений.

17:13:35 DEBUG  Privileges synchronized.                         acl=TYPE database=db0