печать

LDAP

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

Итак, LDAP. Это есть неструктурированная база данных, оптимизированная под операции чтения. То есть хранить можно все, что угодно. Любой объект может иметь несколько типов, именуемых в LDAP objectClass'ами, и иметь свойственные этим классам атрибуты. Структура базы представляет собой дерево, на ветках которого располагаются объекты. Базовым элементом, определяющим положение объекта на дереве, является dn (distinguished name). Каждый объект в базе LDAP обязательно имеет это имя. Записывается dn так:
cn=admin,dc=shebaronin,dc=ru

Запись ведется справа налево, то есть корень дерева расположен справа, в примере это dc=ru. Левее располагаются ветки и само имя объекта, в данном случае cn — атрибут common name, встречается у большинства объектов. Вообще набор атрибутов объекта определяется его objectClass'ом. Сами objectClass определяются в схемах. Схема — это описание структуры и атрибутов объекта. То есть в схеме описывается какие атрибуты должны быть у объекта такого то типа, какие могут. Как уже упоминалось, объект может иметь несколько неконфликтующих objectClass, значит может иметь ВСЕ атрибуты, присущие ВСЕМ objectClass. Что весьма и весьма удобно. Потому как база и объекты получаются как бы расширяемыми, например понадобился какой то дополнительный атрибут — отлично, добавляем к типам объекта objectClass с нужным атрибутом — вуаля, никаких проблем, атрибут есть.
Объекты, да и вообще вся работа с LDAP ведется через так называемый LDIF — спецформат записи объекта. Может выглядеть. например, так:
dn: uid=baron,ou=People,dc=shebaronin,dc=ru
sn: baron
cn: baron
mailRoutingAddress: baron@mailhost.shebaronin.ru
mailMessageStore: baron/
objectClass: top
objectClass: inetOrgPerson
objectClass: inetLocalMailRecipient
objectClass: qmailUser
objectClass: Vacation
mail: alexander@shebaronin.ru
mail: noc@shebaronin.ru
uid: baron
vacationInfo: Out of office
vacationForward: Forward
vacationActive: FALSE

Формат прост: слева до двоеточия — название атрибута, справа от двоеточия — значение. Как видим, объект этот принадлежит сразу нескольким objectClass'ам. Начинается все с класса top — пустой класс. Далее inetOrgPerson — класс, содержащий множество информации о персоне, такой, как имя, фамилия, пароль, адрес электронной почты... inetLocalMailRecipient добавляет атрибут mailRoutingAddress, который в моей системе используется для определения окончательного ящика для доставки почты. Класс qmailUser добавляет атрибуты mailMessageStore и несколько других, мною в данный момент неиспользуемых. И последний — Vacation — для работы так называемого почтового "отбойника", то есть автоответчика на почтовом ящике в отсутствие пользователя. На самом деле список доступных атрибутов значительно длиннее, тут показаны только заполненные.

Для работы с LDAP есть спецтулзы, в Debian живут они в пакете ldap-utils. В нем присутствуют ldapadd, ldapmodify, ldapdelete, ldapsearch. Вообще то их там больше, но эти наиболее часто используемы. По крайней мере мной smile При установке сервер спросит о dn для создаваемой базы. Это будет корень дерева этого сервера. В принципе можно одному серверу прописать несколько баз, но в моем случае это не нужно да и, думаю, не доставит особых трудностей. Впрочем, о конфигурации сервера позже. Итак, утилиты для работы с базой LDAP. Все они имеют одинаковый список опций. Нам интересны несколько:
-h host
имя хоста куда цепляться

-x
использовать "простую" авторизацию (по умолчанию используется SASL)

-W
спрашивать пароль для привязки к серверу

-b basedn
базовый dn для поиска-добавления-правок, обычно равен или корню базы (dc=shebaronin,dc=ru), или какой то ветке в базе, дабы ограничить поиск только этой веткой.

-D binddn
dn для привязки, как бы имя пользователя

Командная строка, которой был получен объект из примера:
ldapsearch -x -h localhost -b "dc=shebaronin,dc=ru" uid=baron

Отсутствие ключа -D при наличии -x означает анонимную привязку, чего для поиска вполне достаточно на большинстве серверов. Далее задан базовый dn с которого начинать поиск и фильтр. Если не указать фильтр, то будут выведены все объекты, лежащие в этой ветке. Фильтровать можно по любому атрибуту. В том числе и objectClass. Например, для выбора записей, для которых включен автоответчик, можно использовать:
ldapsearch -x -h localhost -b "dc=shebaronin,dc=ru" '(&(objectClass=Vacation)(vacationActive=TRUE))'

При написании хитрофильтров не забываем заключать их в апострофы, дабы предотвратить их обработку шеллом. Синтаксис фильтра честно подсмотрен в примерах, поэтому не ручаюсь что это так, но... работает! Фильтр пишется так. Сначала — логическое действие. В данном примере это "И" (&). За ним должны идти два или больше выражений, с которыми это действие будет совершаться. Логических действий мне известно два: И (обозначается &) и ИЛИ (обозначается |). Каждое из выражений в свою очередь может быть логическим действием над другими выражениями и так далее.

Как правило в любой базе LDAP есть так называемый rootdn — аналог юниксового рута для этой базы. При присоединении с данным dn вы получаете ВСЕ права на базу, то есть можете удалять, править, видеть и искать по любым атрибутам вне зависимости от прав доступа, описанных в конфиге сервера. Поэтому пароль от этого dn стоит хранить аккуратно, не вывешивая на всеобщее обозрение.

Похоже настало время разобраться с конфигурацией сервера. Живой конфигурационный файл с комментариями:
разрешаем присоединяться по протоколу версии 2 — очень многие версию 3 не умеют, особенно под виндой
allow bind_v2

включаем нужные схемы
include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema

моя слегка патченная схема. В принципе не нужна.
include         /etc/ldap/schema/mymisc.schema
include         /etc/ldap/schema/openldap.schema

схема от qmail — используется для атрибутов, используемых почтовой системой
include         /etc/ldap/schema/qmail.schema

схема от samba — тут пока навырост :)
include         /etc/ldap/schema/samba.schema

схема для организации автоответчика на почте
include         /etc/ldap/schema/myvacation.schema


включаем проверку объектов на соответствие схемам
schemacheck     on

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


включаем логгирование запросов. очень полезно для дебага, вредно на рабочей системе — логи загаживает :)
loglevel        256

modulepath      /usr/lib/ldap
moduleload      back_bdb

sizelimit 500

tool-threads 1



начинается конфигурация бекендов — реальных драйверов хранения. bdb — самый простой базовый бекенд,
использующий db. Простой и функциональный.
backend         bdb
checkpoint 512 30


можно сконфигурить множество разных бекендов, но нам это не надо
#backend                <other>


конфигурация базы. Объявляем ее как базу на бекенде bdb
database        bdb


базовый dn. с этой точки будут начинаться все записи этой базы.
suffix          "dc=shebaronin,dc=ru"


тот самый root для этой ветки. Может ВСЕ..
rootdn          "cn=admin,dc=shebaronin,dc=ru"


физическое местоположение базы на диске.
directory       "/var/lib/ldap"


записи для репликации базы. при внесении изменений головной сервер автоматически реплицирует их на ведомых
replica uri=ldap://192.168.1.1:389
        binddn="cn=replica,dc=shebaronin,dc=ru"
        bindmethod=simple
        credentials=passwd

первая строка — местоположение ведомого. URI.
binddn — dn для репликации. должен иметь все права на модификацию базы на ведомом.
bindmethod — метод аутентификации. может быть simple и sasl. sasl надежнее, но симпл проще, и в защищенных местах удобнее
credentials --Пароль для присоединения.

вторая реплика. все аналогично первой.
replica uri=ldap://192.168.1.2:389
        binddn="cn=replica,dc=shebaronin,dc=ru"
        bindmethod=simple
        credentials=passwd

маппинги для аутентификации непосредственно по базе.
нужны для аутентификации непосредственно по лдапу, без использования sasl
authz-regexp
        uid=([^,]*),cn=shebaronin.ru,cn=digest-md5,cn=auth
        uid=$1,ou=People,dc=shebaronin,dc=ru

authz-regexp
        uid=([^,]*),cn=digest-md5,cn=auth
        uid=$1,ou=People,dc=shebaronin,dc=ru

store password in cleartext for DIGEST-MD5
password-hash   {CLEARTEXT}

Далее идут тонкие настройки базы, для обычных нормальных людей трогать ничего не надо.
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM
dbconfig set_cachesize 0 2097152 0

# Number of objects that can be locked at the same time.
dbconfig set_lk_max_objects 1500
# Number of locks (both requested and granted)
dbconfig set_lk_max_locks 1500
# Number of lockers
dbconfig set_lk_max_lockers 1500

Индексы. для ускорения поиска рекомендуется индексировать базу по тем атрибутам, по которым чаще всего ищем.
# Indexing options for database #1
index         objectClass                             eq
index         uid,uidNumber,gidNumber,memberUid       eq
index         cn,mail,surname,givenname               eq,subinitial
index         sambaSID                                eq
index         sambaPrimaryGroupSID                    eq
index         sambaDomainName                         eq

неизвестный мне параметр. не трогаем biggrin
lastmod         on

  1. Where to store the replica logs for database #1
replogfile      /var/lib/ldap/replog

# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
access to attrs=userPassword,shadowLastChange,sambaNTPassword,sambaLMPassword
        by dn="cn=admin,dc=shebaronin,dc=ru" write
        by anonymous auth
        by self write
        by * none

# Ensure read access to the base for things like
# supportedSASLMechanisms.  Without this you may
# have problems with SASL not knowing what
# mechanisms are available and the like.
# Note that this is covered by the 'access to *'
# ACL below too but if you change that as people
# are wont to do you'll still need this if you
# want SASL (and possible other things) to work 
# happily.
access to dn.base="" by * read

# The admin dn has full write access, everyone else
# can read everything.
access to *
        by dn="cn=admin,dc=shebaronin,dc=ru" write
        by * read

# For Netscape Roaming support, each user gets a roaming
# profile for which they have write access to
#access to dn=".*,ou=Roaming,o=morsnet"
#        by dn="cn=admin,dc=shebaronin,dc=ru" write
#        by dnattr=owner write

#######################################################################
# Specific Directives for database #2, of type 'other' (can be bdb too):
# Database specific directives apply to this databasse until another
# 'database' directive occurs
#database        <other>

# The base of your directory for database #2
#suffix         "dc=debian,dc=org"

Создано: baron последнее изменение: Thursday 06 December 2007 [13:55:38 UTC] автор baron