Содержание
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:///"
Сужаем права на владение и доступ:
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
Перегружаем OpenLDAP:
sudo service slapd restart
Проверьте ваши системные журналы (/var/log/syslog) чтобы убедиться что сервер запустился правильно.
Репликация и TLS
Если вы настроили репликацию между серверами, существует общая практика шифровать (StartTLS) трафик репликации для исключения прослушивания. Лучше всего использовать шифрование с аутентификацией как мы делали выше. В этой секции мы будем основываться на проделанной работе по TLS-аутентификации.
Здесь предполагается, что вы настроили репликацию между Поставщиком и Провайдером в соответствии с секцией Репликация и настроили TLS для аутентификации на Поставщике следуя инструкциям секции TLS.
Как утверждалось ранее, цель (для нас) репликации - это высокая доступность сервиса LDAP. Поскольку мы имеем TLS для аутентификации на Поставщике, мы нуждаемся в этом и на Потребителе. Однако в дополнение к этому мы хотим зашифровать трафик репликации. Что остается сделать, так это создать ключ и сертификат для Потребителя и затем провести соответствующую настройку. Мы создадим ключ и сертификат на Поставщике для предотвращения создания другого Центра сертификатов, а затем перенесем необходимые данные на Потребителя.
На Поставщике:
Создаем промежуточный каталог (который будет использоваться для переноса) и затем секретный ключ Потребителя:
mkdir ldap02-ssl cd ldap02-ssl sudo certtool --generate-privkey \ --bits 1024 \ --outfile ldap02_slapd_key.pem
Создаем информационный файл ldap02.info для сервера Потребителя; подставляйте свои соответствующие значения:
organization = Example Company cn = ldap02.example.com tls_www_server encryption_key signing_key expiration_days = 3650
Создаем сертификат Потребителя:
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
Получаем копию сертификата CA:
cp /etc/ssl/certs/cacert.pem .
Все готово. Теперь переносим каталог ldap02-ssl на сервер Потребителя. Здесь мы использовали scp (данные изменяем соответственно):
cd .. scp -r ldap02-ssl user@consumer:
На Потребителе:
Настраиваем TLS аутентификацию:
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
Создаем файл /etc/ssl/certinfo.ldif со следующим содержимым (исправляйте соответственно):
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
Настраиваем базу slapd-config:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f certinfo.ldif
Настраиваем /etc/default/slapd как на Поставщике (SLAPD_SERVICES).
На Потребителе:
Настраиваем TLS для репликации на стороне Потребителя. Изменяем существующий атрибут olcSyncrepl присоединяя некоторые TLS опции. Делая это, мы увидим в первый раз как изменять значения атрибутов.
Создаем файл consumer_sync_tls.ldif со следующим содержимым:
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
Дополнительные опции определяют, соответственно, что Потребитель должен использовать StartTLS и что CA сертификат требуется для идентификации Поставщика. Также обратите внимание на LDIF синтаксис для изменения значений атрибута ('replace').
Применяем эти изменения:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f consumer_sync_tls.ldif
И перестартуем slapd:
sudo service slapd restart
На Постащике:
Проверяем, что TLS сессия устанавливается. В /var/log/syslog, предполагая что вы настроили уровень журналирования 'conns', вы сможете увидеть подобные записи:
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
Поскольку вы имеете работающий LDAP сервер, вам потребуется установить библиотеки на клиенте, которые будут знать как и когда к нему (серверу) подсоединяться. На Ubuntu это традиционно производится установкой пакета libnss-ldap. Этот пакет добавит другие инструменты, которые будут помогать вам на шаге настройки. Теперь установим этот пакет:
sudo apt-get install libnss-ldap
У вас будут запрошены подробности по вашему LDAP серверу. Если вы сделаете ошибку, вы можете попробовать снова используя:
sudo dpkg-reconfigure ldap-auth-config
Результат диалога можно увидеть в /etc/ldap.conf. Если ваш сервер требует опции, недоступные в меню, редактируйте этот файл самостоятельно.
Теперь настраиваем LDAP профиль для NSS:
sudo auth-client-config -t nss -p lac_ldap
Настраиваем систему на использование LDAP для аутентификации:
sudo pam-auth-update
Из меню, выберите LDAP и любые другие механизмы аутентификации, которые вам требуются.
Теперь вы имеете возможность входить в систему, используя учетные записи на основе LDAP.
Клиентам LDAP потребуются ссылки на несколько серверов, если используется репликация. В /etc/ldap.conf вам надо иметь что-то похожее:
uri ldap://ldap01.example.com ldap://ldap02.example.com
Запросы имеют таймаут и будет попытка обратиться к Потребителю (ldap02), если Поставщик (ldap01) станет недоступным.
Если вы собираетесь использовать LDAP для хранения пользователей SAMBA, вам потребуется настроить SAMBA сервер на использование LDAP. Смотрите Samba и LDAP для подробностей.
Управление пользователями и группами
Пакет ldap-utils поставляется с достаточным количеством утилит для управления каталогами, но необходимость использовать длинные строки с опциями делает их применение обременительным. Пакет ldapscripts содержит оберточные сценарии (wrapper scripts) для этих утилит, которые некоторые находят более удобными в использовании.
Устанавливаем пакет:
sudo apt-get install ldapscripts
Затем редактируем файл /etc/ldapscripts/ldapscripts.conf для получения нечто похожего на следующее:
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
Теперь создаем файл ldapscripts.passwd чтобы разрешить rootDN доступ к каталогу:
sudo sh -c "echo -n 'secret' > /etc/ldapscripts/ldapscripts.passwd" sudo chmod 400 /etc/ldapscripts/ldapscripts.passwd
Сценарии теперь готовы помогать в управлении вашим каталогом. Здесь несколько примеров как их использовать:
Создать нового пользователя:
sudo ldapadduser george example
Это создаст пользователя с uid george и установит gid example в качестве первичной пользовательской группы.
Изменить пароль пользователя:
sudo ldapsetpasswd george Changing password for user uid=george,ou=People,dc=example,dc=com New Password: New Password (verify):
Удалить пользователя:
sudo ldapdeleteuser george
Добавить группу:
sudo ldapaddgroup qa
Удалить группу:
sudo ldapdeletegroup qa
Добавить пользователя к группе:
sudo ldapaddusertogroup george qa
Вы теперь можете увидеть атрибут memberUid для группы qa со значением для george.
Удалить пользователя из группы:
sudo ldapdeleteuserfromgroup george qa
Атрибут memberUid теперь будет удален из группы qa.
Сценарий ldapmodifyuser позволяет вам добавлять, удалять или заменять пользовательские атрибуты. Сценарий исползует тот же синтаксис, что и утилита ldapmodify. Например:
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
Поле имени пользователя (gecos) теперь "George Carlin".
Приятной особенностью ldapscripts является система шаблонов. Шаблоны позволяют вам настраивать атрибуты пользователей, групп и компьютерных объектов. Например, чтобы разрешить шаблон пользователей, отредактируйте /etc/ldapscripts/ldapscripts.conf, изменив:
UTEMPLATE="/etc/ldapscripts/ldapadduser.template"
В каталоге /etc/ldapscripts находятся шаблоны sample. Скопируйте или переименуйте файл ldapadduser.template.sample в /etc/ldapscripts/ldapadduser.template:
sudo cp /usr/share/doc/ldapscripts/examples/ldapadduser.template.sample \ /etc/ldapscripts/ldapadduser.template
Отредактируйте новый шаблон для добавления желаемых атрибутов. Следующее создаст новых пользователей с objectClass 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
Отметьте опцию <ask>, использованную для атрибута sn. Это создает запрос при использовании ldapadduser для его значения.
Есть утилиты из пакета, которые здесь не рассматривались. Вот их полный список:
ldaprenamemachine
ldapadduser
ldapdeleteuserfromgroup
ldapfinger
ldapid
ldapgid
ldapmodifyuser
ldaprenameuser
lsldap
ldapaddusertogroup
ldapsetpasswd
ldapinit
ldapaddgroup
ldapdeletegroup
ldapmodifygroup
ldapdeletemachine
ldaprenamegroup
ldapaddmachine
ldapmodifymachine
ldapsetprimarygroup
ldapdeleteuser
Резервное копирование и восстановление
Теперь у нас ldap работает именно так, как нам хотелось и настало время убедиться, что мы можем сохранить всю нашу работу и восстановить ее при необходимости.
Что нам требуется, это способ сделать резервные копии для базы данных ldap, специфичные для данных баз заднего (cn=config) и переднего плана (dc=example,dc=com). Если мы собираемся сохранить эти базы, скажем, в /export/backup, мы можем использовать slapcat как показано в следующем сценарии с именем /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
Затем имеет смысл создать сценарии cron для запуска этой программы настолько часто, насколько вам будет комфортно. Для большинства достаточно одного раза в день. Для некоторых требуется чаще. Здесь пример сценария cron, названного /etc/cron.d/ldapbackup, который срабатывает каждую ночь в 22:45:
MAILTO=backup-emails@domain.com 45 22 * * * root /usr/local/bin/ldapbackup
Теперь файлы созданы и они могут быть скопированы на резервный сервер.
Предположим мы сделали переустановку ldap; процесс восстановления будет подобен следующему:
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
Ссылки
- Первый ресурс это актуальная документация: www.openldap.org.
- Существует много страниц руководств пакета slapd. Здесь наиболее важные, особенно в плане рассматриваемых в этом руководстве материалов:
- Другие руководства:
- LDAP for Rocket Scientists от Zytrax; руководство менее педантичное, но содержащее всесторонне рассмотренный LDAP.
- OpenLDAP wiki страница сообщества Ubuntu имеет коллекцию заметок.
- LDAP System Administration от O'Reilly (текст, 2003)
- Mastering OpenLDAP от Packt (текст, 2007)