Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Объединенная служба каталога

Что такое служа каталога и что такое LDAP?

Служба каталога (Directory Service) – это программный комплекс для хранения и каталогизирования информации. По своей сути это очень похоже на обычную базу данных, но с “уклоном” скорее на чтение данных, нежели на их добавление или модификацию. Обычно служба каталога базируется на клиент-серверной архитектуре. Одна из наиболее известных таких систем – это DNS (Domain Name Service): DNS-сервер производит взаимную “трансляцию” имен машин и их IP-адресов. Другие машины в сети могут обращаться к такому серверу за информацией о соответствии имени и адреса. Однако это очень простой пример каталогизации информации. Объекты в такой базе имеют ограниченное количество атрибутов – таких как имя, адрес и еще несколько дополнительных параметров. Разумеется, служба каталога реального предприятия будет содержать более разнообразные данные и иметь гораздо более сложную структуру.

В общем случае служба каталога должна предоставлять простой, централизованный доступ к данным, которые могут использоваться различными приложениями. Протокол, по которому могла бы работать такая служба, был разработан в ISO (International Standartization Organization), получил номер X.500 и назывался DAP (Directory Access Protocol). В соответствии с этим протоколом любое приложение может получить доступ к информации в каталоге. Там же была предложена гибкая и легко расширяемая информационная структура которая позволяла хранить в принципе любой тип данных. К сожалению, X.500 имел и ряд ограничений, одним из которых была зависимость от коммуникационного уровня, который не являлся стандартным протоколом TCP и запутанность требований к правилам именования объектов. В результате решение на базе этого протокола становилось очень дорогим при обслуживании.

Позже появился протокол LDAP (Lightweight Directory Access Protocol), который позволил реализовать доступ по TCP/IP и мог легко расширяться. В результате появилось решение, позволяющее организовать службу каталога на предприятии любого масштаба.

Сегодня существует несколько реализаций данного протокола от различных фирм. Наиболее известные из них – это Netscape Directory Service, Microsoft Active Directory, Novell Directory Service. Из некоммерческих реализаций LDAP наибольшее распространение получил проект OpenLDAP. Именно его мы и будем рассматривать в данной главе, хотя большинство понятий и определений применимо и к другим реализациям сервера LDAP.

Основные понятия

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

  • Данные каталога хранятся в виде объектов или записей (от англ. entry), состоящих из специальных полей называемых атрибутами (attributes). Набор атрибутов, их синтаксис и правила заполнения определяются схемой каталога (scheme).
  • Данные в каталоге можно представить в виде древовидной структуры – DIT (Directory Information Tree). Это очень похоже на структуру, используемую многими файловыми системами.
  • Каждый объект в структуре каталога идентифицируется специальным атрибутом DN (Distinguished Name). По аналогии с файловой системой DN описывает путь, по которому можно найти объект в дереве каталога. Отличие в данном случае в том, что DN формируется не слева направо, как путь к файлу, а наоборот – справа налево.
  • Любой DN в дереве должен заканчиваться специальным DN, называемым суффиксом каталога (suffix) и являющимся корнем дерева.
  • Корневой объект (Root Entry) – это первый элемент дерева. DN корневого объекта полностью соответствует суффиксу.
  • DN администратора каталога (Root Distinguished Name) – это специальный объект, описывающий администратора каталога. Обычно такой объект не имеет суффикса и к нему не применяются списки доступа (ACL).
  • База поиска (Base Distinguished Name) – объект каталога, начиная с которого производится поиск. Дело в том, что не всегда есть необходимость производить поиск по всему дереву каталога; ограничить область поиска можно указнием в запросе базы поиска. По умолчанию этот параметр соответствует суффиксу.

Объекты и атрибуты

Серверы LDAP могут поставляться с несколькими вариантами бэкенда (backend). Например, OpenLDAP имеет такие варианты, как LDBM – собственный формат хранения данных в текстовых файлах; SHELL – интерфейс к базе данных, использующий команды UNIX; PASSWD – простейшая база, использующая стандартные файлы /etc/passwd и /etc/group; SQL – интерфейс к любой базе данных, использующей SQL.

Для процедур импорта и экспорта всеми серверами LDAP поддерживается единый формат обмена данными – LDIF. Вот пример такого файла:

dn:dc=altlinux,dc=ru
objectClass:top
objectClass:organization
o:ALTLinuxTeam
o:altlinux.ru
dn:ou=People,dc=altlinux,dc=ru
objectClass:top
objectClass:organizationalUnit
ou:People
description:ALTworkers
description:Stuffarea

Описание каждого объекта в таком файле начинается с атрибута DN, который идентифицирует данный объект в каталоге. Специальный атрибут objectClass указывает, к каким классам относится данный объект и, следовательно, какие атрибуты он может иметь. В нашем случае принадлежность к классу top означает, что объект обязательно должен иметь атрибут objectClass, а принадлежность к классу organization предполагает наличие нескольких атрибутов, из которых атрибут o является обязательным. Второй объект находится на одну ступеньку ниже по иерархии и поэтому в его DN включен DN объекта верхнего уровня.

Классы, характеризующие объекты, описываются схемой базы – ее пример приведен ниже.

attributetype(2.5.4.10NAME('o''organizationName')
SUPname
)
attributetype(2.5.4.13NAME'description'
EQUALITYcaseIgnoreMatch
SUBSTRcaseIgnoreSubstringsMatch
SYNTAX1.3.6.1.4.1.1466.115.121.1.15{1024}
)
objectclass(2.5.6.4NAME'organization'SUPtopSTRUCTURAL
MUSTo
MAY(userPassword$searchGuide$seeAlso$businessCategory$
x121Address$registeredAddress$destinationIndicator$
preferredDeliveryMethod$telexNumber$teletexTerminalIdentifier$
telephoneNumber$internationaliSDNNumber$
facsimileTelephoneNumber$street$postOfficeBox$postalCode$
postalAddress$physicalDeliveryOfficeName$st$l$description
)
)

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

  • Атрибут o (его можно также называть organizationName) является расширением атрибута name.
  • Атрибут description – это строка длиной до 1024 байт; при поиске в ней регистр символов не учитывается.
  • Класс organization является расширением класса top и имеет единственный обязательный атрибут o. Кроме того имеется большое количество необязательных атрибутов таких как userPassword, businessAddress, street, postOfficeBox и т.д.

Много полезной информации о схемах можно найти по ссылкам на сайте OpenLDAP.

Установка и настройка

Процесс сборки и установки сервера OpenLDAP не отличается от сборки и установки другого программного обеспечения, поставляемого с исходными кодами. Кроме того, практически во всех современных дистрибутивах Linux он поставляется в виде готового пакета. Поэтому уделим больше внимания настройке.

Настройка сервера

Сервер LDAP состоит из двух серверных процессов slapd и slurpd. Процесс slapd занимается приемом и обработкой запросов от клиентов; это основной процесс, который непосредственно работает с базой данных. Сервис slurpd используется в тех случаях, когда данные нужно реплицировать на другие сервера – он контролирует изменения в базе и при необходимости пересылает их на подчиненные сервера.

Приведем пример конфигурационного файла:

include/etc/openldap/schema/core.schema
include/etc/openldap/schema/nis.schema

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

databaseldbm

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

suffix"dc=altlinux,dc=ru"

Корнем информационной структуры будет являться объект dc=altlinux,dc=ru. В принципе, суффикс для каталога можно взять любой, например, o=ALTLinux,c=RU – это не накладывает абсолютно никаких ограничений на функциональность. Однако последнее время все чаще используется именно первый вид суффикса, который подчеркивает, что информационная структура данного предприятия тесно связана со структурой его домена.

rootdn"cn=admin,dc=altlinux,dc=ru"
rootpwsecret

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

rootpw $1$slJFPHzI$x2hWBQDHqzvMaziAoq2bq/
indexobjectClasseq

Формат ldbm поддерживает простейшие индексы с целью ускорения операций поиска. Желательно создать такие индексы по тем атрибутам, по которым предполагается наибольшее количество обращений.

accesstoattr=userPassword
byselfwrite
byanonymousauth
by*none

accessto*by*read

Не всегда данные каталога находятся в публичном доступе. Для управления доступам могут использоваться списки доступа (access lists). В данном примере приводятся два списка – в первом из них ограничивается доступ к атрибуту userPassword (полный доступ к нему могут иметь только сам объект либо администратор базы; для всех остальных доступ запрещен). Второе правило гласит, что всем дается доступ на чтение любых данных (кроме ограниченного предыдущим правилом).

TLSCipherSuiteHIGH:MEDIUM:+SSLv2
TLSCertificateFile/etc/openldap/ssl/slapd.pem
TLSCertificateKeyFile/etc/openldap/ssl/slapd.pem

Часто LDAP используется для централизованной авторизации пользователей сети. В таких случаях из каталога может запрашиваться конфиденциальная информация, например, пароль. Для предотвращения перехвата этих данных желательно использовать протокол LDAPS (LDAP с SSL/TLS).

После настройки можно сразу запустить процесс slapd – например, такой командой:

slapd-uldap-hldap://127.0.0.1/ldaps://ldap.altlinux.ru/

Первые объекты, которые нужно создать в базе – это корневой элемент (root entry) и администратор базы (root dn), которые указаны в конфигурационном файле как suffix и rootdn.

Настройка репликации

Одной из важных особенностей LDAP являются встроенные средства репликации данных. Этот механизм реализован в виде отдельного серверного процесса, контролирующего изменения в базе данных и пересылающего эти изменения на другие сервера. Прежде чем включать такую репликацию, необходимо убедиться, что соответствующие данные на обоих серверах идентичны. Это связано с тем, что slurpd пересылает именно изменения на текущем сервере – он не проверяет и не анализирует состояние данных на удаленном сервере. Настройки slurpd находятся в том же файле, что и настройки slapd – поэтому перечислим, что нужно добавить к перечисленным выше параметрам:

replica/var/log/slapd.replog

Прежде всего укажем файл, в который slapd будет записывать все свои действия и из которого slurpd будет их читать.

replica
host=ldap2.altlinux.ru
tls=yes
bindmethod=simple
binddn="cn=slurpd,ou=lug,dc=altlinux,dc=ru"
credentials=secret

Для каждого подчиненного сервера описывается так называемая реплика. На вторичном сервере нужно создать соответствующий объект и указать, что он имеет права на изменение информации с помощью параметров updatedn и updateref.

Настройка клиента

Существует огромное количество клиентов, работающих с LDAP. Это могут быть почтовые программы, которые обращаются к каталогу в поисках адреса электронной почты сотрудника или за информацией о маршрутизации почты, FTP-сервер, который берет информацию для авторизации своего клиента и многие другие программы – однако все они имеют схожие настройки. Прежде всего это адрес сервера и порт, на котором работает LDAP (обычно это 389 либо 636, если сервер поддерживает протокол LDAPS). Вторым важным параметром является база поиска (Base DN) – в большинстве случаев этот параметр соответствует суффиксу сервера. Третий важный параметр – фильтр поиска. Кроме того, существуют параметры, позволяющие ограничить поиск снизу – например, только самой базой или базой и ее подобъектами первого уровня, управляющие поиском в алиасах (alias) и т.п.

Трех этих параметров в большинстве случаев достаточно, чтобы выполнить запрос к любому серверу LDAP. Однако если на сервере существуют ограничения на доступ к данным, то может потребоваться авторизация. Авторизоваться в LDAP можно, указав DN одного из объектов базы данных LDAP; пароль для такого объекта будет искаться в его атрибуте userPassword.

Ниже приводится фрагмент настройки почтового сервера Postfix:

canonical_maps=ldap:canonical
canonical_server_host=localhost
canonical_search_base=ou=People,dc=altlinux,dc=ru
canonical_query_filter=(&(uid=%s)(objectClass=posixAccount))
canonical_result_attribute=mail
canonical_scope=sub
canonical_bind=yes
canonical_bind_dn=cn=mta,dc=altlinux,dc=ru
canonical_bind_pw=supersecret

В данном фрагменте описывается, что в процессе канонизации почтового адреса необходимо сделать запрос в LDAP и найти данные по атрибуту mail для объекта, у которого uid соответствует искомой строке и который относится к классу posixAccount. Поиск ограничивается только объектом ou=People,dc=altlinux,dc=ru и его подобъектами первого уровня. Для того, чтобы получить доступ к этим данным, необходимо авторизоваться как объект cn=mta,dc=altlinux,dc=ru, используя пароль supersecret.

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

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

include/etc/openldap/schema/core.schema
include/etc/openldap/schema/cosine.schema
include/etc/openldap/schema/inetorgperson.schema
include/etc/openldap/schema/nis.schema

TLSCipherSuiteHIGH:MEDIUM:+SSLv2
TLSCertificateFile/etc/openldap/ssl/slapd.pem
TLSCertificateKeyFile/etc/openldap/ssl/slapd.pem

pidfile/var/run/slapd.pid
argsfile/var/run/slapd.args
directory/var/lib/ldap
databaseldbm
indexobjectClass,uid,uidNumber,gidNumbereq
indexcn,name,surName,givenNameeq,subinitial
password-hash{MD5}

suffix"dc=altlinux,dc=ru"
rootdn"cn=admin,dc=altlinux,dc=ru"
rootpw{md5}$1$ION4SIII$EYyGEeYt4g2hEe9tjICac.

accesstoattr=userPassword
byselfwrite
byanonymousauth
by*none
accesstoattr=shadowLastChange
byselfread
byanonymousauth
by*none
accesstoattr=shadowFlag
byselfread
byanonymousauth
by*none
accesstoattr=shadowMax
byselfread
byanonymousauth
by*none
accesstoattr=shadowMin
byselfread
byanonymousauth
by*none
accesstoattr=shadowWarning
byselfread
byanonymousauth
by*none
accesstoattr=shadowInactive
byselfread
byanonymousauth
by*none
accesstoattr=shadowExpire
byselfread
byanonymousauth
by*none
accessto*by*read

После этого создадим пользователя ldap, от имени которого будет работать наш сервер, сертификат с помощью программы openssl и запустим процесс slapd следующей командой:

#slapd-uldap-h'ldap://127.0.0.1/ldap//ldap.altlinux.ru/ldaps://ldap.altlinux.ru'

Тепрь можно создать базу данных – например, с помощью утилиты ldapadd:

$ldapadd-xWDcn=admin,dc=altlinux,dc=ru-Hldaps://ldap.altlinux.ru-finitial.ldif

Содержимое файла initial.ldif будет такое:

dn:dc=altlinux,dc=ru
objectClass:top
objectClass:organization
o:ALTLinuxTeam
o:altlinux.ru

dn:cn=admin,dc=altlinux,dc=ru
objectClass:top
objectClass:organizationalRole
cn:admin
description:ALTLinuxLDAPmanager

dn:ou=People,dc=altlinux,dc=ru
objectClass:top
objectClass:organizationalUnit
ou:People
description:Stuffarea

dn:uid=migor,ou=People,dc=altlinux,dc=ru
objectClass:top
objectClass:account
objectClass:posixAccount
objectClass:shadowAccount
objectClass:inetOrgPerson
cn:IgorMuratov
sn:Muratov
givenName:Igor
uid:migor
uidNumber:1000
gidNumber:1000
homeDirectory:/home/migor
loginShell:/bin/bash
userPassword:{md5}$1$ION4SIII$EYyGEeYt4g2hEe9tjICac.
mail:migor@altlinux.ru
mail:migor@linux.ru.net

....

dn:ou=Group,dc=altlinux,dc=ru
objectClass:top
objectClass:organizationalUnit
ou:Group
description:Groupsofusers

dn:cn=luser,ou=Group,dc=altlinux,dc=ru
objectClass:top
objectClass:posixGroup
cn:luser
gidNumber:1000
description:DefaultgroupforuserspresentedbyLDAP

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

$ldapsearch-xLLL"(uid=migor)"
dn:uid=migor,ou=People,dc=altlinux,dc=ru
objectClass:top
objectClass:account
objectClass:posixAccount
objectClass:shadowAccount
objectClass:inetOrgPerson
cn:IgorMuratov
sn:Muratov
givenName:Igor
uid:migor
uidNumber:1000
gidNumber:1000
homeDirectory:/home/migor
loginShell:/bin/bash
mail:migor@altlinux.ru
mail:migor@linux.ru.net

Поскольку, согласно нашим настройкам, доступ к атрибуту userPassword имеют только сам пользователь и администратор, то этот атрибут мы не получили. Собственно, пока он нам и не нужен.

Адресная книга

На сегодняшний день почти все почтовые программы поддерживают возможность использовать LDAP как адресную книгу. В качестве примера возьмем пакет Mozilla; установите пакеты libldap, mozilla, mozilla-mail и запустите программу, далее:

  • откройте окно настройки (Edit->Preferences...);
  • выберите слева категорию Mail & Newsgroups, подкатегорию Addressing;
  • справа в опциях Address Autocompletion включите Directory Server и нажмите кнопку Edit Directories...;
  • в новом окне нажмите кнопку Add и на вкладке General заполните поля Name: ExampleLDAP , Hostname: ldap.altlinux.ru и BaseDN: dc=altlinux,dc=ru;
  • при желании на вкладке Advanced можно указать ограничение на количество возвращаемых записей (по умолчанию это 100) и фильтр поиска.

После этого сохраните изменения – и теперь при заполнении поля To: можно писать не адрес, а имя получателя из атрибута cn. Программа произведет соответствующий поиск и предложит варианты атрибута mail, которые найдет в базе.

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

Маршрутизация почты в Postfix

Предположим, что наше предприятие не имеет своего POP3/IMAP-сервера либо для некоторых сотрудников удобнее получать почту через другой сервер. Для этого нам необходимо принять почту пользователя, приходящую в наш домен, и переправить ее на тот адрес который для сотрудника удобнее. Решений для этой задачи существует несколько: в простейшем варианте можно создать в домашнем каталоге пользователя файл .forward, в котором он сам мог бы указать нужный ему адрес. Однако усложним задание – предположим, что на нашем почтовом сервере нет учетной записи для данного пользователя; тогда получается, что этот файл некуда поместить. Второй вариант – настроить пересылку на самом сервере; для этого создается файл /etc/postfix/virtual приблизительного такого вида:

migor@altlinux.rumigor@linux.ru.net

а в конфигурационном файле Postfix указывается

virtual_maps=hash:/etc/postfix/virtual

Теперь остается только создать хэш и перезапустить Postfix; однако, если мы имеем много таких пользователей и если почтовых серверов существует несколько, то отслеживать синхронное изменение файлов /etc/postfix/virtual становится нелегкой задачей.

Немного модифицируем наше последнее решение. Перенесем данные из файла /etc/postfix/virtual в LDAP; для этого модифицируем приведенную выше базу следующим образом: добавим пользователю класс inetLocalMailRecipient и новый атрибут mailRoutingAddress. Атрибут mail у нас теперь имеет только одно значение.

dn:uid=migor,ou=People,dc=altlinux,dc=ru
changetype:modify
objectClass:top
objectClass:account
objectClass:posixAccount
objectClass:shadowAccount
objectClass:inetOrgPerson
objectClass:inetLocalMailRecipient
mail:migor@altlinux.ru
mailRoutingAddress:migor@linux.ru.net
После этого изменим настройки Postfix:
virtual_maps=ldap:virtual
virtual_server_host=ldap.altlinux.ru
virtual_search_base=ou=People,dc=altlinux,dc=ru
virtual_query_filter=(&(mail=%s)(objectClass=inetLocalMailRecipient))
virtual_result_attribute=mailRoutingAddress
virtual_scope=sub

Теперь почта для данного пользователя будет пересылаться на адрес из атрибута mailRoutingAddress, тем не менее в адресной книге все останется без изменений и там будет показываться “официальный” адрес пользователя из атрибута mail.

Централизованная авторизация

Разобравшись с почтой, хочется перенести в LDAP и авторизацию. Обычно для этих целей используют NIS+, однако хочется использовать для этого более совершенную технологию – в конце концов, у нас уже есть LDAP-сервер, содержащий все необходимые данные по нашим пользователям. Для того, чтобы система искала своих пользователей не только в файле /etc/passwd, необходимо установить пакеты nss_ldap и pam_ldap. Оба пакета имеют общий конфигурационный файл /etc/ldap.conf (в других дистрибутивах это могут быть другие файлы, но синтаксис у них одинаковый).

urildaps://ldap.altlinux.ru
ldap_version3
basedc=altlinux,dc=ru
rootbinddncn=admin,dc=altlinux,dc=ru
timelimit15
sslon

Поскольку нам необходимо получить доступ к атрибуту пароля userPassword, потребуется авторизованный доступ. Для этого укажем опцию rootbinddn, а в файле /etc/ldap.secret запишем пароль администратора базы. Затем подправим файл /etc/nsswitch.conf:

passwd:fileldap
shadow:fileldap
group:fileldap

Теперь проверяем, подключены ли пользователи из базы:

$idmigor
uid=1000(migor)gid=1000(luser)groups=1000(luser)

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

Приложения

RFC

Список RFC, поддерживающих LDAP:

  • RFC 1558: A String Representation of LDAP Search Filters
  • RFC 1777: Lightweight Directory Access Protocol
  • RFC 1778: The String Representation of Standard Attribute Syntaxes
  • RFC 1779: A String Representation of Distinguished Names
  • RFC 1781: Using the OSI Directory to Achieve User Friendly Naming
  • RFC 1798: Connectionless LDAP
  • RFC 1823: The LDAP Application Programming Interface
  • RFC 1959: An LDAP URL Format
  • RFC 1960: A String Representation of LDAP Search Filters
  • RFC 2251: Lightweight Directory Access Protocol (v3)
  • RFC 2307: LDAP as a Network Information Service