И Active Directory (AD) и OpenLDAP играют важные роли в ИТ-инфраструктуре многих предприятий. В одной и той же компании можно найти как группу администраторов UNIX, использующую OpenLDAP, так и сегменты сети и администраторов Windows, использующих AD. Однако большинству администраторов не удается получить полный доступ к схеме AD через OpenLDAP.

OpenLDAP и AD могут мирно сосуществовать, вопрос в том, чтобы найти наилучший способ позволить LDAP-операциям пересекать границы между организациями AD и OpenLDAP. Один из способов это реализовать — использовать службу-посредника OpenLDAP. Для демонстрации этой службы-посредника я опишу шаги, которые сделают контейнер AD cn=Users, по умолчанию содержащий все пользовательские объекты, частью каталога OpenLDAP.

Термины и версии

Для начала определимся с терминологией. Во-первых, сервер LDAP — это так называемый агент службы каталогов Directory Service Agent (DSA). Во-вторых, DSA управляет частью или всем информационным деревом каталога Directory Information Tree (DIT). Несколько агентов DSA могут быть развернуты для управления всем деревом DIT, а также для репликации и обеспечения высокого уровня отказоустойчивости. Часть дерева DIT, которым управляет конкретный агент DSA, называют разделом или базой данных. Я использую термин «база данных».

Для создания примеров данной статьи я использовал систему CentOS 4.3, службу каталогов OpenLDAP 2.2.13 и службу каталогов AD на Windows Server 2003 R2. Далее я покажу ограничение широко применяемого OpenLDAP 2.2, которое можно преодолеть путем установки OpenLDAP 2.3 на CentOS 4.3. Для CentOS 4.3 я использую версию RPMS, размещенную на сайте dev.centos.org/centos/4/testing/i386/RPMS/ (cм. врезку «Обновление OpenLDAP на CentOS» для инструкций по установке).

Запуск процесса сервера OpenLDAP

Процесс сервера OpenLDAP называется slapd; он представляет собой демон LDAP. Этот процесс обеспечивает почти всю функциональность сервера LDAP, включая способность принимать подключения от клиентов LDAP, обрабатывать запросы и обновления, а также осуществлять управление списками ACL, которые ограничивают доступ к конфиденциальной информации в каталоге. Репликация каталога OpenLDAP полностью управляется совершенно другим процессом, и данный вопрос остается за рамками нашей статьи.

Начнем с примера настройки slapd, в котором запустим базовую версию DIT без списков управления доступом ACL и других специальных возможностей. На сервере OpenLDAP конфигурация задается в файле slapd.conf, показанном в листинге 1. В этой конфигурации slapd управляет базой данных для дерева dc=testcorp, dc=com.

Для запуска slapd введем следующую команду:

# service ldap start

и загрузим записи инициализации в базу данных.

Для загрузки записей нужно сначала перенести информацию из листинга 2 в файл с именем dir.ldif. Эти записи определяют очень простое дерево, которое имеет суффикс (или корень) dc=testcorp, dc=com и две ветви: ou=People и ou=Groups. Теперь загрузим записи, используя ldapadd:

# ldapadd -x -h localhost
-D cn=manager, dc=testcorp,
dc=com -W
-f dir.ldif
Enter LDAP Password:
adding new entry "dc=testcorp, dc=com"
adding new entry "ou=People, dc=testcorp, dc=com"
adding new entry "ou=Groups,
dc=testcorp, dc=com"

Параметр -x определяет, что ldapadd должен использовать простую аутентификацию вместо аутентификации Simple Authentication and Security Layer (SASL). С простой аутентификацией клиент LDAP (в данном случае — ldapadd) посылает логин/пароль открытым текстом. Даже используя LDAP поверх SSL (LDAPS) или LDAP StartTLS, вы также будете применять простую аутентификацию, однако туннель, используемый при этом для соединения, шифрует передаваемую информацию (поэтому он безопаснее).

Мы можем проверить правильность загрузки наших записей с помощью команды ldapsearch:

# ldapsearch -LLL -x -h localhost
–b 'dc=testcorp, dc=com'

которая посылает запрос для поиска всех записей, начиная от корня дерева. На экране показан результат выполнения запроса. Как и ожидалось, ldapsearch возвращает три записи, которые мы импортировали с помощью ldapadd. Теперь мы готовы к работе со ссылками.

Предостережение по поводу использования ссылок

Я показал, как с помощью простой команды ldapsearch можно просмотреть записи, которыми управляет OpenLDAP, а вот как просмотреть записи, которыми управляет AD? Для этого нужно настроить подключение к AD либо LDAP-клиента, либо LDAP-сервера (т. е. OpenLDAP).

Очевидное решение — использовать ссылку, с помощью которой агент DSA перенаправляет LDAP-запрос другому агенту DSA. Однако важно иметь в виду следующее: то, как клиент взаимодействует со ссылкой, полностью зависит от его реализации. Например, ldapsearch для OpenLDAP может взаимодействовать со ссылкой при использовании параметра -C, но только для анонимного доступа, ldapsearch не осуществляет проверку подлинности при обращении ко второму агенту DSA.

Если бы вы создавали посредника (пересыльщика) из OpenLDAP в AD, то команда ldapsearch (как и другие команды OpenLDAP, например, ldapadd) возвращала бы следующий результат: «In order to perform this operation a successful bind must be completed on the connection» («Для выполнения операции необходимо для данного подключения установить соответствующие привязки»). Это означает, что ldapsearch направил запрос к контроллеру домена, но операция была отклонена, так как ldapsearch не пытался выполнить проверку подлинности.

Для решения этой проблемы можно разработать собственные клиенты LDAP (например, используя средства Perl Net:: LDAP), задействовать инструментальные средства других разработчиков или обойти эту проблему с помощью службы-посредника OpenLDAP. Мы рассмотрим третий из этих вариантов.

Использование OpenLDAP в качестве службы-посредника

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

С OpenLDAP в качестве посредника все операции направляются через slapd, даже в том случае, если некоторые из них нужно выполнять прямо в AD. Для того чтобы работало перенаправление через slapd, нужно настроить slapd-ldap, посредник для slapd-демона. Вы можете использовать и другие ссылки, например slapd-meta, который даже предоставляет больше возможностей, вроде переопределения контекста именования, но slapd-ldap является самым простым вариантом для первоначальных опытов.

Добавим конфигурацию для slapd-ldap в файл slapd.conf. В листинге 3 показан пример кода. В нем можно увидеть некоторые изменения:

  • database ldap. Мы определили нового посредника slapd-ldap, который будет нашей службой перенаправления.
  • subordinate. Без этого ключевого слова slapd осуществляет поиск только в базе данных, определенной в качестве базы поиска (например, если ldap-объект dc=testcorp, dc=com был указан в качестве базы поиска, то поиск никогда не будет осуществляться в cn=users, dc=testcorp, dc=com, потому что это другая база данных slapd).
  • rebind-as-user. Этот параметр связывает slapd с удаленным DSA от имени учетной записи клиента; данная учетная запись должна быть действительной в AD.
  • Uri. Данный параметр определяет удаленный сервер LDAP, который в нашем случае является контроллером домена AD. Обратите внимание, что мы здесь не используем SSL. В реальной ситуации можно настроить SSL для обеспечения безопасности.
  • chase-referrals. Этот параметр определяет, что slapd автоматически использует любые ссылки.

Что интересно, AD использует тот же самый суффикс dc=testcorp, dc=com, что и OpenLDAP. Часто администраторы и UNIX-, и Windows настраивают службу каталогов одним и тем же стандартным суффиксом (или контекстом именования) и уже позднее осознают, что необходимо обеспечить более тесную интеграцию служб каталогов.

Теперь перезапустим slapd и снова запустим ldapsearch:

# ldapsearch -x -h localhost
    -LLL
-b dc=testcorp, dc=com
-D cn=dpuryear, cn=users,
     dc=testcorp, dc=com -W
'(cn=dpuryear)' cn
Enter LDAP Password:

В этом примере команда ldapsearch посылает запрос на поиск в cn=users, dc=testcorp, dc=com, который slapd должен перенаправить в CN=Users в AD. В том, что slapd действительно выполняет это перенаправление, вы можете убедиться в окне вывода результатов этой команды:

dn: CN=dpuryear, CN=Users, DC=t
   estcorp, DC=com
cn: dpuryear

в котором имеется запись CN=dpuryear, CN=Users, DC=testcorp, DC=com для учетной записи с именем dpuryear в контейнере CN=Users службы каталогов AD. slapd теперь знает, что любая операция с контейнером cn=users, dc=testcorp, dc=com (который является начальной точкой в дереве службы каталогов), требует выполнения следующих шагов:

  1. Установить LDAP-подключение с объектом ldap://dc1.testcorp.com/.
  2. Установить связь от имени учетной записи клиента.
  3. Выполнить операцию.
  4. Возвратить результат операции клиенту.

Однако здесь есть одна проблема: мы не имеем доступа ко всем данным в AD. Чтобы понять, что я имею в виду, попробуйте возвратить атрибут sAMAccountName, который является специфичным именно для схемы каталога AD. Когда я ввожу команду

# ldapsearch -x -h localhost -LLL -b
   dc=testcorp, dc=com
-D cn=dpuryear, cn=users, dc=testcorp,
   dc=com -W
'(cn=dpuryear)' cn sAMAccountName
Enter LDAP Password:

slapd возвращает только атрибуты, определенные в схеме и известные OpenLDAP, и ничего более:

dn: CN=dpuryear, CN=Users, DC=testcorp,
   DC=com
cn: dpuryear

Обратите внимание, что атрибут sAMAccountName в результате не показан, хотя он существует в AD и был запрошен во введенной нами команде ldapsearch. Чтобы получить доступ ко всем данным AD, необходимо установить самую свежую версию OpenLDAP, OpenLDAP 2.3, которая может прозрачно передавать неизвестную схему, хотя и с некоторыми незначительными изменениями в правилах синтаксиса, примененными таким образом, чтобы можно было выполнить фильтрацию.

Использование OpenLDAP 2.3 для передачи неизвестной схемы

Можно установить OpenLDAP 2.3 компиляцией исходного текста или, что намного проще, через RPM Package Manager (RPM). После установки единственное требуемое изменение конфигурации — модификация файлов pidfile и argsfile, так как более новый пакет RPM OpenLDAP предполагает другое местоположение этих файлов. В листинге 4 показан соответствующий код.

Итак, перезапустим slapd и снова выполним команду ldapsearch, используя cn в фильтре:

# ldapsearch -x -h localhost -LLL -b
   dc=testcorp, dc=com
-D cn=dpuryear, cn=users, dc=testcorp,
dc=com -W
   '(cn=dpuryear)' cn sAMAccountName
Enter LDAP Password:

а затем для атрибута sAMAccountName, используемого только в AD:

# ldapsearch -x -h localhost -LLL -b
   dc=testcorp, dc=com
-D cn=dpuryear, cn=users, dc=testcorp,
   dc=com -W
'(sAMAccountName=dpuryear)' cn
   sAMAccountName
Enter LDAP Password:

Получилось! Как видно в окне вывода результатов, ldapsearch послал запрос slapd, который в свою очередь перенаправил этот запрос AD:

dn: cn=dpuryear, cn=Users, dc=testcorp,
   dc=com
cn: dpuryear
SAMACCOUNTNAME: dpuryear

Ключевое различие здесь заключается в том, что мы теперь имеем доступ к полной схеме AD, включая атрибут sAMAccountName.

Прозрачный доступ к AD

Теперь мы можем подключать каталог AD к любой части своего каталога OpenLDAP. Можно осуществлять проверку подлинности пользователей из AD в приложениях LDAP, которые используют OpenLDAP или даже обеспечивают доступ к нескольким каталогам AD корпоративной сети, если они уже не являются частью большего леса.

Дастин Пурье (dustin@puryear-it.com) — консультант и эксперт по управляющим и интегрирующим системам и службам UNIX и Windows. Автор Best Practices for Managing Linux and UNIX Servers (Windows IT Pro eBooks)


Краткое описание решения

Проблема
Не удается получить доступ к схеме Active Directory (AD) через OpenLDAP.

Решение
Использовать службу перенаправления OpenLDAP для подключения к AD.

Что потребуется
CentOS; OpenLDAP; AD на сервере с системой Windows Server 2003 R2.

Уровень сложности
?  ?  ?  ?? ??

Шаги решения

  1. Запустить slapd.
  2. Настроить slapd-ldap; перезапустить slapd и выполнить ldapsearch.
  3. Установить OpenLDAP 2.3.
  4. Внести изменения в файлы pidfile и argsfile.
  5. Перезапустить slapd и снова выполнить ldapsearch.

Листинг 1. slapd.conf

# Import our schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema

# Support both LDAPv2 and LDAPv3
allow bind_v2

pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args

Loglevel 1

# Our primary back end
database bdb
suffix “dc=testcorp,dc=com”
rootdn “cn=manager,dc=testcorp,dc=com”
rootpw “password”
directory /var/lib/ldap
# Indexes for this back end
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uid eq,pres,sub


Листинг 2. Записи в dir.ldif для описания простого дерева

dn: dc=testcorp,dc=com
objectClass: top
objectClass: organization
objectClass: dcObject
dc: testcorp
o: Test Corp, Inc.

dn: ou=People,dc=testcorp,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=testcorp,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Groups


Листинг 3. Добавление конфигурации slapd-ldap в slapd.conf

# Import our schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema

# Support both LDAPv2 and LDAPv3
allow bind_v2

pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args

Loglevel 1

# Our slapd-ldap back end to connect to AD

database ldap
suffix “cn=users,dc=testcorp,dc=com”
subordinate
rebind-as-user
uri “ldap://dc1.testcorp.com/”
chase-referrals yes

# Our primary back end

database bdb
suffix “dc=testcorp,dc=com”
rootdn “cn=manager,dc=testcorp,dc=com”
rootpw “password”
directory /var/lib/ldap
# Indexes for this back end
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uid eq,pres,sub


Листинг 4. Модификация pidfile и argsfile

# Import our schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema

# Support both LDAPv2 and LDAPv3
allow bind_v2

pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args

Loglevel 1

# Our slapd-ldap back end to connect to AD

database ldap
suffix “cn=users,dc=testcorp,dc=com”
subordinate
rebind-as-user
uri “ldap://dc1.testcorp.com”
chase-referrals yes

# Our primary back end
#

database bdb
suffix “dc=testcorp,dc=com”
rootdn “cn=manager,dc=testcorp,dc=com”
rootpw “password”
directory /var/lib/ldap
# Indexes for this back end
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uid eq,pres,sub


Обновление OpenLDAP на CentOS

Для перехода от OpenLDAP 2.2 к OpenLDAP 2.3 на CentOS 4.3 придется обновить yum, автоматический модуль обновления, установщик пакетов или модуль удаления в системах с RPM. Затем можно перейти к обновлению пакетов OpenLDAP. Первым делом укажите yum в репозитории разработки CentOS, добавив следующие строки к /etc/yum.repos.d/CentOS-Base.repo:

[testing]
name=CentOS-$releasever — Testing
baseurl=http://dev.centos.org/centos/$releasever/testing/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://dev.centos.org/centos/RPM-GPG-KEY-CentOS-testing

Затем обновите пакеты OpenLDAP с помощью команды:

# yum -y install openldap.i386 openldap-clients.i386 openldap-devel.i386
   openldap-servers.i386

Обновление требует времени, поскольку yum нужно обновить все пакеты, связанные с OpenLDAP.