2. Установка OpenLDAP

2.1 Установка пакетов

Где работаем: ldap-srv

Прежде чем установить пакет sudo-ldap необходимо задать пароль для учетной записи root. Пакеты sudo и sudo-ldap взаимоисключающие, поэтому нужно перестраховаться, если с их установкой или работой случится беда.

#  passwd
Введите новый пароль UNIX:
Повторите ввод нового пароля UNIX:

Теперь установим все необходимые пакеты. Мы сразу устанавливаем krb5-kdc-ldap и sudo-ldap, даже несмотря на то, что настроим их позже. Идея заключается в том, чтобы сразу получить необходимые схемы наборов данных OpenLDAP.

#  apt-get install slapd ldap-utils krb5-kdc-ldap sudo-ldap

Во время установки Вам будет предложено задать некоторые настройки:

На данном этапе эти настройки не важны. Мы последовательно опишем их в дальнейшем.

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

$  dpkg --get-selections|egrep '(slapd|ldap-utils|krb5-kdc-ldap|sudo-ldap)'
krb5-kdc-ldap                                   install
ldap-utils                                      install
slapd                                           install
sudo-ldap                                       install

2.2 Инициализация конфигурации каталога

Где работаем: ldap-srv

Инициализацию конфигурации каталога мы произведём с нуля с использованием нового подхода, OLC (cn=config).

Создайте каталог для работы со службой каталогов. У нас будет много конфигурационных файлов, неплохо бы класть их в одно место:

$  mkdir ~/ldap
$  cd ~/ldap

Избавимся от установленных по-умолчанию конфигурации slapd и его базы данных:

#  service slapd stop
#  rm -rf /etc/ldap/slapd.d
#  rm -rf /var/lib/ldap

Создадим пустой каталог для нашей новой конфигурации:

#  mkdir /etc/ldap/slapd.d

Создадим файл 2.2-init-config.ldif с новой конфигурацией и запишем в него:

dn: cn=config
objectClass: olcGlobal
cn: config
olcPidFile: /var/run/slapd/slapd.pid
olcArgsFile: /var/run/slapd/slapd.args

dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage

dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema

В этом файле первым делом мы определяем корневую запись DIT (Directory Information Tree), cn=config. С помощью директив olcPidFile и olcArgsFile мы указали, куда необходимо записать ID процесса службы каталогов и аргументы его запуска соответственно.

Во втором разделе задаём служебную базу данных конфигурации cn=config. Мы так же добавили правило доступа (ACL, Access Control List), разрешающее манипулировать ей от имени пользователя root (uid=0, gid=0) с помощью механизма SASL EXTERNAL и идентификационной сущности IPC. Помните, что в конце каждого ACL, если не задан модификатор break, подразумевается наличие правила by * none . То есть остальной доступ к объекту в условии to — запрещён.

Последним разделом мы добавляем в конфигурацию контейнер для наборов схем данных.

Инициализируем конфигурацию:

#  slapadd -n 0 -F /etc/ldap/slapd.d -l 2.2-init-config.ldif
_#################### 100.00% eta   none elapsed            none fast!
Closing DB...

Модификатор -n 0 говорит о том, что мы добавляем данные в базу данных с индексом 0, который зарезервирован для cn=config.

Проверим, всё ли в порядке с нашей конфигурацией:

#  slaptest -uF /etc/ldap/slapd.d
config file testing succeeded

Поправим права доступа, разрешив пользователю openldap заправлять в каталоге /etc/ldap/slapd.d:

#  chown -R openldap:openldap /etc/ldap/slapd.d
#  chmod 750 /etc/ldap/slapd.d

2.3 Запуск службы каталогов

Где работаем: ldap-srv

Разрешим нашей службе каталогов использовать только IPv4. Для этого установим  SLAPD_OPTIONS="-4" в файле /etc/default/slapd. В остальном конфигурация стандартная:

SLAPD_CONF=
SLAPD_USER="openldap"
SLAPD_GROUP="openldap"
SLAPD_PIDFILE=
SLAPD_SERVICES="ldap:/// ldapi:///"
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
SLAPD_OPTIONS="-4"

Настроим rsyslog, чтобы он писал события службы каталогов в отдельный файл. Для этого достаточно добавить три строки в его конфигурацию после глобальных директив (/etc/rsyslog.conf):

$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog   # provides kernel logging support

$KLogPermitNonKernelFacility on

$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

$RepeatedMsgReduction on

$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog

$WorkDirectory /var/spool/rsyslog

$IncludeConfig /etc/rsyslog.d/*.conf

# Пишем журнал демона slapd в /var/log/slapd.log
if $programname == 'slapd' then /var/log/slapd.log
& ~

Создадим файл для журнала службы каталогов и зададим для него права доступа. Затем перезапустим rsyslog, чтобы изменения вступили в силу:

#  touch /var/log/slapd.log
#  chmod 0640 /var/log/slapd.log
#  chown syslog:adm /var/log/slapd.log
#  service rsyslog restart

Настроим logrotate для управления этим журналом. Создадим файл конфигурации /etc/logrotate.d/slapd и запишем в него:

/var/log/slapd.log {
 daily
 missingok
 rotate 7
 compress
 delaycompress
 notifempty
}

Проверим настройку logrotate:

# logrotate -df /etc/logrotate.conf

Наконец запускаем нашу службу каталогов:

#  service slapd start
 * Starting OpenLDAP slapd  [ OK ]

Заглянем в файл журнала slapd.log. Всё ли в порядке?

#  tail /var/log/slapd.log
...
slapd starting

Проверим, активен ли TCP порт 389:

$  ss -tan | grep 389
LISTEN  0 128 *:389  *:*

Убедимся, что UNIX сокет тоже активен:

$  ss -xa | grep ldap
u_str LISTEN  0 128 /var/run/slapd/ldapi  44345  * 0

Для пущей убедительности проверим текущую конфигурацию каталога с помощью ldapsearch:

#  ldapsearch -QLLL -Y EXTERNAL -H ldapi:/// -b 'cn=config' dn
dn: cn=config
dn: cn=schema,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config

Заметьте, что slapadd (из предыдущего пункта) добавил в наш каталог описание служебной базы данных frontend (в ней можно определить опции, которые будут применяться ко всем базам данных в текущей конфигурации OLC). Однако, если те же самые опции (в том числе правила ACL) определены в конкретной базе данных, то будут применяться именно они.

2.4 Подключение динамических модулей

Где работаем: ldap-srv

Для работы нам понадобится два модуля. Один — для механизма базы данных mdb. На данный момент он рассматривается как основной для нормальных баз данных и должен прийти на смену bdb и hdb. Второй модуль — monitor, для создания и динамической поддержки ветки с информацией о текущем статусе демона slapd.

Чтобы их подключить нам понадобится всего один короткий LDIF-файл и специальная запись cn=module,cn=config. Назовём файл 2.4-add-modules.ldif и запишем в него:

dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib/ldap
olcModuleLoad: back_mdb.la
olcModuleLoad: back_monitor.la

Каталог с модулями в нашем случае — /usr/lib/ldap.

Добавим наш LDIF-файл в конфигурацию:

#  ldapadd -QY EXTERNAL -H ldapi:/// -f 2.4-add-modules.ldif
adding new entry "cn=module,cn=config"

2.5 Добавление наборов схем данных

Где работаем: ldap-srv

Прежде чем добавлять наборы схем данных в каталог, необходимо подготовить наборы схем из пакетов krb5-kdc-ldap и sudo-ldap к загрузке (перевести их в формат LDIF).

В используемой нами версии Ubuntu искомые наборы схем находятся здесь:

/usr/share/doc/sudo-ldap/schema.OpenLDAP
/usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz

Скопируем их во временный каталог:

$  zcat /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz > ~/ldap/kerberos.schema
$  cp /usr/share/doc/sudo-ldap/schema.OpenLDAP ~/ldap/sudo.schema

На просторах сети был найден несложный скрипт для преобразования файлов schema в формат LDIF. Немного откорректируем его (для универсальности) и сохраним в том же каталоге ~/ldap под именем 2.5-schema-ldif.sh:

#!/bin/bash

SCHEMAD=~/ldap

tmpd=`mktemp -d`
pushd ${tmpd} >>/dev/null

echo '' > convert.dat

for schema in ${SCHEMAS} ; do
    echo include ${SCHEMAD}/${schema} >> convert.dat
done

slaptest -f convert.dat -F .

if [ $? -ne 0 ] ; then
    echo "slaptest conversion failed"
    exit 
fi

for schema in ${SCHEMAS} ; do
    fullpath=${SCHEMAD}/${schema}
    schema_name=`basename ${fullpath} .schema`
    schema_dir=`dirname ${fullpath}`
    ldif_file=${schema_name}.ldif

    find . -name *${schema_name}.ldif -exec mv '{}' ./${ldif_file} \;
    sed -i "/dn:/ c dn: cn=${schema_name},cn=schema,cn=config" ${ldif_file}
    sed -i "/cn:/ c cn: ${schema_name}" ${ldif_file}
    sed -i '/structuralObjectClass/ d' ${ldif_file}
    sed -i '/entryUUID/ d' ${ldif_file}
    sed -i '/creatorsName/ d' ${ldif_file}
    sed -i '/createTimestamp/ d' ${ldif_file}
    sed -i '/entryCSN/ d' ${ldif_file}
    sed -i '/modifiersName/ d' ${ldif_file}
    sed -i '/modifyTimestamp/ d' ${ldif_file}
    sed -i '/^ *$/d' ${ldif_file}

    mv ${ldif_file} ${schema_dir}
done

popd >>/dev/null
rm -rf $tmpd

Сделаем его исполняемым и запустим, передав через переменную SCHEMAS имена файлов конвертируемых наборов схем:

$  chmod +x 2.5-schema-ldif.sh
$  SCHEMAS='kerberos.schema sudo.schema' 2.5-schema-ldif.sh
config file testing succeeded

На выходе должны получить два набора схем данных в формате LDIF:

$  ls ~/ldap | egrep '(kerberos.ldif|sudo.ldif)'
kerberos.ldif
sudo.ldif

Переместим  их в каталог к остальным наборам схем и поправим права доступа:

#  mv ~/ldap/{kerberos.ldif,sudo.ldif} /etc/ldap/schema
#  chown root:root /etc/ldap/schema/{kerberos.ldif,sudo.ldif}
#  chmod 0644 /etc/ldap/schema/{kerberos.ldif,sudo.ldif}

Удалим не нужные больше наборы схем данных:

$  rm kerberos.schema sudo.schema

Создадим LDIF-файл с необходимыми нам наборами схем данных. Порядок их следования в файле очень важен! Атрибуты наборов схем иерархически связаны и требуют их объявления с соблюдением иерархии. Назовём файл 2.5-add-schemas.ldif и запишем в него:

include: file:///etc/ldap/schema/core.ldif
include: file:///etc/ldap/schema/cosine.ldif
include: file:///etc/ldap/schema/inetorgperson.ldif
include: file:///etc/ldap/schema/collective.ldif
include: file:///etc/ldap/schema/corba.ldif
include: file:///etc/ldap/schema/duaconf.ldif
include: file:///etc/ldap/schema/openldap.ldif
include: file:///etc/ldap/schema/dyngroup.ldif
include: file:///etc/ldap/schema/java.ldif
include: file:///etc/ldap/schema/misc.ldif
include: file:///etc/ldap/schema/nis.ldif
include: file:///etc/ldap/schema/ppolicy.ldif
include: file:///etc/ldap/schema/kerberos.ldif
include: file:///etc/ldap/schema/sudo.ldif

Последними строчками мы указали получившиеся в результате конвертации наборы схем kerberos.ldif и sudo.ldif.

Добавим наши наборы схем:

#  ldapadd -QY EXTERNAL -H ldapi:/// -f 2.5-add-schemas.ldif
adding new entry "cn=core,cn=schema,cn=config"
adding new entry "cn=cosine,cn=schema,cn=config"
adding new entry "cn=inetorgperson,cn=schema,cn=config"
adding new entry "cn=collective,cn=schema,cn=config"
adding new entry "cn=corba,cn=schema,cn=config"
adding new entry "cn=duaconf,cn=schema,cn=config"
adding new entry "cn=openldap,cn=schema,cn=config"
adding new entry "cn=dyngroup,cn=schema,cn=config"
adding new entry "cn=java,cn=schema,cn=config"
adding new entry "cn=misc,cn=schema,cn=config"
adding new entry "cn=nis,cn=schema,cn=config"
adding new entry "cn=ppolicy,cn=schema,cn=config"
adding new entry "cn=kerberos,cn=schema,cn=config"
adding new entry "cn=sudo,cn=schema,cn=config"
adding new entry "cn=autofs,cn=schema,cn=config"

2.6 Инициализация базы данных

Где работаем: ldap-srv

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

Для начала создадим пароль администратора. Утилита slappasswd генерирует посоленный хэш вводимого нами пароля:

# slappasswd -h '{SSHA}'
New password:
Re-enter new password:
{SSHA}RMjrfsi7NkpBMR+NQHTDk4iddvo/2le+

Не забудьте сам пароль! :)

Сформируем конфигурационный LDIF-файл для нашей базы данных (2.6-db.ldif) и запишем получившийся хэш в атрибут olcRootPW:

dn: olcDatabase=mdb,cn=config
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=example,dc=com
olcDbDirectory: /var/lib/ldap
olcDbMaxsize: 1073741824
olcRootDN: cn=admin,dc=example,dc=com
olcRootPW: {SSHA}RMjrfsi7NkpBMR+NQHTDk4iddvo/2le+
olcAccess: {0}to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * break
olcAccess: {1}to attrs=userPassword
  by self write
  by anonymous auth
olcAccess: {2}to *
  by self read

dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor

И вновь несколько комментариев...

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

#  mkdir /var/lib/ldap
#  chown openldap:openldap /var/lib/ldap
#  chmod 0700 /var/lib/ldap

Загрузим конфигурацию базы данных:

#  ldapadd -QY EXTERNAL -H ldapi:/// -f 2.6-db.ldif
adding new entry "olcDatabase=mdb,cn=config"
adding new entry "olcDatabase=monitor,cn=config"

Определим RootDN для доступа к конфигурации службы каталогов. Он будет ссылаться на RootDN, находящийся в нашей БД. Эта запись желательна только при первоначальной настройке или в тестовой конфигурации. Не оставляйте её в боевой системе! Для {-1}frontend зададим минимально необходимые права для доступа к RootDSE. Создадим LDIF-файл 2.6-acl-mod.ldif, модифицирующий права доступа:

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com

dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to *
  by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
  by * break
olcAccess: {1}to dn.base=""
  by * read
olcAccess: {2}to dn.base="cn=subschema"
  by * read

Загрузим LDIF, изменяющий ACL:

#  ldapadd -QY EXTERNAL -H ldapi:/// -f 2.6-acl-mod.ldif
modifying entry "olcDatabase={-1}frontend,cn=config"
modifying entry "olcDatabase={0}config,cn=config"

Теперь мы ещё больше повысили значимость учётной записи администратора. С её помощью теперь можно получить полный доступ к службе каталогов. Имейте это ввиду. :)

Проверим корректность всех ACL и, заодно, наличие всех добавленных нами данных (вывод отформатирован для наглядности):

#  ldapsearch -QLLL -Y EXTERNAL -H ldapi:/// -b 'cn=config' dn olcAccess
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}inetorgperson,cn=schema,cn=config
dn: cn={3}collective,cn=schema,cn=config
dn: cn={4}corba,cn=schema,cn=config
dn: cn={5}duaconf,cn=schema,cn=config
dn: cn={6}openldap,cn=schema,cn=config
dn: cn={7}dyngroup,cn=schema,cn=config
dn: cn={8}java,cn=schema,cn=config
dn: cn={9}misc,cn=schema,cn=config
dn: cn={10}nis,cn=schema,cn=config
dn: cn={11}ppolicy,cn=schema,cn=config
dn: cn={12}kerberos,cn=schema,cn=config
dn: cn={13}sudo,cn=schema,cn=config

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.base=""
  by * read
olcAccess: {2}to dn.base="cn=subschema"
  by * read

dn: olcDatabase={0}config,cn=config
olcAccess: {0}to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external ,cn=auth" manage

dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external ,cn=auth" manage
  by * break
olcAccess: {1}to attrs=userPassword
  by self write
  by anonymous auth
olcAccess: {2}to *
  by self read

dn: olcDatabase={2}monitor,cn=config

Убедимся, что учётная запись администратора имеет доступ к нашей службе каталогов:

$  ldapwhoami -WD cn=admin,dc=example,dc=com
Enter LDAP Password:
dn:cn=admin,dc=example,dc=com

Отлично! Теперь у нас есть работающий сервер OpenLDAP.

Отредактируем файл /etc/ldap/ldap.conf. Это нужно только для того, чтобы немного упростить себе жизнь и меньше печатать в дальнейшем. В BASE подставьте свой суффикс, а в URI — FQDN Вашего сервера OpenLDAP:

BASE  dc=example,dc=com
URI  ldap://ldap-srv.example.com
# TLS_CACERT /etc/ssl/certs/rootca.crt
# TLS_REQCERT demand
TIMELIMIT 15
TIMEOUT  20

С настройкой TLS  мы разберемся в следующем разделе.

И последний штрих. Добавим демон нашей службы каталогов в автозагрузку:

#  update-rc.d slapd defaults
Pro-LDAP.ru 2015 г. Последнее изменение страницы — 3 мая 2015 г. Вопросы и предложения принимаются на форуме проекта.