Введение
LDAP, или Lightweight Directory Access Protocol, является открытым протоколом, используемым для хранения и получения данных из каталога с иерархической структурой. Обычно используемый для хранения информации об организации, ее активах и пользователях, LDAP является гибким решением для определения любого типа сущностей и их свойств.
Для многих пользователей LDAP может показаться сложным для понимания, поскольку он опирается на своеобразную терминологию, имеет иногда необычные сокращения, и часто используется как компонент более крупной системы, состоящей из взаимодействующих частей. В этом тексте мы познакомим вас с некоторыми основами LDAP, чтобы у вас была хорошая основа для работы с технологией.
Что такое «служба каталогов»?
Служба каталогов используется для хранения, организации и представления данных в формате вида
Данные, хранящиеся в службе каталогов, часто носят описательный характер и используются для определения качеств сущности. Примером физического объекта, который был бы хорошо представлен в службе каталога, является адресная книга. Каждое лицо может быть представлено записью в справочнике, с парами
Что такое LDAP?
LDAP, или облегчённый протокол доступа к каталогам, является коммуникационным протоколом, который определяет методы, в которых служба каталога может быть доступна. Говоря более широко, LDAP формирует способ, которым данные внутри службы директории должны быть представлены пользователям, определяет требования к компонентам, используемым для создания записей данных внутри службы директории, и описывает способ, которым различные примитивные элементы используются для составления записей.
Поскольку LDAP является открытым протоколом, существует множество различных реализаций. Проект OpenLDAP является одним из наиболее хорошо поддерживаемых вариантов с открытым исходным кодом.
Основные компоненты данных LDAP
Выше мы обсуждали, как LDAP является протоколом, используемым для связи с базой данных директорий с целью запроса, добавления или изменения информации. Однако это простое определение искажает сложность систем, поддерживающих этот протокол. То, как LDAP отображает данные для пользователей, очень зависит от взаимодействия и отношений между некоторыми определенными структурными компонентами.
Атрибуты
Сама информация в
Установка значения для атрибута производится с помощью имени атрибута и значения атрибута, разделенного двоеточием и пробелом. Пример атрибута под названием mail
, который определяет почтовый адрес, будет выглядеть следующим образом:
email: admin@example.com
При обращении к атрибуту и его данным (когда он не задан), две стороны соединяются знаком равенства:
Значения атрибутов содержат большую часть фактических данных, которые вы хотите хранить, и к которым вы хотите получить доступ в системе LDAP. Остальные элементы внутри LDAP используются для определения структуры, организации
Записи
Атрибуты сами по себе не очень полезны. Чтобы иметь смысл, они должны быть связаны с
Например, вы можете иметь запись для пользователя в вашей системе, или для каждого предмета инвентаризации. Это примерно аналогично строке в системе реляционной базы данных, или одной странице в адресной книге (атрибуты здесь будут представлять различные поля в каждой из этих моделей). В то время как атрибут определяет качество или характеристику
Пример записи, отображаемой в LDIF (LDAP Data Interchange Format), будет выглядеть примерно так:
dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
objectclass: person
sn: Ellingwood
cn: Justin Ellingwood
Приведенный выше пример может быть валидной записью в системе LDAP.
DIT
Начав знакомиться с LDAP, легко понять, что данные, определяемые атрибутами, представляют собой лишь часть доступной информации об объекте. Остальное — это расположение записи в системе LDAP и связи, проистекающие из этого.
Например, если можно иметь записи как для пользователя, так и для объекта инвентаризации, как
DIT представляет собой организационную структуру, похожую на файловую систему, где каждая запись (кроме записи верхнего уровня) имеет ровно одну родительскую запись и под ней может находиться любое количество дочерних записей. Поскольку записи в
Таким образом, у вас может быть запись для «people» и запись для «inventoryItems». Ваши фактические записи данных могут быть созданы как дочерние записи приведенных выше, чтобы лучше различать их тип. Ваши организационные записи могут быть произвольно определены, чтобы наилучшим образом представить ваши данные.
В примере записи в разделе выше мы видим одно указание на DIT, в строке dn
:
Эта строка называется distinguished name («dn», «отличительное имя») записи (подробнее об этом позже) и используется для идентификации записи. Она функционирует как полный путь до «корня» DIT. В данном случае у нас есть запись под названием sn=Ellingwood
, которую мы создаем. Прямым родителем является запись с именем ou=people
, которая, вероятно, используется в качестве контейнера для записей, описывающих людей. Родители этой записи произошли от доменного имени digitalocean.com
, которое выступает как корень нашей DIT.
Определение компонентов данных LDAP
В последнем разделе мы обсудили, как представлены данные в системе LDAP. Однако мы также должны поговорить о том, как определяются компоненты, которые хранят данные. Например, мы упомянули, что данные должны соответствовать типу, определённому для каждого атрибута. Откуда берутся эти определения? Давайте начнем с самого низа (с точки зрения сложности), и пройдём весь путь вверх.
Определения атрибутов
Атрибуты определяются с использованием достаточно сложного синтаксиса. Они должны указывать имя атрибута, любые другие имена/названия, которые могут быть использованы для ссылки на атрибут, тип данных, а также множество других метаданных. Эти метаданные могут описывать атрибут, указывая LDAP, как сортировать или сравнивать значение атрибута, и пояснять, как он соотносится с другими атрибутами.
Например, это определение для атрибута name
:
attributetype (<nobr>2.5.4.41</nobr> NAME 'name' DESC 'RFC4519: common supertype of name attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX <nobr>1.3.6.1</nobr>.4.1.1<nobr>466.115.121.1</nobr>.15{32768})
name
— это имя атрибута. Номер в первой строке — это глобально уникальный OID (object id, идентификатор объекта), присвоенный атрибуту, чтобы отличить его от всех остальных атрибутов. Остальная часть записи определяет, как можно сравнить запись во время поиска, и имеет указатель, поясняющий, где найти информацию по требуемому типу данных атрибута.
Одной из важных частей определения атрибута является то, может ли атрибут быть задан в записи более одного раза. Например, в определении может быть определено, что фамилия может быть определена в записи только один раз, но атрибут «niece» позволительно указывать несколько раз в одной записи. Атрибуты по умолчанию многозначны и должны содержать флаг <nobr>SINGLE-VALUE</nobr>
, если их можно задавать в записи только один раз.
Определения атрибутов намного сложнее, чем использование и установка атрибутов. К счастью, в большинстве случаев Вам не придётся определять собственные атрибуты, так как наиболее распространённые из них включены в большинство реализаций LDAP, а другие легко импортируются.
Определения классов объектов
Атрибуты собираются в сущностях, называемых ObjectClass (классы объектов). ObjectClasses — это просто группировка связанных атрибутов, которая была бы полезна при описании конкретной вещи. Например, «person» — это objectClass.
Записи имеют возможность использовать атрибуты objectClass путем задания специального атрибут с названием objectClass
, задающий objectClass, который вы хотите использовать. На самом деле, objectClass
— это единственный атрибут, который можно задать в записи, не указывая более objectClass.
Таким образом, если Вы создаете запись для описания человека, то objectClass person
(или любой из более специфических объектов objectClasses, производных от person — об этом мы поговорим позже) позволяет использовать все атрибуты внутри этого objectClass:
dn: . . .
objectClass: person
После этого у вас появляется возможность установить внутри записи следующие аттрибуты:
— cn: Общее имя (Common name)
— description: Понятное человеку описание записи
— seeAlso: Ссылка на связанные записи
— sn: Фамилия (Surename)
— telephoneNumber: Номер телефона
— userPassword: Пароль пользователя
Атрибут objectClass
может использоваться несколько раз, если вам нужны атрибуты из разных классов объектов, но есть правила, которые диктуют, что разрешено. ObjectClasses может быть нескольких «типов».
Два основных типа ObjectClasses — это структурный (structural) и дополнительный (auxiliary). Запись должна должна иметь ровно один структурный класс, но может иметь ноль или более вспомогательных классов, используемых для дополнения списка атрибутов, доступных этому классу. Структурный ObjectClasses используется для создания и определения записи, а вспомогательные
Определения ObjectClass определяют, являются ли предоставляемые атрибуты обязательными (обозначаются спецификацией MUST
) или необязательными (обозначаются спецификацией MAY
). Несколько ObjectClasses могут предоставлять одни и те же атрибуты, а категоризация атрибута MAY
или MUST
может варьироваться от
В качестве примера, объект Класс person
определяется так:
objectclass (<nobr>2.5.6.6</nobr> NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST (sn $ cn) MAY (userPassword $ telephoneNumber $ seeAlso $ description))
Это определяется как структурный объектClass, что означает, что он может быть использован для создания записи. Созданная запись должна содержать заданными атрибуты surname
и commonname
, и может, при желании, содержать аттрибуты userPassword
, telephoneNumber
, seeAlso
, или description
.
Схемы
Определения ObjectClass и определения атрибутов, в свою очередь, сгруппированы в конструкции, известной как schema (схема). В отличие от традиционных реляционных баз данных, схемы в LDAP представляют собой просто наборы взаимосвязанных ObjectClasses и атрибутов. Один DIT может иметь много различных схем, так что он может создавать нужные ему записи и атрибуты.
Схемы часто включают дополнительные определения атрибутов и могут требовать атрибутов, определенных в других схемах. Например, объектный класс person
, о котором мы говорили выше, требует, чтобы атрибут surname
или sn
был установлен для любых записей, использующих объектный класс person
. Если они не определены в самом
Формат схемы, по сути, является просто комбинацией вышеперечисленных записей, например:
. . .
objectclass (<nobr>2.5.6.6</nobr> NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL MUST (sn $ cn) MAY (userPassword $ telephoneNumber $ seeAlso $ description))
attributetype (<nobr>2.5.4.4</nobr> NAME ('sn' 'surname') DESC 'RFC2256: last (family) name(s) for which the entity is known by' SUP name)
attributetype (<nobr>2.5.4.4</nobr> NAME ('cn' 'commonName') DESC 'RFC4519: common name(s) for which the entity is known by' SUP name)
. . .
Организация данных
Мы рассмотрели общие элементы, которые используются для построения записей в LDAP системе и поговорили о том, как эти «строительные блоки» определяются в системе. Однако мы еще не много говорили о том, как организована и структурирована сама информация в LDAP DIT.
Размещение записей в DIT
DIT — это просто иерархия, описывающая взаимосвязь существующих записей. После создания, каждая новая запись должна «подключаться» к существующему DIT, помещая себя в качестве дочерней по отношению к
Верхний DIT — это самая широкая категория, под которой каждый последующий узел является dc=example,dc=com
для управляющей информации LDAP, связанной с example.com
), местоположений (l=new_york,c=us
для организации или сегмента в ou=marketing,o=Example_Co
).
Записи, используемые для организации (используемые как папки) часто используют объектный класс organizationalUnit
, что позволяет использовать простой описательную метку атрибут с названием ou=
. Такого рода записи часто используются для общих категорий в записи DIT верхнего уровня (пример часто используемых — ou=people
, ou=groups
и ou=inventory
). LDAP оптимизирован для поиска информации по дереву в направлении
Именование (Naming) и ссылочные записи (Referencing Entries) в DIT
Мы ссылаемся на записи по их атрибутам. Это означает, что каждая запись должна иметь однозначный атрибут или группу атрибутов на своем уровне в иерархии DIT. Этот атрибут или группа атрибутов называется относительное отличительное имя или RDN (от relative distinguished name), и несет ту же функцию, что и имя файла в каталоге.
Чтобы однозначно ссылаться на запись, вы используете её RDN в сочетании со всеми RDN её родительских записей. Эта цепочка RDN ведет назад, вверх по иерархии DIT и указывает однозначный путь к соответствующему элементу. Мы называем эту цепочку RDN различимым именем или DN (от distinguished name). Вы должны указать DN для записи во время создания, чтобы система LDAP знала, где разместить новую запись, и могла убедиться, что RDN записи уже не используется другой записью.
По аналогии, вы можете считать RDN относительным именем файла или директории, как если бы вы работали с ними в файловой системе. DN, с другой стороны, больше похоже на абсолютный путь. Важным отличием является то, что LDAP DN содержит наиболее уточнящие значение слева, в то время как файловые пути содержат наиболее уточняющую информацию справа.
Например, запись для человека по имени Джон Смит может быть помещена под запись «People» в организации example.com
. Так как в организации может быть несколько Джонов Смитов, идентификатор пользователя может быть лучшим выбором для RDN записи. Запись может быть указана вот так:
dn: uid=jsmith1,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
cn: John Smith
sn: Smith
uid: jsmith1
Нам пришлось использовать объектный класс inetOrgPerson
, чтобы получить доступ к атрибуту uid
в данном случае (кроме того, мы ещё имеем доступ ко всем атрибутам, определенным в объектном классе person
, причина этого будет понятна в следующем разделе).
Наследование в LDAP
По большей части то, как данные в
Наследование объектных классов
Каждый objectClass — это класс, который описывает характеристики объектов данного типа.
Однако, в отличие от простого наследования, объекты в LDAP могут быть, и часто являются, экземплярами нескольких классов (некоторые языки программирования предоставляют аналогичную функциональность посредством множественного наследования). Это возможно потому, что LDAP под классом понимает просто набор атрибутов, которые он ДОЛЖЕН (MUST) или может (MAY) иметь. Это позволяет указать для записи несколько классов (хотя только один структурный объектный класс может и должен присутствовать), в результате чего объект просто имеет доступ к объединенной коллекции атрибутов со строжайшими определениями MUST или MAY, имеющими приоритет.
По своему определению, объектный класс может иметь указывать на родительский объектный класс, от которого он наследует свои атрибуты. Это делается с помощью определениям SUP
, за которым следует название объектного класса, от которого происходит наследование. Например, определение объектного класса organizationalPerson
начинается следующим образом:
objectclass (<nobr>2.5.6.7</nobr> NAME 'organizationalPerson' SUP person STRUCTURAL. . .
Родительским объектом является объектный класс, следующий за идентификатором SUP
. STRUCTURAL
или AUXILIARY
). Дочерний объектный класс автоматически наследует атрибуты и требования атрибутов родителя.
При назначении объектного класса конкретной записи, Вам нужно только указать самого последнего потомка цепочки наследования, чтобы иметь доступ ко всему набору атрибутов. В предыдущем разделе мы использовали это для указания inetOrgPerson
в качестве единственного objectClass для нашей записи John Smith, в то же время получив доступ к атрибутам, определенным в объектных классах person
и organizationalPerson
. Иерархия наследования inetOrgPerson
выглядит следующим образом:
inetOrgPerson -> organizationalPerson -> person -> top
Почти все деревья наследования каждого объектного класса заканчиваются специальным объектным классом, называемым «top». Это абстрактный объектный класс, единственное предназначение которого заключается в том, чтобы можно было выполнить требование задавания объектного класса. Он используется для указания вершины цепочки наследования.
Наследование атрибутов
Точно так же, сами атрибуты могут указать родительский атрибут в своем определении. В этом случае атрибут наследует свойства, которые были установлены в родительском атрибуте.
Это часто используется для создания более специфических версий общего атрибута. Например, атрибут фамилия (surname) имеет тот же тип, что и имя, и может использовать все те же методы для сравнения и проверки на равенство. Он может унаследовать эти качества, чтобы получить обобщенную форму атрибута «имя» (name). На деле, конкретное определение фамилии может содержать чуть больше, чем указатель на родительский атрибут.
Это полезно, так как позволяет создать конкретный атрибут, полезный для людей, интерпретирующих элемент, даже когда его обобщенная форма остаётся неизменной. Наследование атрибута surname
, о котором мы говорили здесь, помогает людям различать фамилию и более обощенное имя, но кроме разницы в значениях названия, разница между фамилией и именем в LDAP системе невелика.
Вариации протокола LDAP
В начале мы упоминали, что LDAP на самом деле является лишь протоколом, определяющим интерфейс связи для работы со службами каталогов. Обычно он известен как LDAP, или протокол ldap.
Стоит упомянуть, что вы можете увидеть некоторые варианты в обычном формате:
— ldap://: Это основной протокол LDAP, позволяющий получить структурированный доступ к службе каталогов.
— ldap://: Этот вариант используется для доступа к LDAP поверх SSL/TLS. Обычно трафик LDAP не шифруется, но большинство реализаций LDAP поддерживают подобный вариант доступа. Такой способ шифрования
— ldapi://: Это используется для указания LDAP через IPC. Это часто используется для безопасного соединения с локальной
Все три формата используют протокол LDAP, но последние два указывают на дополнительную информацию о том, как он используется.
Заключение
Вы должны достаточно хорошо понимать протокол LDAP и то, как реализации LDAP представляют данные для пользователей. Понимание того, как элементы системы связаны друг с другом, и где они получают свои свойства, делает управление и использование