Это старая версия документа.
Содержание
OpenLDAP сервер
Легковесный протокол доступа к каталогам, или LDAP - это протокол запросов и изменений к сервису каталогов на базе X.500, работающий поверх TCP/IP. Текущая версия LDAP это LDAPv3, как определено в RFC4510, а реализация LDAP в Ubuntu - это OpenLDAP, текущей версии 2.4.25 (Oneiric) (2.4.28 для Precise - прим. переводчика).
Итак, этот протокол обеспечивает доступ к каталогам LDAP. Здесь приведены некоторые ключевые понятия и термины:
LDAP каталог - это дерево данных в виде записей, иерархичных по своей натуре, называемое Дерево каталогов информации (DIT).
Запись содержит набор атрибутов.
Атрибут имеет тип (имя/описание) и одно или несколько значений.
Каждый атрибут должен быть определен как минимум в одном objectClass.
Атрибуты и объектные классы определяются в схемах (объектный класс фактически рассматривается как специальный вид атрибута).
Каждая запись имеет уникальный идентификатор: свое Отличительное имя (DN или dn). Она состоит из своего Относительного отличительного имени (RDN), следующим за записью родительского DN.
DN записи - это не атрибут. Оно не является рассматриваемой частью собственно записи.
Например, далее мы имеем одну запись, содержащую 11 атрибутов. Ее DN - это "cn=John Doe,dc=example,dc=com"; ее RND - это "cn=John Doe"; а родительский DN - "dc=example,dc=com".
dn: cn=John Doe,dc=example,dc=com cn: John Doe givenName: John sn: Doe telephoneNumber: +1 888 555 6789 telephoneNumber: +1 888 555 1232 mail: john@example.com manager: cn=Larry Smith,dc=example,dc=com objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top
Вышеприведенная запись - это формат LDIF (формат обмена данными LDAP). Любая информация, которую вы помещаете в ваш DIT должна быть в таком формате. Это определено в RFC2849.
Хотя данное руководство описывает как использовать это для централизованной идентификации, LDAP хорош для всего, что затрагивает большое количество запросов к системе, основанной на атрибутах (имя:значение) и ориентированной преимущественно на чтение. В качестве примеров можно привести адресную книгу, список адресов email и конфигурация почтового сервера.
Установка
Установка сервиса сервера OpenLDAP и привычных утилит управления LDAP. Они находятся в пакетах slapd и ldap-utils соответственно.
Установка slapd создаст работающую конфигурацию. В частности она создаст экземпляр базы данных, которую вы можете использовать для хранения своих данных. Однако суффикс (или базовый DN) этого экземпляра будет определен из доменного имени localhost. Если вы хотите использовать что-то другое, отредактируйте /etc/hosts и замените доменное имя на подходящее. В качестве примера, если вам нужен суффикс dc=example,dc=com, то ваш файл должен иметь подобную строку:
127.0.1.1 hostname.example.com hostname
Вы можете отменить изменения после установки пакета.
Продолжим с установкой:
sudo apt-get install slapd ldap-utils
Начиная с Ubuntu 8.10 slapd проектируется, чтобы настраиваться самостоятельно, выделяя отдельный DIT для этой цели. Это позволяет динамически настраивать slapd без необходимости перестартовывать сервис. Эта конфигурационная база данных содержит коллекцию текстовых LDIF файлов, расположенных в /etc/ldap/slapd.d. Этот вариант работы известен под разными именами: метод slapd-config, RTC метод (настройка в реальном времени) или cn=config метод. Вы все еще можете использовать традиционный метод плоского файла (slapd.conf), но это не рекомендуется; данная функциональность в конечном счете будет убрана.
Во время установки у вас будет запрос на информацию об администраторе. Это LDAP данные для rootDN вашего экземпляра базы данных. По умолчанию этот пользовательский DN cn=admin,dc=example,dc=com. Также по умолчанию не создаеется административного пользователя для базы данных slapd-config и вы, следовательно, будете вынуждены использовать внешнюю авторизацию LDAP для доступа к ней. Мы рассмотрим как это делается позднее.
Некоторые классические схемы (cosine, nis, inetorgperson) выпускаются теперь для slapd. Это также включает базовую (core) схему, которая предполагается для любой рабочей схемы.
Проверка после установки
Процесс установки создаст 2 DIT. Один для slapd-config и один для ваших данных (dc=example,dc=com). Давайте взглянем:
Здесь показано как выглядит дерево (DIT) базы данных slapd-config. Напомним, что эта база основана на LDIF и находится в /etc/ldap/slapd.d:
/etc/ldap/slapd.d/ ├── cn=config │ ├── cn=module{0}.ldif │ ├── cn=schema │ │ ├── cn={0}core.ldif │ │ ├── cn={1}cosine.ldif │ │ ├── cn={2}nis.ldif │ │ └── cn={3}inetorgperson.ldif │ ├── cn=schema.ldif │ ├── olcBackend={0}hdb.ldif │ ├── olcDatabase={0}config.ldif │ ├── olcDatabase={-1}frontend.ldif │ └── olcDatabase={1}hdb.ldif └── cn=config.ldif
Здесь ппоказано как выглядит дерево slapd-config через LDAP протокол:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn dn: cn=config dn: cn=module{0},cn=config dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: olcBackend={0}hdb,cn=config dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}hdb,cn=config
Объяснение по записям:
cn=config: глобальные настройки
cn=module{0},cn=config: динамически загружаемый модуль
cn=schema,cn=config: содержит жестко запрограммированную схему системного уровня
cn={0}core,cn=schema,cn=config: жестко запрограммированная схема ядра (core)
cn={1}cosine,cn=schema,cn=config: схема cosine
cn={2}nis,cn=schema,cn=config: схема nis
cn={3}inetorgperson,cn=schema,cn=config: схема inetorgperson
olcBackend={0}hdb,cn=config: тип хранилища 'hdb' заднего плана
olcDatabase={-1}frontend,cn=config: база переднего плана, настройка по умолчанию для других баз данных
olcDatabase={0}config,cn=config: конфигурационная база slapd (cn=config)
olcDatabase={1}hdb,cn=config: экземпляр вашей базы данных (dc=examle,dc=com)
А здесь показано как выглядит дерево dc=example,dc=com:
ldapsearch -x -LLL -H ldap:/// -b dc=example,dc=com dn dn: dc=example,dc=com dn: cn=admin,dc=example,dc=com
Объяснение по записям:
dc=example,dc=com: базовый уровень вашего дерева (DIT)
cn=admin,dc=example,dc=com: администратор (rootDN) данного дерева (заполняется в процессе установки пакета)
Изменение/заполнение вашей базы данных
Давайте введем некоторые данные в нашу базу. Мы добавим следующее:
ноду с названием People (сохранять пользователей)
ноду с названием Groups (сохранять группы)
группу с названием miners
пользователя с именем john
Создайте следующий LDIF файл и назовите его add_content.ldif:
dn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People dn: ou=Groups,dc=example,dc=com objectClass: organizationalUnit ou: Groups dn: cn=miners,ou=Groups,dc=example,dc=com objectClass: posixGroup cn: miners gidNumber: 5000 dn: uid=john,ou=People,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: john sn: Doe givenName: John cn: John Doe displayName: John Doe uidNumber: 10000 gidNumber: 5000 userPassword: johnldap gecos: John Doe loginShell: /bin/bash homeDirectory: /home/john
Добавляем контент:
ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_content.ldif Enter LDAP Password: ******** adding new entry "ou=People,dc=example,dc=com" adding new entry "ou=Groups,dc=example,dc=com" adding new entry "cn=miners,ou=Groups,dc=example,dc=com" adding new entry "uid=john,ou=People,dc=example,dc=com"
Мы можем проверить, что информация добавлена правильно с помощью утилиты ldapsearch:
ldapsearch -x -LLL -b dc=example,dc=com 'uid=john' cn gidNumber dn: uid=john,ou=People,dc=example,dc=com cn: John Doe gidNumber: 5000
Объяснения по параметрам:
-x: "простое" связывание; не будет использоваться метод SASL по умолчанию
-LLL: отключить вывод посторонней информации
uid=john: "фильтр" для нахождения пользователя john
cn gidNumber: запрос на вывод определенных атрибутов (по умолчанию выводятся все атрибуты)
Изменение базы данных настройки slapd
Дерево (DIT) slapd-config также может запрашиваться и изменяться. Здесь приведено несколько примеров.
Используйте ldapmodify для добавления индекса (атрибут DbIndex) для вашей {1}hdb,cn=config базы (dc=example,dc=com). Создайте файл с названием uid_index.ldif следующего содержания:
dn: olcDatabase={1}hdb,cn=config add: olcDbIndex olcDbIndex: uid eq,pres,sub
Затем выполните команду:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f uid_index.ldif modifying entry "olcDatabase={1}hdb,cn=config"
Вы можете подтвердить изменения следующим способом:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={1}hdb)' olcDbIndex dn: olcDatabase={1}hdb,cn=config olcDbIndex: objectClass eq olcDbIndex: uid eq,pres,sub
Давайте добавим схему. Это будет первый раз, когда потребуется конвертация в LDIF формат. Вы можете найти несконвертированные схемы в добавление к сконвертированным в каталоге /etc/ldap/schema.
Удаление схемы из базы slapd-config - нетривиальная задача. Потренируйтесь добавлять схемы на тестовой системе.
Перед добавлением любой схемы, вам следует проверить какие схемы уже установлены (показан вывод по умолчанию, для состояния "из коробки"):
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=schema,cn=config dn dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config In the following example we'll add the CORBA schema. dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config
В следующем примере мы добавим схему CORBA.
Создайте конфигурационный файл преобразования schema_convert.conf, содержащий следующие строки:
include /etc/ldap/schema/core.schema include /etc/ldap/schema/collective.schema include /etc/ldap/schema/corba.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/duaconf.schema include /etc/ldap/schema/dyngroup.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/java.schema include /etc/ldap/schema/misc.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/openldap.schema include /etc/ldap/schema/ppolicy.schema include /etc/ldap/schema/ldapns.schema include /etc/ldap/schema/pmi.schema
Создайте каталог назначения ldif_output.
Определите индекс схемы:
slapcat -f schema_convert.conf -F ldif_output -n 0 | grep corba,cn=schema cn={1}corba,cn=schema,cn=config
Используйте slapcat для выполнения преобразования:
slapcat -f schema_convert.conf -F ldif_output -n0 -H \ ldap:///cn={1}corba,cn=schema,cn=config -l cn=corba.ldif
Сконвертированная (преобразованная) схема теперь в cn=corba.ldif
Редактируйте cn=corba.ldif, по достижении следующих атрибутов:
dn: cn=corba,cn=schema,cn=config ... cn: corba
Также удалите следующие строки в конце:
structuralObjectClass: olcSchemaConfig entryUUID: 52109a02-66ab-1030-8be2-bbf166230478 creatorsName: cn=config createTimestamp: 20110829165435Z entryCSN: 20110829165435.935248Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20110829165435Z
Значения ваших атрибутов могут быть другими.
Наконец, используйте ldapadd для добавления новой схемы к дереву slapd-config:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f cn\=corba.ldif adding new entry "cn=corba,cn=schema,cn=config"
Проверьте текущую загруженную схему:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: cn={4}corba,cn=schema,cn=config
Ведение журналов
Ведение журнала активности для slapd обязательно, когда осуществляется решение на базе OpenLDAP, поэтому его требуется включить вручную после установки приложения. Иначе только элементарные сообщения будут доступны в журналах. Ведение журналов, как и другие настройки slapd, подключаются через базу данных slapd-config.
OpenLDAP поставляется с несколькими подсистемами (уровнями) журналирования, каждая из которых включает подчиненную (дополнительную). Хороший вариант, который стоит попробовать - это stats. Страница руководства slapd-config содержит больше информации по иным подсистемам.
Создайте файл logging.ldif со следующим содержимым:
dn: cn=config changetype: modify add: olcLogLevel olcLogLevel: stats
Производим изменения:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f logging.ldif
Это породит значительный объем записи в журнал и вы захотите уменьшить уровень детализации когда ваша система станет боевой. С таким уровнем детализации система журналирования вашего хоста (rsyslog) может отнимать значительное время процессора, а также пропускать сообщения:
rsyslogd-2177: imuxsock lost 228 messages from pid 2547 due to rate-limiting
Вы можете решить изменить настройки rsyslog. В файл /etc/rsyslog.conf поместите следующее:
# Disable rate limiting # (default is 200 messages in 5 seconds; below we make the 5 become 0) $SystemLogRateLimitInterval 0
А затем перезапустите сервис rsyslog:
sudo service rsyslog restart
Репликация
Сервис LDAP становится все более и более важным поскольку большинство сетевых систем начинают зависеть от него. В этом контексте стандартной практикой является встраивание избыточности (высокой доступности) в LDAP для защиты от опустошения, которое сделает сервер неработающим. Это достигается с помощью репликации LDAP.
Репликация доступна через механизм Syncrepl. Он позволят синхронизировать изменения используя модель Потребитель-Поставщик. Специфический вид репликации, который мы будем реализовывать в этом руководстве, является комбинацией следующих режимов: refreshAndPersist и delta-syncrepl. Это подразумевает что Потребитель передает измененные записи Поставщику, как только они появляются, но при этом посылаются только актуальные изменения, а не все записи.
Настройка Поставщика
Начнем с настройки Поставщика.
Создадим LDIF файл со следующим содержимым и назовем его provider_sync.ldif:
# Add indexes to the frontend db. dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryCSN eq - add: olcDbIndex olcDbIndex: entryUUID eq #Load the syncprov and accesslog modules. dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov - add: olcModuleLoad olcModuleLoad: accesslog # Accesslog database definitions dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /var/lib/ldap/accesslog olcSuffix: cn=accesslog olcRootDN: cn=admin,dc=example,dc=com olcDbIndex: default eq olcDbIndex: entryCSN,objectClass,reqEnd,reqResult,reqStart # Accesslog db syncprov. dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE # syncrepl Provider for primary db dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE # accesslog overlay definitions for primary db dn: olcOverlay=accesslog,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogSuccess: TRUE # scan the accesslog DB every day, and purge entries older than 7 days olcAccessLogPurge: 07+00:00 01+00:00
Замените rootDN в LDIF файле на соответствующий вашему каталогу.
Профиль apparmor для slapd нужно будет отрегулировать для расположения базы accesslog. Отредактируйте /etc/apparmor.d/local/usr.sbin.slapd, добавив следующее:
/var/lib/ldap/accesslog/ r, /var/lib/ldap/accesslog/** rwk,
Создаем каталог, устанавливаем файл настроек базы данных и перегружаем рофиль apparmor:
sudo -u openldap mkdir /var/lib/ldap/accesslog sudo -u openldap cp /var/lib/ldap/DB_CONFIG /var/lib/ldap/accesslog sudo service apparmor reload
Добавляем новый контент и, поскольку изменили apparmor, перестартуем сервис:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f provider_sync.ldif sudo service slapd restart
Поставщик теперь настроен.
Настройка Потребителя
А теперь настроим Потребителя.
Установим программное обеспечение как указано в Установке. Убедитесь, что база slapd-config аналогична базе Поставщика. Особенно проверьте, что одинаковы схемы и суффикс базы.
Создайте LDIF файл со следующим содержимым и назовите его consumer_sync.ldif:
dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryUUID eq - add: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog - add: olcUpdateRef olcUpdateRef: ldap://ldap01.example.com
Убедитесь, что следующие атрибуты имеют корректные значения:
provider (hostname сервера Поставщика - ldap01.example.com в этом примере - или IP адрес)
binddn (DN администратора, которым вы пользуетесь)
credentials (пароль для DN администратора, который вы используете)
searchbase (суффикс базы, которую вы используете)
olcUpdateRef (hostname сервера Поставщика или его IP адрес)
rid (Replica ID, уникальное трехзначное число, идентифицирующее данную копию. Каждый Потребитель должен иметь минимум один rid)
Добавьте новый контент:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f consumer_sync.ldif
Вы сделали это! Две базы (суффикс: dc=example,dc=com) будут теперь синхронизированы.
Проверка
Как только репликация стартует, вы можете отслеживать ее запустив:
ldapsearch -z1 -LLLQY EXTERNAL -H ldapi:/// -s base contextCSN dn: dc=example,dc=com contextCSN: 20120201193408.178454Z#000000#000#000000
как на Поставщике, так и на Потребителе. Как только вывод (20120201193408.178454Z#000000#000#000000 в примере выше) на обеих машинах совпадет, вы провели репликацию. Каждый раз, как происходят изменения на Поставщике, это значение будет изменяться и должно стать таким же на Поставщике.
Если ваше соединение медленное и/или ваша база LDAP велика, процесс приведения в соответствие contextCSN Потребителя и Поставщика может быть протяженным. Но, вы должны знать, что процесс запускается как только contextCSN Потребителя неизбежно увеличивается.
Если contextCSN Потребителя отсутствует или не совпадает со значением Поставщика, вы должны остановиться и понять причину проблемы перед тем как продолжить. Попробуйте проверить slapd (syslog - системный журнал) и файлы журналов авторизации Поставщика, чтобы увидеть удачны ли были запросы авторизации Потребителя и не возвращались ли ошибки в ответ на запросы данных (они будут видны как множество записей ldapsearch).
Чтобы проверить, что все работает, просто запросите на Потребителе DN из базы:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b dc=example,dc=com dn
Вы должны увидеть пользователя 'john' и группу 'miners', также как ноды 'People' и 'Groups'.
Контроль доступа
Управление какой тип доступа (чтение, запись и пр.) пользователей должен быть предоставлен к ресурсам известен как контроль доступа. Сочетания подобных директив называются Списками контроля доступа (ACL).
Когда мы устанавливаем пакет slapd различные ACL устанавливаются автоматически. Мы рассмотрим некоторые важные следствия этих умолчаний и, занимаясь этим, мы поймем идею того, как работают ACL и как их настраивать.
Для получения эффективных ACL для запроса LDAP нам надо посмотреть на ACL записи запрашиваемой базы данных также как и на записи специального экземпляра базы данных переднего плана. По умолчанию используются ACL, полученные последним действием, в случае, если они не совпадают с правилами из предыдущего варианта. База данных переднего плана опрашивается во вторую очередь и применяется ACL по первому совпадению среди этих двух источников ACL. Следующие команды покажут соответственно ACL базы hdb ("dc=example,dc=com") и они же из базы переднего плана:
To get the effective ACL for an LDAP query we need to look at the ACL entries of the database being queried as well as those of the special frontend database instance. The ACLs belonging to the latter act as defaults in case those of the former do not match. The frontend database is the second to be consulted and the ACL to be applied is the first to match («first match wins») among these 2 ACL sources. The following commands will give, respectively, the ACLs of the hdb database («dc=example,dc=com») and those of the frontend database:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={1}hdb)' olcAccess dn: olcDatabase={1}hdb,cn=config olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none olcAccess: {1}to dn.base="" by * read olcAccess: {2}to * by self write by dn="cn=admin,dc=example,dc=com" write by * read
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={-1}frontend)' olcAccess dn: olcDatabase={-1}frontend,cn=config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred, cn=external,cn=auth manage by * break olcAccess: {1}to dn.exact="" by * read olcAccess: {2}to dn.base="cn=Subschema" by * read
Самый первый ACL очень важен:
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none
Это может быть представлено по-другому для лучшего понимания:
to attrs=userPassword by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none to attrs=shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=com" write by * none
Этот составной ACL (их два) предписывает следующее:
Анонимный 'auth' доступ обеспечивается к атрибуту userPassword для осуществления изначального соединения. Возможно потребуется counter-intuitively для 'by anonymous auth' даже когда анонимный доступ к DIT не требуется. Как только удаленное соединение установлено, требуется авторизация (см. следующий пункт).
Должна пройти авторизация, поскольку все пользователи имеют доступ на чтение (вследствие 'by self write') к атрибуту userPassword.
Атрибут userPassword не доступен для всех других пользователей за исключением rootDN, который имеет полный доступ.
Для того чтобы пользователи могли менять собственные пароли, используя passwd или иные утилиты, атрибут shadowLastChange должен быть доступен как только пользователь авторизовался.
Поиск по этому DIT может быть проведен анонимно из-за 'by * read' в данном ACL:
to * by self write by dn="cn=admin,dc=example,dc=com" write by * read
Если это нежелательно, то вам потребуется изменить набор ACL. Для принуждения к авторизации в процессе связывающего (bind) запроса в качестве альтернативы (или в комбинации с измененным ACL) вам надо использовать директиву 'olcRequire: authc'.
Как указывалось ранее, никаких административных пользователей не создается для базы slapd-config. Однако существует идентификация SASL, которая обеспечивает полный к ней доступ. Она подобна суперпользователю для localhost (root/sudo). Вот она:
dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
Следующая команда покажет ACL базы slapd-config:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcDatabase={0}config)' olcAccess dn: olcDatabase={0}config,cn=config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred, cn=external,cn=auth manage by * break
Поскольку это SASL идентификация, нам потребуется механизм SASL, когда запрашивается LDAP утилита, о которой идет речь и мы увидим это много раз в данном руководстве. Это внешний (EXTERNAL) механизм. Смотрите предыдущую команду в качестве примера. Обратите внимание:
Вы должны использовать sudo для идентификации как root чтобы ACL сработали.
Механизм EXTERNAL работает через IPC (доменные сокеты UNIX). Это означает , что вы должны использовать ldapi формат адресации (URI).
Короткий путь для получения всех ACL выглядит следующим образом:
sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b \ cn=config '(olcAccess=*)' olcAccess olcSuffix
Есть еще много что сказать по контролю доступа. Смотрите страницу руководства по slapd.access.
TLS
Когда происходит аутентификация на OpenLDAP сервере, лучше всего это делать используя зашифрованную сессию. Это может быть достигнуто использованием транспортного уровня шифрования (TLS).
Здесь мы организуем свой собственный Центр сертификатов (Certificate Authority - CA) и затем создадим и подпишем сертификат нашего LDAP сервера от имени этого CA. Поскольку slapd скомпилирован с использованием библиотеки gnutls, мы будем использовать для выполнения этих задач утилиту certtool.
Устанавливаем пакеты gnutls-bin и ssl-cert:
sudo apt-get install gnutls-bin ssl-cert
Создаем секретный ключ Центра сертификатов:
sudo sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
Создаем временный файл /etc/ssl/ca.info для оределения CA:
cn = Example Company ca cert_signing_key
Создаем самоподписанный сертификат центра:
sudo certtool --generate-self-signed \ --load-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ca.info \ --outfile /etc/ssl/certs/cacert.pem
Создаем секретный ключ для сервера:
sudo certtool --generate-privkey \ --bits 1024 \ --outfile /etc/ssl/private/ldap01_slapd_key.pem
Создаем информационный файл /etc/ssl/ldap01.info, содержащий следующее:
organization = Example Company cn = ldap01.example.com tls_www_server encryption_key signing_key expiration_days = 3650
Данный сертификат будет действителен 10 лет (3650 дней). Вы можете выбрать другое значение.
Создаем серверный сертификат:
sudo certtool --generate-certificate \ --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template /etc/ssl/ldap01.info \ --outfile /etc/ssl/certs/ldap01_slapd_cert.pem
Создайте файл certinfo.ldif со следующим содержимым (подставляйте свои значения, наш пример предполагает использование https://www.cacert.org):
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap01_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap01_slapd_key.pem
Используйте команду ldapmodify, чтобы сказать slapd о работе нашего TLS через базу данных slapd-config:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ssl/certinfo.ldif
Вопреки распространенному мнению, вам не обязательно указывать ldaps:// в /etc/default/slapd чтобы использовать шифрование. Вам достаточно указать:
SLAPD_SERVICES="ldap:/// ldapi:///"
Tighten up ownership and permissions:
sudo adduser openldap ssl-cert sudo chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap01_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
Restart OpenLDAP:
sudo service slapd restart
Check your host's logs (/var/log/syslog) to see if the server has started properly.
Репликация и TLS
If you have set up replication between servers, it is common practice to encrypt (StartTLS) the replication traffic to prevent evesdropping. This is distinct from using encryption with authentication as we did above. In this section we will build on that TLS-authentication work.
The assumption here is that you have set up replication between Provider and Consumer according to Replication and have configured TLS for authentication on the Provider by following TLS.
As previously stated, the objective (for us) with replication is high availablity for the LDAP service. Since we have TLS for authentication on the Provider we will require the same on the Consumer. In addition to this, however, we want to encrypt replication traffic. What remains to be done is to create a key and certificate for the Consumer and then configure accordingly. We will generate the key/certificate on the Provider, to avoid having to create another CA certificate, and then transfer the necessary material over to the Consumer.
On the Provider,
Create a holding directory (which will be used for the eventual transfer) and then the Consumer's private key:
mkdir ldap02-ssl cd ldap02-ssl sudo certtool --generate-privkey \ --bits 1024 \ --outfile ldap02_slapd_key.pem
Create an info file, ldap02.info, for the Consumer server, adjusting it's values accordingly:
organization = Example Company cn = ldap02.example.com tls_www_server encryption_key signing_key expiration_days = 3650
Create the Consumer's certificate:
sudo certtool --generate-certificate \ --load-privkey ldap02_slapd_key.pem \ --load-ca-certificate /etc/ssl/certs/cacert.pem \ --load-ca-privkey /etc/ssl/private/cakey.pem \ --template ldap02.info \ --outfile ldap02_slapd_cert.pem
Get a copy of the CA certificate:
cp /etc/ssl/certs/cacert.pem .
We're done. Now transfer the ldap02-ssl directory to the Consumer. Here we use scp (adjust accordingly):
cd .. scp -r ldap02-ssl user@consumer:
On the Consumer,
Configure TLS authentication:
sudo apt-get install ssl-cert sudo adduser openldap ssl-cert sudo cp ldap02_slapd_cert.pem cacert.pem /etc/ssl/certs sudo cp ldap02_slapd_key.pem /etc/ssl/private sudo chgrp ssl-cert /etc/ssl/private/ldap02_slapd_key.pem sudo chmod g+r /etc/ssl/private/ldap02_slapd_key.pem sudo chmod o-r /etc/ssl/private/ldap02_slapd_key.pem
Create the file /etc/ssl/certinfo.ldif with the following contents (adjust accordingly):
dn: cn=config add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/ldap02_slapd_cert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/ldap02_slapd_key.pem
Configure the slapd-config database:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
Configure /etc/default/slapd as on the Provider (SLAPD_SERVICES).
On the Consumer,
Configure TLS for Consumer-side replication. Modify the existing olcSyncrepl attribute by tacking on some TLS options. In so doing, we will see, for the first time, how to change an attribute's value(s).
Create the file consumer_sync_tls.ldif with the following contents:
dn: olcDatabase={1}hdb,cn=config replace: olcSyncRepl olcSyncRepl: rid=0 provider=ldap://ldap01.example.com bindmethod=simple binddn="cn=admin,dc=example,dc=com" credentials=secret searchbase="dc=example,dc=com" logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" schemachecking=on type=refreshAndPersist retry="60 +" syncdata=accesslog starttls=critical tls_reqcert=demand
The extra options specify, respectively, that the consumer must use StartTLS and that the CA certificate is required to verify the Provider's identity. Also note the LDIF syntax for changing the values of an attribute ('replace').
Implement these changes:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f consumer_sync_tls.ldif
And restart slapd:
sudo service slapd restart
On the Provider,
Check to see that a TLS session has been established. In /var/log/syslog, providing you have 'conns'-level logging set up, you should see messages similar to:
slapd[3620]: conn=1047 fd=20 ACCEPT from IP=10.153.107.229:57922 (IP=0.0.0.0:389) slapd[3620]: conn=1047 op=0 EXT oid=1.3.6.1.4.1.1466.20037 slapd[3620]: conn=1047 op=0 STARTTLS slapd[3620]: conn=1047 op=0 RESULT oid= err=0 text= slapd[3620]: conn=1047 fd=20 TLS established tls_ssf=128 ssf=128 slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" method=128 slapd[3620]: conn=1047 op=1 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0 slapd[3620]: conn=1047 op=1 RESULT tag=97 err=0 text
Установление подлинности через LDAP
Once you have a working LDAP server, you will need to install libraries on the client that will know how and when to contact it. On Ubuntu, this has been traditionally accomplishd by installing the libnss-ldap package. This package will bring in other tools that will assist you in the configuration step. Install this package now:
sudo apt-get install libnss-ldap
You will be prompted for details of your LDAP server. If you make a mistake you can try again using:
sudo dpkg-reconfigure ldap-auth-config
The results of the dialog can be seen in /etc/ldap.conf. If your server requires options not covered in the menu edit this file accordingly.
Now configure the LDAP profile for NSS:
sudo auth-client-config -t nss -p lac_ldap
Configure the system to use LDAP for authentication:
sudo pam-auth-update
From the menu, choose LDAP and any other authentication mechanisms you need.
You should now be able to log in using LDAP-based credentials.
LDAP clients will need to refer to multiple servers if replication is in use. In /etc/ldap.conf you would have something like:
uri ldap://ldap01.example.com ldap://ldap02.example.com
The request will time out and the Consumer (ldap02) will attempt to be reached if the Provider (ldap01) becomes unresponsive.
If you are going to use LDAP to store Samba users you will need to configure the Samba server to authenticate using LDAP. See Samba and LDAP for details.
An alternative to the libnss-ldap package is the libnss-ldapd package. This, however, will bring in the nscd package which is problably not wanted. Simply remove it afterwards.
Управление пользователями и группами
The ldap-utils package comes with enough utilities to manage the directory but the long string of options needed can make them a burden to use. The ldapscripts package contains wrapper scripts to these utilities that some people find easier to use.
Install the package:
sudo apt-get install ldapscripts
Then edit the file /etc/ldapscripts/ldapscripts.conf to arrive at something similar to the following:
SERVER=localhost BINDDN='cn=admin,dc=example,dc=com' BINDPWDFILE=«/etc/ldapscripts/ldapscripts.passwd» SUFFIX='dc=example,dc=com' GSUFFIX='ou=Groups' USUFFIX='ou=People' MSUFFIX='ou=Computers' GIDSTART=10000 UIDSTART=10000 MIDSTART=10000
Now, create the ldapscripts.passwd file to allow rootDN access to the directory:
sudo sh -c «echo -n 'secret' > /etc/ldapscripts/ldapscripts.passwd» sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
Replace “secret” with the actual password for your database's rootDN user.
The scripts are now ready to help manage your directory. Here are some examples of how to use them:
Create a new user:
sudo ldapadduser george example
This will create a user with uid george and set the user's primary group (gid) to example
Change a user's password:
sudo ldapsetpasswd george Changing password for user uid=george,ou=People,dc=example,dc=com New Password: New Password (verify):
Delete a user:
sudo ldapdeleteuser george
Add a group:
sudo ldapaddgroup qa
Delete a group:
sudo ldapdeletegroup qa
Add a user to a group:
sudo ldapaddusertogroup george qa
You should now see a memberUid attribute for the qa group with a value of george.
Remove a user from a group:
sudo ldapdeleteuserfromgroup george qa
The memberUid attribute should now be removed from the qa group.
The ldapmodifyuser script allows you to add, remove, or replace a user's attributes. The script uses the same syntax as the ldapmodify utility. For example:
sudo ldapmodifyuser george # About to modify the following entry : dn: uid=george,ou=People,dc=example,dc=com objectClass: account objectClass: posixAccount cn: george uid: george uidNumber: 1001 gidNumber: 1001 homeDirectory: /home/george loginShell: /bin/bash gecos: george description: User account userPassword:: e1NTSEF9eXFsTFcyWlhwWkF1eGUybVdFWHZKRzJVMjFTSG9vcHk=
# Enter your modifications here, end with CTRL-D. dn: uid=george,ou=People,dc=example,dc=com replace: gecos gecos: George Carlin
The user's gecos should now be “George Carlin”.
A nice feature of ldapscripts is the template system. Templates allow you to customize the attributes of user, group, and machine objectes. For example, to enable the user template edit /etc/ldapscripts/ldapscripts.conf changing:
UTEMPLATE="/etc/ldapscripts/ldapadduser.template"
There are sample templates in the /etc/ldapscripts directory. Copy or rename the ldapadduser.template.sample file to /etc/ldapscripts/ldapadduser.template:
sudo cp /usr/share/doc/ldapscripts/examples/ldapadduser.template.sample \ /etc/ldapscripts/ldapadduser.template
Edit the new template to add the desired attributes. The following will create new users with an objectClass of inetOrgPerson:
dn: uid=<user>,<usuffix>,<suffix> objectClass: inetOrgPerson objectClass: posixAccount cn: <user> sn: <ask> uid: <user> uidNumber: <uid> gidNumber: <gid> homeDirectory: <home> loginShell: <shell> gecos: <user> description: User account title: Employee
Notice the <ask> option used for the sn attribute. This will make ldapadduser prompt you for it's value.
There are utilities in the package that were not covered here. Here is a complete list:
ldaprenamemachine ldapadduser ldapdeleteuserfromgroup ldapfinger ldapid ldapgid ldapmodifyuser ldaprenameuser lsldap ldapaddusertogroup ldapsetpasswd ldapinit ldapaddgroup ldapdeletegroup ldapmodifygroup ldapdeletemachine ldaprenamegroup ldapaddmachine ldapmodifymachine ldapsetprimarygroup ldapdeleteuser
Резервное копирование и восстановление
Now we have ldap running just the way we want, it is time to ensure we can save all of our work and restore it as needed.
What we need is a way to backup the ldap database(s), specifically the backend (cn=config) and frontend (dc=example,dc=com). If we are going to backup those databases into, say, /export/backup, we could use slapcat as shown in the following script, called /usr/local/bin/ldapbackup:
#!/bin/bash
BACKUP_PATH=/export/backup SLAPCAT=/usr/sbin/slapcat
nice ${SLAPCAT} -n 0 > ${BACKUP_PATH}/config.ldif nice ${SLAPCAT} -n 1 > ${BACKUP_PATH}/example.com.ldif nice ${SLAPCAT} -n 2 > ${BACKUP_PATH}/access.ldif chmod 640 ${BACKUP_PATH}/*.ldif
These files are uncompressed text files containing everything in your ldap databases including the tree layout, usernames, and every password. So, you might want to consider making /export/backup an encrypted partition and even having the script encrypt those files as it creates them. Ideally you should do both, but that depends on your security requirements.
Then, it is just a matter of having a cron script to run this program as often as we feel comfortable with. For many, once a day suffices. For others, more often is required. Here is an example of a cron script called /etc/cron.d/ldapbackup that is run every night at 22:45h:
MAILTO=backup-emails@domain.com 45 22 * * * root /usr/local/bin/ldapbackup
Now the files are created, they should be copied to a backup server.
Assuming we did a fresh reinstall of ldap, the restore process could be something like this:
sudo service slapd stop sudo mkdir /var/lib/ldap/accesslog sudo slapadd -F /etc/ldap/slapd.d -n 0 -l /export/backup/config.ldif sudo slapadd -F /etc/ldap/slapd.d -n 1 -l /export/backup/domain.com.ldif sudo slapadd -F /etc/ldap/slapd.d -n 2 -l /export/backup/access.ldif sudo chown -R openldap:openldap /etc/ldap/slapd.d/ sudo chown -R openldap:openldap /var/lib/ldap/ sudo service slapd start
Ссылки
The primary resource is the upstream documentation: www.openldap.org
There are many man pages that come with the slapd package. Here are some important ones, especially considering the material presented in this guide:
slapd slapd-config slapd.access slapo-syncprov
Other man pages:
auth-client-config pam-auth-update
Zytrax's LDAP for Rocket Scientists; a less pedantic but comprehensive treatment of LDAP
A Ubuntu community OpenLDAP wiki page has a collection of notes
O'Reilly's LDAP System Administration (textbook; 2003)
Packt's Mastering OpenLDAP (textbook; 2007)