15. Использование SASL

Клиенты и серверы OpenLDAP способны производить аутентификацию с использованием системы Simple Authentication and Security Layer (SASL), описанной в RFC4422 (рус.) (RFC4422 (ориг.)). В данном разделе рассказано о том, как использовать SASL в OpenLDAP.

Существует несколько механизмов аутентификации, являющихся промышленными стандартами, которые могут быть использованы с SASL, в том числе GSSAPI для Kerberos V, DIGEST-MD5, а также PLAIN и EXTERNAL, которые используются с Transport Layer Security (TLS).

Стандартные клиентские утилиты, поставляемые с OpenLDAP, такие как ldapsearch(1) и ldapmodify(1), по умолчанию будут пытаться аутентифицировать пользователя на сервере службы каталогов LDAP, используя SASL. С помощью ряда несложных действий администраторы LDAP могут настроить сервис простой аутентификации SASL, чтобы позволить пользователям аутентифицироваться на сервере slapd от имени своей записи LDAP. С помощь нескольких дополнительных действий можно разрешить некоторым пользователям и службам использовать функцию прокси-авторизации SASL, что позволит им, после прохождения аутентификации, переключаться со своей идентификационной сущности на идентификационную сущность другого пользователя или службы.

В этом разделе предполагается, что Вы прочли руководство Cyrus SASL для системных администраторов, распространяемое с пакетом Cyrus SASLdoc/sysadmin.html), и у Вас есть рабочая инсталляция Cyrus SASL. Вам следует протестировать Вашу инсталляцию SASL с помощью Cyrus SASL sample_client и sample_server перед тем, как Вы будете использовать её совместно с программным обеспечением OpenLDAP.

Обратите внимание, что в последующем тексте термин пользователь применяется для описания человека или сущности приложения, которые подключаются к серверу LDAP с помощью клиента LDAP, такого, как ldapsearch(1). Поэтому термин пользователь относится не только к человеку, использующему LDAP-клиент, но и к приложению, которое выполняет операции клиента LDAP без прямого контроля человека. Например, сущностью приложения является почтовый сервер, использующий операции LDAP для доступа к информации, содержащейся на сервере LDAP.


15.1. Вопросы безопасности при использовании SASL

SASL предлагает множество различных механизмов аутентификации. В этом подразделе кратко излагаются вопросы безопасности.

Некоторые механизмы, такие как PLAIN и LOGIN, предлагают уровень безопасности не выше, чем простая (simple) аутентификация LDAP. Как и простая аутентификация LDAP, такие механизмы не должны использоваться без принятия других адекватных мер защиты. Рекомендуется использовать эти механизмы только вместе с Transport Layer Security (TLS). Применение механизмов PLAIN и LOGIN далее в этом документе не обсуждается.

Механизм DIGEST-MD5 является обязательным механизмом аутентификации для реализации LDAPv3. Хотя DIGEST-MD5 не является механизмом строгой аутентификации по сравнению с доверенными системами аутентификации третьих сторон (такими как Kerberos или системы открытых ключей), он предлагает значительную защиту от некоторых атак. В отличие от механизма CRAM-MD5, он предотвращает chosen plaintext attacks (атаки по избранному простому тексту). DIGEST-MD5 предпочтительнее, чем использование простых парольных механизмов. Механизм CRAM-MD5 считается устаревшим в пользу DIGEST-MD5. Применение DIGEST-MD5 обсуждается ниже.

Механизм GSSAPI использует GSS-API Kerberos V для обеспечения сервисов безопасной аутентификации. Механизм KERBEROS_V4 делает то же самое, используя Kerberos IV. Kerberos рассматривается как безопасная распределенная система аутентификации, подходящая как для малых, так и для крупных предприятий. Применение GSSAPI и KERBEROS_V4 обсуждается ниже.

Механизм EXTERNAL использует сервисы аутентификации, предоставляемые низкоуровневыми сетевыми службами, такими как Transport Layer Security (TLS). При использовании совместно с основанной на X.509 технологией открытых ключей TLS, механизм EXTERNAL предлагает строгую аутентификацию. TLS обсуждается в разделе Использование TLS.

Механизм EXTERNAL также может быть использован с транспортом ldapi:///, поскольку Unix-сокеты могут сообщать UID и GID клиентского процесса.

Можно выбрать и другие механизмы строгой аутентификации, в том числе OTP (one time passwords, одноразовые пароли) и SRP (secure remote passwords, безопасные удалённые пароли). Эти механизмы не обсуждаются в данном документе.


15.2. Аутентификация с помощью SASL

Чтобы простая аутентификация с помощью SASL заработала, нужно выполнить несколько шагов. На первом шаге настраивается окружение Вашего сервера slapd так, чтобы он мог взаимодействовать с клиентскими программами, используя систему безопасности, развёрнутую на Вашем сайте. Как правило, это предполагает создание сервисного ключа, открытого ключа или других форм создания зашифрованных соединений. На втором шаге настраивается отображение аутентификационных идентификационных сущностей в DN LDAP, это зависит от структуры размещения записей в Вашем каталоге. Объяснение первого шага дано в последующем подразделе на примере механизма Kerberos V4. Действия, требуемые для настройки аутентификационного механизма, используемого в Вашей системе, будут подобны приведённым в примере, однако руководство по каждому механизму, доступному с SASL, выходит за рамки данного раздела. Второй шаг описан в подразделе Отображение аутентификационных идентификационных сущностей.

15.2.1. GSSAPI

В этом подразделе описано использование механизма GSSAPI SASL и Kerberos V совместно с OpenLDAP. Предполагается, что у Вас уже развёрнут Kerberos V, Вы знакомы с работой этой системы, и что Ваши пользователи умеют ею пользоваться. Также предполагается, что Вы ознакомились с использованием механизма GSSAPI, прочитав Configuring GSSAPI and Cyrus SASL (поставляется с Cyrus SASL в файле doc/gssapi), и провели успешные эксперименты с предоставляемыми Cyrus приложениями sample_server и sample_client. Основную информацию по Kerberos можно найти на сайте http://web.mit.edu/kerberos/www/.

Для использования механизма GSSAPI совместно с slapd(8) сначала нужно создать сервисный ключ с принципалом (principal) для сервиса ldap в области (realm) для хоста, на котором запущена служба каталога. Например, если Ваш slapd запущен на directory.example.com и Ваш realm - EXAMPLE.COM, Вам нужно создать сервисный ключ с таким принципалом:

        ldap/directory.example.com@EXAMPLE.COM

При запуске slapd(8) он должен иметь доступ к этому ключу. Обычно это достигается путём помещения ключа в файл keytab, /etc/krb5.keytab. Информацию о настройках местоположения файла keytab можно получить в документации по Kerberos и Cyrus SASL.

Чтобы использовать механизм GSSAPI для аутентификации при подключении к службе каталогов, пользователь получает "разрешение на получение разрешения" (Ticket Granting Ticket, TGT) перед тем, как запустить клиент LDAP. При использовании клиентских утилит OpenLDAP, пользователь может явно указать использование механизма GSSAPI, передав параметр командной строки -Y GSSAPI.

В целях аутентификации и авторизации, slapd(8) ассоциирует DN запроса аутентификации в форме:

        uid=<primary[/instance]>,cn=<realm>,cn=gssapi,cn=auth

Продолжая наш пример, пользователь с принципалом Kerberos kurt@EXAMPLE.COM будет иметь ассоциированный DN:

        uid=kurt,cn=example.com,cn=gssapi,cn=auth

а принципал ursula/admin@FOREIGN.REALM будет иметь ассоциированный DN:

        uid=ursula/admin,cn=foreign.realm,cn=gssapi,cn=auth

Поскольку DN запроса аутентификации имеет правильный формат LDAP DN, он может быть непосредственно использован в ACL и атрибутах "member" записей с объектным классом groupOfNames. Или же, DN запроса аутентификации перед использованием может быть отображено в какое-нибудь другое DN. Подробности смотрите в подразделе Отображение аутентификационных идентификационных сущностей.

15.2.2. KERBEROS_V4

В этом подразделе описано использование механизма KERBEROS_V4 SASL совместно с OpenLDAP. Предполагается, что Вы знакомы с работой системы безопасности Kerberos IV и что у Вас уже развёрнут Kerberos IV. Ваши пользователи должны быть знакомы с политикой аутентификации, а также с тем, как получить учётные данные в кэше разрешений (ticket cache) Kerberos, и как обновить учётные данные, срок действия которых истёк.


Примечание: KERBEROS_V4 и Kerberos IV считаются устаревшими в пользу GSSAPI и Kerberos V.

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

Сервер slapd запускает сервис под названием "ldap", и серверу требуется файл srvtab, содержащий сервисный ключ. Клиенты, которые осведомлены, что им нужно использовать SASL, получают разрешение (ticket) сервиса "ldap" с пользовательским "разрешением на получение разрешения" (TGT), в котором экземпляр разрешения совпадает с именем хоста сервера OpenLDAP. Например, если Ваш realm называется EXAMPLE.COM и сервер slapd запущен на хосте directory.example.com, файл /etc/srvtab на сервере будет содержать сервисный ключ

        ldap.directory@EXAMPLE.COM

Когда клиент LDAP аутентифицирует пользователя при подключении к службе каталогов с использованием механизма KERBEROS_IV, он будет запрашивать ключ сессии для принципала, ассоциированного с этим пользователем, либо из кэша разрешений, либо получая новый от сервера Kerberos. Для этого требуется, чтобы в кэше было доступно правильное TGT. Если его там нет или срок его действия истёк, клиент может вывести следующее сообщение:

        ldap_sasl_interactive_bind_s: Local error

Когда сервисное разрешение получено, оно будет передано серверу LDAP в качестве подтверждения идентификационной сущности пользователя. Сервер, с помощью библиотечных функций SASL, извлечёт из сервисного разрешения идентификационную сущность и realm и конвертирует их в DN запроса аутентификации в форме

        uid=<имя пользователя>,cn=<realm>,cn=<механизм>,cn=auth

Таким образом, в приведённом выше примере, если имя пользователя было "adamson", DN запроса аутентификации будет:

        uid=adamsom,cn=example.com,cn=kerberos_v4,cn=auth

Этот DN запроса аутентификации может быть непосредственно использован в ACL, или же, перед использованием, может быть отображен в какой-нибудь другой. Подробности смотрите в подразделе Отображение аутентификационных идентификационных сущностей.

15.2.3. DIGEST-MD5

В этом подразделе описано использование механизма DIGEST-MD5 SASL, использующего секретные последовательности, хранящиеся либо в самом каталоге, либо в собственной базе данных Cyrus SASL. DIGEST-MD5 строит работу на "секретной последовательности" (как правило, пароле), известной и клиенту, и серверу. Сервер генерирует запрос, знает ли клиент секретную последовательность, и клиент отвечает, доказывая, что эта общая секретная последовательность ему известна. Это гораздо более безопасно, чем просто отправлять пароль по сети.

Cyrus SASL поддерживает несколько механизмов с общими секретными последовательностями. Для этого ему необходим доступ к паролю в открытом виде (в отличие от механизмов, пересылающих пароли в открытом виде по сети, где сервер может хранить захэшированную версию пароля).

Копия общих паролей, которой пользуется сервер, может храниться в собственной базе данных Cyrus SASL sasldb, во внешней системе, доступной через saslauthd, либо в самой базе данных LDAP. В любом случае, очень важно применять контроль доступа к файлам и контроль доступа к LDAP для предотвращения раскрытия паролей. Конфигурация и команды, обсуждаемые в этом подразделе, предполагают использование Cyrus SASL 2.1.

Чтобы использовать секретные последовательности, хранимые в sasldb, просто добавьте пользователей командой saslpasswd2:

       saslpasswd2 -c <имя пользователя>

Управление паролями таких пользователей должно осуществляться с помощью команды saslpasswd2.

Чтобы использовать секретные последовательности, хранимые в каталоге LDAP, поместите пароли в открытом виде в атрибут userPassword. Чтобы убедиться, что пароли, устанавливаемые с помощью операции изменения пароля LDAP (LDAP Password Modify Operation) сохраняются в открытом виде, необходимо добавить в slapd.conf опцию:

       password-hash   {CLEARTEXT}

Управление паролями, хранимыми таким способом, может осуществляться либо с помощью утилиты ldappasswd(1), либо просто изменением атрибута userPassword. Независимо от того, где хранятся пароли, требуется отображение DN запроса аутентификации в DN пользователя.

Механизм DIGEST-MD5 создаёт аутентификационные идентификаторы в форме:

        uid=<имя пользователя>,cn=<realm>,cn=digest-md5,cn=auth

Если используется realm по умолчанию, то в идентификаторе имя realm опускается, и получается:

        uid=<имя пользователя>,cn=digest-md5,cn=auth

Информацию о дополнительном отображении идентификационных сущностей смотрите ниже в подразделе Отображение аутентификационных идентификационных сущностей.

Если подходящее отображение настроено, пользователи могут указывать идентификаторы SASL при выполнении операций LDAP, и для проверки подлинности будут использованы пароли, хранящиеся в sasldb или непосредственно в каталоге. Например, пользователь, идентифицируемый записью каталога:

       dn: cn=Andrew Findlay+uid=u000997,dc=example,dc=com
       objectclass: inetOrgPerson
       objectclass: person
       sn: Findlay
       uid: u000997
       userPassword: secret

может выполнять команды в такой форме:

       ldapsearch -Y DIGEST-MD5 -U u000997 ...


Примечание: в каждом из приведённых выше случаев не было предоставлено авторизационной идентификационной сущности (например, с помощью -X). Если вы не пытались использовать проки-авторизацию SASL, то авторизационная идентификационная сущность опять же не будет определена. Сервер будет вычислять авторизационную идентификационную сущность на основании аутентификационной идентификационной сущности (как описано ниже).

15.2.4. EXTERNAL

Механизм EXTERNAL SASL позволяет использовать аутентификацию, уже выполненную протоколом низкого уровня, как правило TLS или Unix IPC.

Каждый транспортный протокол возвращает аутентификационные идентификационные сущности в своём собственном формате.

15.2.4.1. Формат аутентификационной идентификационной сущности TLS

Это DN Субъекта из клиентского сертификата. Обратите внимание, что DN в LDAP и X.509 отображаются по разному, поэтому сертификат, выданный

        C=gb, O=The Example Organisation, CN=A Person

будет создавать аутентификационную идентификационную сущность:

        cn=A Person,o=The Example Organisation,c=gb

Также обратите внимание, что Вы должны установить подходящее значение параметра TLSVerifyClient, чтобы сервер запрашивал использование клиентского сертификата. Если этого не сделать, сервер не будет пытаться использовать механизм EXTERNAL SASL. Подробности смотрите в подразделе Использование TLS.

15.2.4.2. Формат идентификационной сущности IPC (ldapi:///)

Он формируется из Unix UID и GID клиентского процесса:

        gidNumber=<номер>+uidNumber=<номер>,cn=peercred,cn=external,cn=auth

Таким образом, идентификационная сущность клиентского процесса, запущенного от root, будет:

        gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth

15.2.5. Отображение аутентификационных идентификационных сущностей

Механизм проверки подлинности на сервере slapd будет использовать библиотечные вызовы SASL для получения "имени пользователя" аутентифицированного пользователя, основываясь на том, какой механизм аутентификации применялся. Это имя пользователя располагается в пространстве имён механизма аутентификации, а не в нормальном пространстве имён LDAP. Как показано в предыдущих подразделах, такие имена пользователей включены в DN запроса аутентификации, который имеет следующую форму:

        uid=<имя пользователя>,cn=<realm>,cn=<механизм>,cn=auth

или

        uid=<имя пользователя>,cn=<механизм>,cn=auth

в зависимости от того, применяется ли в <механизме> концепция "realm". Также обратите внимание, что часть <realm> будет опущена в случае применения при аутентификации realm по умолчанию.

Чтобы определить идентификационную сущность, ассоциированную с пользователем, можно использовать утилиту ldapwhoami(1). Она очень полезна и при проверке правильности работы функции отображения.

В общем случае не подразумевается, что Вы будете заполнять свою базу данных LDAP записями LDAP в приведённой выше форме. Скорее всего, в Вашем дереве каталога будут записи LDAP для каждого человека, которому нужно проходить аутентификацию при подключении к серверу LDAP, и это дерево не будет начинаться с cn=auth. Однако, если в Вашей системе поддерживается чёткое соответствие между "именем пользователя" и записью LDAP для человека, можно будет настроить сервер LDAP так, чтобы он автоматически отображал DN запроса аутентификации в аутентификационный DN пользователя.


Примечание: не выдвигается требований, чтобы DN запроса аутентификации или аутентификационный DN пользователя, полученный в результате отображения, ссылались на запись, содержащуюся в каталоге. Однако в этом случае становятся доступными дополнительные возможности (смотрите ниже).

Администратор LDAP должен настроить сервер slapd так, чтобы тот знал, как отображать DN запроса аутентификации в аутентификационный DN пользователя. Это делается добавлением одной или более директив authz-regexp в файл slapd.conf(5). Эта директива принимает два аргумента:

        authz-regexp   <шаблон поиска>   <шаблон замены>

DN запроса аутентификации сравнивается с шаблоном поиска с помощью функций регулярных выражений regcomp() и regexec(), и если совпадение найдено, он переписывается согласно шаблону замены. Если присутствует несколько директив authz-regexp, используется только та из них, у которой первым найдено совпадение шаблона поиска с аутентификационной идентификационной сущностью. Строка, образованная после применения шаблона замены, должна быть либо аутентификационным DN пользователя, либо LDAP URL. Если полученная после замены строка означает DN, запись, именем которой служит этот DN, не обязательно должна содержаться на этом сервере. Если полученная после замены строка означает LDAP URL, то этот LDAP URL должен соответствовать одной и только одной записи, содержащейся на этом сервере.

Шаблон поиска может содержать любой из символов, применяемых в регулярных выражениях, которые перечислены в regexec(3C). Основные из этих символов - точка ".", звёздочка "*", открывающиеся и закрывающиеся круглые скобки "(" и ")". Если коротко, точка соответствует любому символу, звездочка говорит о возможности нуля или более повторов непосредственно предшествующего ей символа, а совпадения с выражениями в скобках запоминаются для использования в шаблоне замены.

В результате применения шаблона замены создаётся либо DN, либо URL, указывающий на пользователя. Любая часть DN запроса аутентификации, совпавшая с выражением в скобках в шаблоне поиска, хранится в переменной "$1". Эта переменная "$1" может быть указана в шаблоне замены, и будет заменена на совпавшую строку из DN запроса аутентификации. Если в шаблоне поиска было указано несколько выражений в скобках, то совпадения с ними доступны в переменных $2, $3, и так далее.

15.2.6. Прямое отображение

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

Предположим, DN запроса аутентификации представлен в виде:

        uid=adamson,cn=example.com,cn=gssapi,cn=auth

, а актуальная запись LDAP пользователя:

        uid=adamson,ou=people,dc=example,dc=com

В этом случае прямое отображение будет выполняться следующей директивой authz-regexp в slapd.conf(5):

        authz-regexp
          uid=([^,]*),cn=example.com,cn=gssapi,cn=auth
          uid=$1,ou=people,dc=example,dc=com

Можно указать даже более общие правила:

        authz-regexp
          uid=([^,]*),cn=[^,]*,cn=auth
          uid=$1,ou=people,dc=example,dc=com

Однако будьте внимательны, настраивая слишком общие поисковые шаблоны. Это может привести к тому, что человек будет ошибочно аутентифицирован как DN, к которому у него не должно быть доступа. Лучше уж написать несколько конкретных директив, чем одну общую директиву, открывающую бреши в системе безопасности. Если в Вашей системе используется только один механизм аутентификации и один realm (или его вообще нет), то можно написать всего одну директиву authz-regexp, которая позволит Вам отображать аутентификационные идентификационные сущности в LDAP DN.

Не забудьте учесть случай, когда realm пропущен, также, как и случай, когда realm указан явно. Это может потребовать написания отдельных директив authz-regexp для каждого случая, причём директива с явным указанием realm должна следовать первой.

15.2.7. Отображения, основанные на поиске

В ряде случаев целесообразно использовать отображение в LDAP URL. Например, в некоторых каталогах объекты, описывающие людей, могут располагаться в нескольких областях дерева LDAP, к примеру, в поддеревьях ou=accounting и ou=engineering, причём RDN записей в них могут пересекаться между собой. Либо искомое отображение должно основываться не на DN, а на информации, содержащейся в самой записи пользователя. Рассмотрим случай, когда необходимо отобразить DN запроса аутентификации на пользователя со следующей записью:

        dn: cn=Mark Adamson,ou=People,dc=Example,dc=COM
        objectclass: person
        cn: Mark Adamson
        uid: adamson

Информации, содержащейся в DN запроса аутентификации, недостаточно, чтобы напрямую получить отображение в DN пользователя, поэтому здесь требуется осуществить поиск DN пользователя. В подобных ситуациях как раз нужно использовать директивы authz-regexp, шаблон замены которых формирует LDAP URL. Этот URL затем будет использоваться для выполнения внутреннего поиска в базе данных LDAP, чтобы найти аутентификационный DN пользователя.

Как и другие URL, LDAP URL имеет вид

        ldap://<host>/<base>?<attrs>?<scope>?<filter>

Здесь содержатся все элементы, необходимые для выполнения поиска LDAP: <host> - имя хоста сервера, <base> - базовый LDAP DN для поиска, <attrs> - атрибуты LDAP, которые требуется получить, <scope> -диапазон поиска, имеет одно из трёх значений: "base", "one", и "sub", наконец, <filter> - поисковый фильтр LDAP. Поскольку поиск LDAP DN выполняется на текущем сервере, часть <host>можно оставить пустой. Поле <attrs> также игнорируется, так как нас интересует только DN. Эти два элемента были оставлены нами при описании формата URL, чтобы было понятно, какая информация располагается в каждой из частей строки URL.

Предположим, что человек из примера выше при проверке подлинности имеет фактическое имя пользователя "adamson", и что информация об этом содержится в атрибуте "uid" его записи LDAP. Тогда можно написать такую директиву authz-regexp:

        authz-regexp
          uid=([^,]*),cn=example.com,cn=gssapi,cn=auth
          ldap:///ou=people,dc=example,dc=com??one?(uid=$1)

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

Для ускорения поиска необходимо проиндексировать атрибуты, используемые в поисковом фильтре <filter> в URL. Если этого не было сделано, этап аутентификации может занять неприемлемо долгое время, и у пользователей сложится впечатление, что сервер недоступен.

Более комплексные системы могут использовать несколько realm, каждый из которых соответствует разным поддеревьям каталога. Данная ситуация может быть обработана с помощью определений следующего вида:

        # совпадение с realm Engineering
        authz-regexp
           uid=([^,]*),cn=engineering.example.com,cn=digest-md5,cn=auth
           ldap:///dc=eng,dc=example,dc=com??one?(&(uid=$1)(objectClass=person))

        # совпадение с realm Accounting
        authz-regexp
           uid=([^,].*),cn=accounting.example.com,cn=digest-md5,cn=auth
           ldap:///dc=accounting,dc=example,dc=com??one?(&(uid=$1)(objectClass=person))

        # realm по умолчанию - customers.example.com
        authz-regexp
           uid=([^,]*),cn=digest-md5,cn=auth
           ldap:///dc=customers,dc=example,dc=com??one?(&(uid=$1)(objectClass=person))

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

Учтите также, что на внутренний поиск authz-regexp распространяется действие контроля доступа. В частности, аутентификационные идентификационные сущности должны иметь уровень доступа auth.

Более подробную информацию смотрите в slapd.conf(5).


15.3. Прокси-авторизация SASL

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

Решение запретить или разрешить осуществление авторизации зависит от правил и политики системы, в которой функционирует LDAP, и оно не может быть принято одной только SASL. Библиотека SASL возлагает принятие такого решения на сервер. Администратор LDAP устанавливает руководящие принципы о том, кто может авторизоваться под какой идентификационной сущностью, добавляя информацию об этом в записи базы данных LDAP. Данная функция авторизации отключена по умолчанию и, перед использованием, должна быть явно настроена администратором LDAP.

15.3.1. Применение прокси-авторизации

Такой тип сервиса полезен, когда одной сущности необходимо выполнять действия от имени многих других пользователей. Например, пользователям может быть предоставлена web-страница для изменения своей персональной информации в записи LDAP. Для подтверждения своей идентификационной сущности такие пользователи проходят аутентификацию на web-сервере, но CGI-скрипт на web-сервере не может пройти аутентификацию на сервере LDAP по учётным данным того же самого пользователя, чтобы затем внести изменения в его запись. Вместо этого, web-сервер аутентифицирует себя на сервере LDAP как служебная идентификационная сущность, скажем,

        cn=WebUpdate,dc=example,dc=com

а затем с помощью SASL авторизуется как DN требуемого пользователя. Как только такая авторизация пройдена, CGI-скрипт вносит изменения в запись LDAP пользователя, поскольку сервер slapd сообщает своим ACL, что на том конце соединения находится именно этот пользователь. Конечно, пользователи могут напрямую подключаться к серверу LDAP и проходить аутентификацию самостоятельно, но это требует от них умения работать с клиентами LDAP, а с помощью web-страницы всё гораздо проще.

Прокси-авторизация также может применяться для ограничения доступа учётным записям, имеющим повышенные привилегии доступа к базе данных. Для такой учётной записи, возможно даже для root DN, определённого в slapd.conf(5), может быть создан ограниченный список людей, которые могут авторизоваться от имени этого DN. Можно разрешить вносить изменения в базу данных LDAP только этому DN, а чтобы стать таким DN, пользователю нужно сначала пройти аутентификацию под именем одного из тех, кто присутствует в этом списке. Это позволяет лучше контролировать, кто же конкретно вносил изменения в базу данных LDAP. Если же пользователям будет разрешено напрямую аутентифицироваться от имени привилегированной учётной записи с помощью пароля, полученного из директивы rootpw файла slapd.conf(5), либо из атрибута userPassword, то контроль изменений становится более затруднительным.

Обратите внимание, что после успешной прокси-авторизации, оригинальный аутентификационный DN соединения LDAP перезаписывается новым DN из запроса авторизации. Если служебная программа способна пройти аутентификацию от своего собственного аутентификационного DN, а затем авторизоваться от другого DN, то, если в течение одной сессии LDAP она планирует переключиться на какие-нибудь другие идентификационные сущности, то ей потребуется проходить повторную аутентификацию от своего имени каждый раз перед прохождением авторизации от имени другого DN (либо использовать другой механизм прокси-авторизации). Сервер slapd не учитывает способности служебной программы переключаться на другие DN. Поэтому, при использовании механизмов аутентификации типа Kerberos, прокси-авторизация не потребует установки нескольких соединений с сервером Kerberos, поскольку TGT пользователя, от которого устанавливает соединение служебная программа, и ключ сессии "ldap" действительны для многократных обращений в течение нескольких часов срока действия разрешения.

15.3.2. Авторизационные идентификационные сущности SASL

Авторизационная идентификационная сущность SASL посылается серверу LDAP через переключатель -X для ldapsearch(1) и других утилит, или с помощью параметра *authzid при вызовах lutil_sasl_defaults(). Идентификационная сущность может быть в одной из двух форм:

        u:<имя пользователя>

или

        dn:<dn>

В первой форме <имя пользователя> берётся из того же самого пространства имён, что и аутентификационные идентификационные сущности выше. Это то самое имя пользователя, на которое происходит ссылка при использовании какого-либо конкретного механизма аутентификации. Авторизационные идентификационные сущности переводятся в формат DN в помощью тех же самых функций, которые используются и в процессе аутентификации, в результате чего получается DN запроса авторизации в форме

        uid=<имя пользователя>,cn=<realm>,cn=<механизм>,cn=auth

Этот DN запроса авторизации затем пропускается через тот же самый процесс authz-regexp для преобразования в правильный авторизационный DN из базы данных. Если он не может быть преобразован вследствие неудачного завершения поиска по LDAP URL, запрос авторизации также завершается неудачей и выдаёт "inappropriate access" ("несанкционированный доступ"). В противном случае, строка DN становится правильным авторизационным DN, готовым пройти санкционирование.

Если авторизационная идентификационная сущность представлена во второй форме, с префиксом "dn:", строка после префикса уже находится в форме авторизационного DN и готова пройти санкционирование.

15.3.3. Правила прокси-авторизации

Когда slapd получает авторизационный DN, начинается сам процесс санкционирования. Для разрешения авторизации администратор LDAP может поместить в записи LDAP два атрибута:

        authzTo
        authzFrom

Оба они могут иметь несколько значений. Атрибут authzTo - это правило источника, он помещается в запись, ассоциируемую с аутентификационным DN, чтобы указать, какие авторизационные DN может принять на себя этот аутентификационный DN. Второй атрибут - это правило назначения, он помещается в запись, ассоциируемую с запрашиваемым авторизационным DN, чтобы указать какие аутентификационные DN могут принимать его на себя.

Выбор, какой атрибут политики авторизации следует использовать, остаётся за системным администратором. Сначала проверяются правила источника в записи человека с аутентификационным DN, и, если там нет правила authzTo, указывающего на разрешение запрашиваемой авторизации, то проверяются правила authzFrom в записи с авторизационным DN. Если и в данном случае нет указаний на легальность данного запроса авторизации, запрос запрещается. Поскольку по умолчанию запросы авторизации запрещены, правилами определяется только возможность разрешить такой запрос; обратных правил, запрещающих выполнение авторизации, не существует.

Значение (или значения) этих двух атрибутов указываются в той же форме, что и строка, получаемая на выходе шаблона замены в директиве authz-regexp: либо DN, либо LDAP URL. Например, если значение authzTo - это DN, то под этим DN может авторизоваться пользователь, прошедший аутентификацию. С другой стороны, если значение authzTo - это LDAP URL, данный URL используется для внутреннего поиска в базе данных LDAP, и аутентифицированный пользователь может стать ЛЮБЫМ ИЗ DN, которые будут возвращены в результате поиска. Если запись LDAP выглядит так:

        dn: cn=WebUpdate,dc=example,dc=com
        authzTo: ldap:///dc=example,dc=com??sub?(objectclass=person)

то любой пользователь, прошедший аутентификацию как cn=WebUpdate,dc=example,dc=com, может авторизоваться от имени любой другой записи LDAP в поддереве dc=example,dc=com, которая имеет объектный класс person.

15.3.3.1. Замечания по правилам прокси-авторизации

LDAP URL в атрибутах authzTo или authzFrom будут возвращать набор DN. Каждый возвращаемый DN будет подвергнут проверке. Если в результате поиска будет возвращаться большой набор DN, процесс авторизации может занять неприемлемо долгое время. Кроме того, необходимо проиндексировать атрибуты, по которым будет осуществляться поиск.

Для задания в authzFrom и authzTo более широких правил, разрешено использовать в значениях этих атрибутов DN, содержащие символы регулярных выражений. Это означает, что правило источника вида

        authzTo: dn.regex:^uid=[^,]*,dc=example,dc=com$

разрешит пользователям, прошедшим аутентификацию, авторизоваться от имени любого DN, который совпадёт с шаблоном указанного регулярного выражения. Подобные сравнения с регулярными выражениями могут выполняться значительно быстрее, чем поиски LDAP с фильтром (uid=*).

Также имейте ввиду, что значения в правилах авторизации должны быть в одной из двух форм: LDAP URL или DN (с символами регулярных выражений или без них). Любая строка, в начале которой нет "ldap://", воспринимается как DN. Нельзя использовать в качестве правила авторизации другую авторизационную идентификационную сущность в форме "u:<username>".

15.3.3.2. Настройка политики

Решение о том, правила какого типа, authzFrom или authzTo, нужно использовать, будет зависеть от ситуации, сложившейся в системе. Например, если список людей, которые могут авторизоваться под данной идентификационной сущностью, может быть легко описан одним поисковым фильтром, то можно написать одно правило назначения. Если такой список нельзя легко задать с помощью поискового фильтра, и этот список не велик, возможно лучше написать в каждой из записей тех людей, которым будет разрешено выполнять прокси-авторизацию, правило источника.

По умолчанию, обработка правил прокси-авторизации отключена. Для включения авторизации нужно установить в файле slapd.conf(5) директиву authz-policy. Эта директива может быть установлена в none - не обрабатывать правила (по умолчанию), to - для обработки правил источника, from - для обработки правил назначения, или both - для обработки обоих типов правил.

Правила источника являются чрезвычайно мощными. Если у обычных пользователей есть право изменять атрибут authzTo своих собственных записей, они могут написать правила, которые позволят им авторизоваться под кем бы то ни было. Поэтому, при использовании правил источника, необходимо защищать атрибут authzTo с помощью ACL, которые будут позволять изменять значения данного атрибута только привилегированным пользователям.