четверг, 25 октября 2012 г.

Установка и настройка openLDAP 2.4 в CentOS 6

Сервер каталогов играет важную роль в IT сфере, позволяя связать многие сервисы единой базой. На примере openLDAP версии 2.4 и CentOS 6 будет показана базовая настройка и установка сервера каталогов.

 

Базовая настройка openLDAP

Начиная с версии 2.3.х openLDAP переходит на использование механизма динамической конфигурации (slapd.d) вместо slapd.conf. Хотя даже в последних версия все еще можно использовать старый механизм, все же лучше использовать новый по ряду причин, на которых не буду останавливаться. В качестве дистрибутива был выбран CentOS 6.
Итак, приступим.Для начала нам необходимо установить следующие пакеты:

[root@server]# yum install openldap openldap-clients openldap-servers

Далее сгенерируем пароль для администратора командой slappasswd:

[root@server]# slappasswd -h {SSHA}
New password:
Re-enter new password:
{SSHA}Hc3knTS0np8GVOVAK4ng9RqBiRBDnNID

Заметка

Пароля нужно будет два — один для администратора базы openLDAP(с помощью этого аккаунта можно добавлять данные в базу) лежит в olcDatabase={2}bdb.ldif, второй для "суперпользователя " сервиса openLDAP(с помощью только этого аккаунта можно динамически настраивать openLDAP) лежит в olcDatabase={0}config.ldif. Если попытаться динамически изменить конфигурацию работающего openLDAP от имени администратора базы, то будет ошибка:
ldap_add: Insufficient access (50)

Далее в параметр olcRootPW файла /etc/openldap/cn=config/olcDatabase={2}bdb.ldif впишем сгенерированный hash:

olcRootPW: {SSHA}Hc3knTS0np8GVOVAK4ng9RqBiRBDnNID

Пароль администратора в файле /etc/openldap/cn=config/olcDatabase={0}config.ldif задается таким же способом. Пароли могут(даже должны) отличаться ;)
Имена администраторов задаются параметром olcRootDN. По-умолчанию, в файлах cn=config/olcDatabase={0}config.ldif и cn=config/olcDatabase={2}bdb.ldif заданы cn=config и cn=Manager,dc=mydomain,dc=com соответственно. Их можно поменять либо при первоначальной настройке ручной правкой этих файлов либо в процессе эксплуатации сервера openLDAP, например, создав RootDN.ldif с таким содержимым:

dn: olcDatabase={2}bdb, cn=config
chahgetype: modify
replace: olcRootDN
olcRootDN: cn=administrator,dc=example,dc=net
[root@server]# ldapadd -x -W -D cn=config -f RootDN.ldif
Enter LDAP Password:
modifying entry "olcDatabase={2}bdb,cn=config

Теперь настроим базовый домен. В файлах /etc/openldap/cn=config/olcDatabase={2}bdb.ldif поменяем "mydomain.com" на свой домен "example.net":

[root@server]# vim /etc/openldap/slapd.d/cn\=config/olcDatabase\={2\}bdb.ldif
:%s/dc=my-domain,dc=com/dc=example,dc=net/g

Выполним команду updatedb.
Скопируем файл DB_CONFIG(бэкенд openLDAP берет большинство своих настроек и параметров именно здесь):

[root@server]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG

где /var/lib/ldap/ путь по умолчанию к базе openLDAP, задаваемый в файле olcDatabase={2}bdb.ldif. Проверим права на каталог и содержимое, и выставим права в случае необходимости:

[root@server]# ls -l
[root@server]# chown -Rf ldap:ldap /var/lib/ldap/ /var/lib/ldap/DB_CONFIG

Теперь проверим файлы на "синтаксическую корректность":

[root@server]# slaptest -u
config file testing succeeded

Строка "config file testing succeeded" говорит об корректности конфига. Запустим демона ldap и добавим его в автозагрузку:

[root@server]# /etc/init.d/slapd start
[root@server]# chkconfig slapd on

Теперь у нас есть работающий, однако пустой сервер openLDAP. Для полноценной работы добавим нужные данные в базу. Наполним нашу базу первой информацией, для этого создадим файл base.ldif с таким содержимым:

dn: dc=example,dc=net
objectClass: dcObject
objectClass: organization
o: example
dc: example

dn: ou=People,dc=example,dc=net
objectClass: top
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=example,dc=net
objectClass: top
objectClass: organizationalUnit
ou: Groups

Теперь добавим эти данные в базу:

[root@server]# ldapadd -x -W -D ”cn=Manager,dc=example,dc=net” -f base.ldif

Заметка

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

#ldapadd -Y EXTERNAL -H ldapi:// -f example.ldif

где example.ldif — это файл с настройками openLDAP в формате ldif или файл для добавления/изменения информации в базу openLDAP. Для возможности использования IPC соединения(ldapi) в RHEL/CentOS/SL в файле /etc/sysconfig/ldap раскомментировать строку "SLAPD_LDAPI=yes"(в Debian в /etc/default/ldap в параметре SLAPD_SERVICES добавить "ldapi://").
IPC позволяет использовать встроенные механизмы SASL для аутентификации. Для добавления информации в базу через IPC необходимо наличие параметра olcAccess в файле olcDatabase={2}bdb.ldif следующего вида:

olcAccess: to * by dn.exact=gidnumber=0+uidnumber=0,cn=peerced,cn=external,cn=auth manage by * break

Для использования IPC нужен пакет cyrus-sasl-ntlm.

Настроим логи. Все свои логи openLDAP ведёт через syslog(LOCAL4), поэтому для отдельно лог-файла необходимо внести такие изменения в файл /etc/rsyslog.conf(в CentOS используется именно rsyslog):

local4.* /var/log/slapd.log

и создать /var/log/slapd.log. Уровень логирования настраивается параметром olcLogLevel. Ну и напоследок я бы убрал возможность анонимного доступа к базе openLDAP с помощью olcDisallows: bind_anon в файле cn=config.ldif.

Управление правами

Мы рассмотрим небольшую, но важную часть управления правами openLDAP, более подробное описание дано в официальном руководстве.
По-умолчанию, права к базе имеют следующий вид: to * by * read , т.е все имеют право на чтение(кроме администратора, который всегда имеет полные права). Права доступа задаются параметром olcAccess. Рассмотрим пример добавления простого правила:

dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcAccess
olcAccess: to attrs=userPassword by anonymous auth by self write by * none

это правило раздаёт права доступа к атрибуту userPassword - анонимы должны пройти аутентификацию; пользователь имеет доступ на чтение и запись только своего атрибута; остальные не имеют доступа к этому атрибуту. Порядок перечисления кому какой доступ очень важен, потому как в цепочке срабатывает первое правило, удовлетворяющее критерию(поменяв местами правила by self write и by * none вы по сути лишитесь правила by self write, что не даст возможность пользователям доступа к своему атрибуту).
Также не менее важен порядок параметров olcAccess, потому что тут аналогично срабатывает первое правило по цепочке, удовлетворяющее некоему критерию. В конфигурационных файлах параметры olcAccess пронумерованы и имеют такой вид:

...
olcAccess: {0}to...
olcAccess: {1}to...
olcAccess: {2}to...
...

Для изменения правил используйте конструкцию вот такого вида(например, правила под номером один):

dn: olcDatabase={2}bdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {1}
-
add: olcAccess
olcAccess: {1}to...

Если вы будете добавлять свои правила без указания номера, то они будут добавляться в самый конец цепочки. Так что будьте внимательны.
Следует отметить ещё одну важную деталь - после добавления хотя бы одного правила, права доступа по-умолчанию меняюся на противоположные - после выполнения всех правил действует политика запрета, т.е. to * by * none вместо to * by * read, как было сказано вначале. Поэтому если пользователь не попал не под одно правило, то он не имеет доступа вообще.


Подключение схем

По умолчанию, после установки, openLDAP сконфигурирован с минимальными настройками для запуска демона slapd. В CentOS по умолчанию уже создана минимальная конфигурация с подключенными схемами, однако не все схемы там присутствуют. Ниже будет рассмотрен пример добавления схемы Samba. Для других схем применимы те же самые действия.
В openLDAP теперь схемы подключаются в виде файлов формата ldif. Такого файла для схемы Samba пока не существует(да и для многих схем такая же ситуация), поэтому конвертируем нашу схему в нужный нам формат.

Итак, начнем. Создадим файл с именем scheme-converter.conf следующего содержания:

include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/duaconf.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/collective.schema
include /etc/openldap/schema/samba.schema

Порядок "инклюдов" важен, поэтому лучше перечислять их так, как они перечислены в /etc/openldap/slapd.d/cn=config/cn=scheme/, а в конце добавить нужную строку со схемой самбы.
Создадим каталог /tmp/schema_2_ldif и конвертируем схемы командой slaptest:

[root@server]# mkdir /tmp/schema_2_ldif
[root@server]# slaptest -F /путь/к/scheme_converter.conf -f /tmp/scheme_2_ldif

в результате получим каталог /tmp/scheme_2_ldif/slapd.d с нужной нам схемой в формате ldif. Добавляем в конфиг нашу схему:

[root@server]# ldapadd -x -W -D cn=config -f /путь/к/samba.ldif

Заметка

Добавить схему можно еще одним способом. Для этого необходимо остановить openLDAP:

[root@server]# service slapd stop
[root@server]# slapadd -n 0 -l /путь/к/samba.ldif

ВАЖНО!

После конвертации схем из формата .schema в формат .ldif необходимо заменить строки в уже получившихся файлах-схемах *.ldif подобным образом:

dn: cn={№}samba → dn: cn=samba,cn=schema,cn=config
cn: {№}samba → cn: samba

а также удалить все строки, начинающиеся со строки "structuralObjectClass"(находятся в самом конце файла схемы):

structuralObjectClass: olcSchemaConfig
entryUUID: 01fc8e14-9a61-1031-95a2-29c9a128f6cd
creatorsName: cn=config
createTimestamp: 20120924065836Z
entryCSN: 20121015070053.115456Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20121015070053Z

Настройка TLS в openLDAP

Для использования TLS необходимо добавить два параметра в файл настроек базы olcDataBase={2}bdb.ldif:

olcTLSVerifyClient: never
olcTLSCipherSuite: TLSv1+RSA:!EXPORT:!NULL
olcTLSCertificateFile: /etc/openldap/certs/slapdcert.pem
olcTLSCertificateKeyFile: /etc/openldap/certs/slapdkey.pem
где olcTLSCipherSuite означает, что для шифрования будут использоваться только шифры TLSv1, использующие алгоритм RSA. !EXPORT означает, что не будут использоваться шифры, экспортирующие свой SSF; !NULL означает, что не будут использоваться шифры, которые передают данные открытым текстом (только аутентификация шифруется).

Теперь создадим эти сертификаты:

[root@server]# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out /etc/openldap/certs/slapdcert.pem -keyout /etc/openldap/certs/slapdkey.pem

Раздадим права на созданные файлы:

[root@server]# chown -Rf root:ldap /etc/openldap/certs/*cert.pem
[root@server]# chmod -Rf 750 /etc/openldap/certs/*key.pem

Теперь если вам нужен ещё и SSL openLDAP, то его можно включить в /etc/sysconfig/ldap(для TLS этого не требуется):

SLAPD_LDAPS=yes

Теперь можно перезапустить демон openLDAP и он сможет TLS соединения.

Подключение модулей динамической загрузки

Если подключение проходит впервые, то необходимо создать конфигурационный файл. Для этого создаем module.ldif:

dn: cn=module, cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/openldap
olcModuleLoad: syncprov.la

Если конфигурационный файл cn=module{0} уже имеется(номер в скобках может отличаться), тогда создаем файлик addmodule.ldif:

dn: cn=module{0}, cn=config
changetype: add
add: olcModuleLoad
olcModuleLoad: syncprov.la

и добавляем это динамически в конфиг openLDAP:

[root@server]# ldapadd -x -W -D cn=config -f addmodule.ldif
Enter LDAP Password:
adding new entry "cn=module,cn=config"


Настройка репликации(delta-syncrepl)

Репликация - это процесс копирования данных из одного источника данных в другой (см. wiki). В терминах openLDAP эти источники именуются как поставщик(provider) и потребитель(consumer). Мы рассмотри случай поставщик-потребитель. Стоит заметить, что один и тот же сервер может быть и поставщиком и потребителем одновременно. Ну что ж, приступим.

Provider
Начнём с настройки поставщика как наиболее ёмкого по настройкам.
Создадим нового пользователя, от имени которого будет осуществляться доступ к данным поставщика, и добавим его в базу

replicator.ldif:
dn: cn=replicator, dc=example, dc=net
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: replicator
userPassword: {SSHA}U3cVnX/lZupPW85F5mFj/UPemcR0uTba
[root@server]# ldapadd -x -W -D cn=administrator,dc=example,dc=net -f replicator.ldif
Enter LDAP Password:
adding new entry "cn=replicator,dc=example,dc=net"

Добавим индексацию следующих записей

index.ldif:
dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN eq
-
add: olcDbIndex
olcDbIndex: entryUUID eq
[root@server]# ldapadd -x -W -D cn=config -f index.ldif
Enter LDAP Password:
modifying entry "olcDatabase={2}bdb,cn=config
где entryCSN - это индикатор состояния синхронизации содержимого поставщика, а entryUUID - уникальный идентификатор записи в протоколе LDAP Sync. Снова обращаю ваше внимание, что для изменения настроек используется аккаунт из olcDatabase={0}config.ldif, а для внесения данных в базу - аккаунт из olcDatabase={0}bdb.ldif.

Теперь нам необходимо сделать загрузку модуля syncprov и настроить этот overlay

module.ldif:
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/openldap
olcModuleLoad: syncprov.la

syncprov.ldif:
dn: olcOverlay=syncprov,olcDatabase={2}bdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 1000 100

Consumer
Теперь настала очередь настройки потребителя. Всё, что нам необходимо - это добавить индексы для известных нам записей(entryUUID и entryCSN) и воспользоваться непосредственно механизмом репликации syncrepl

index.ldif:
dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: entryCSN eq
-
add: olcDbIndex
olcDbIndex: entryUUID eq

syncrepl.ldif:
dn: olcDatabase={2}bdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=0 provider=ldap://provider_ip_or_name bindmethod=simple binddn="cn=replicator,dc=example,dc=net" credentials=SECRET searchbase="dc=example,dc=net" schemachecking=on type=refreshAndPersist retry="60 +"
-
add: olcUpdateRef
olcUpdateRef: ldap://provider_ip_or_name
где olcUpdateRef это ссылка на поставщика, выдаваемая клиенту(потребителя) при попытке изменить данные на потребителе.

Для использования accesslog в репликации, можете воспользоваться неплохой статьёй. Руководство администратора в оригинале(англ. язык) находится здесь. Вот тут находится перевод на русский этого руководства, да и вообще на этом сайте много разных переводов, связанных с openLDAP. Наиболее полная справочная информация по параметрам в файлах конфигурации находится конечно же в man slapd-config ;)

25 комментариев:

  1. Спасибо за отличную статью!

    ОтветитьУдалить
  2. Доброго времени суток!

    Спасибо за супер понятную статью!!!

    У меня возник вопрос: Поднял openLDAP по Вашей статье, все ОК, работает. Но вот сейчас озадачился наложением политик для паролей, т.к. планируется, что пользователи сами будут менять пароли. Хочется, чтоб при изменении пораля, проверялся формат, например от 10-ти символов, может состоять как из латинских букв, как маленьких, так и больших + цифры. Подскажите, как подключить?

    ОтветитьУдалить
    Ответы
    1. Рад, что вам пригодилась статья. По поводу политик, думаю вам нужно посмотреть сюда http://www.zytrax.com/books/ldap/ch6/ppolicy.html. В линуксах есть ещё пакет cracklib, но его можно, например, прикрутить к самбе, а к openldap напрямую не получится.

      Удалить
    2. Здравствуйте! Подскажите, сейчас изучил мануал по Вашей ссылке (http://www.zytrax.com/books/ldap/ch6/ppolicy.html), там есть атрибут: pwdCheckModule. В нем можно загрузить модуль check_password.so
      Я применил наложение, но как и откуда будет тянутся данный модуль так и не понят! Может у Вас есть опят или знаете как и откуда его прицепить?

      Удалить
    3. сегодня осмотрел в оф. документацию и нашёл интересный раздел http://www.openldap.org/doc/admin24/overlays.html#Password Policies . я думаю это то, что вам нужно. к сожалению, я глубоко не копал, но уверен, что сложностей у вас это не вызовет.

      Удалить
    4. Спасибо за статью. Реально помогло.

      Удалить
  3. По поводу TLS - только после того, как сказал
    chown -Rf root:ldap /etc/openldap/certs/$cert.pem

    - только после этого сумел из java подлключиться по TLS (используя примеры GetAuthenticated.java и StartTLS.java из http://www.novell.com/documentation/developer/samplecode/jldap_sample/.

    То ли в статье ошибка, то ли я чего-то недопонял.

    Спасибо за статью, очень помогло!

    ОтветитьУдалить
  4. Извините, не то вставил в предыдущем комментарии.
    я хотел сказал, что мне пришлось ВМЕСТО
    chown -Rf root:ldap /etc/openldap/certs/$cert.pem
    сказать
    chown -R root:ldap /etc/openldap/certs/*

    ОтветитьУдалить
    Ответы
    1. Спасибо, что указали. Там действильно ошибка. Необходимо *cert.pem вместо $cert.pem

      Удалить
  5. Доброго времени суток!
    Посылаю лучи добра за отличную статью.

    Только небольшой нюанс. В команде генерации схем
    [root@server]# slaptest -F /путь/к/scheme_converter.conf -f /tmp/scheme_2_ldif
    аргументы должны быть в обратном порядке. Т.е.

    slaptest -f /путь/к/scheme_converter.conf -F /tmp/scheme_2_ldif

    ОтветитьУдалить
  6. Добрый день!
    Спасибо автору за статью.
    У меня стоит задача сделать контроллер домена(ОС одинаковая на серве и на клиентских Сentos 6 x64) для 20-ти машин. Реально ли сделать с помощью лдап и самбы, чтобы юзеры этих 20ти машин могли логиниться на любую под своей учеткой и подтягивался их профиль? Если нет, то какой остается вариант? Спасибо.

    ОтветитьУдалить
    Ответы
    1. Конечно, можно! Вы создаете домен NT с помощью связки samba3+ldap и настраивает перемещаемые профили. Но учтите, что у вас будут отсутствовать групповые политики. Есть ещё вариант использовать samba4, которая умеет работать как полноценный MS AD.

      Удалить
    2. Вот ссылка из моего блога для создания контроллера http://z1kk0.blogspot.ru/2012/11/samba-openldap-tls.html?m=1

      Удалить
  7. Имя каталога /etc/openldap/cn=config надо заменить на /etc/openldap/slapd.d/cn=config
    CentOS 6.5 ami, OpenLDAP 2.4.39-8.el6.x86_64

    ОтветитьУдалить
  8. Непонятно, зачем выполнять команду updatedb?
    Для того, чтобы "locate DB_CONFIG" нашел /usr/share/openldap-servers/DB_CONFIG.example ?

    ОтветитьУдалить
  9. При редактировании файлов в /etc/openldap/slapd.d рекомендуется удалять из заголовка строку с CRC32, иначе постоянно будет вылезать надпись "550139d1 ldif_read_file: checksum error on ..."

    ОтветитьУдалить
  10. /usr/lib/openldap используется на 32-разрядной системе. На 64-разрядной - /usr/lib64/openldap

    ОтветитьУдалить
  11. Если есть правило "olcAccess: to attrs=userPassword by anonymous auth by self write by * none", то будет ли у репликатора доступ к чтению паролей?

    ОтветитьУдалить
  12. я извеняюсь но у меня вопрос открыл директорию /etc/openldap/slapd.d/cn=config в ней нет файла olcDatabase={2}bdb что делать ? и куда вписывать пароли рута и администратора ?

    ОтветитьУдалить
    Ответы
    1. Вы пробуете на Centos 6 или 7?

      Удалить
    2. у меня в директрории cn=config есть следующие файлы: olcDatabase={0}config.ldif , olcDatabase={1}monitor.ldif , cn=shema.ldif , olcDatabase={-1}frontend.ldif , olcDatabase={2}hdb.ldif и еще есть дериктория cn=shema. Версия ldap 2.4.39.-7

      Удалить