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

Disclaimer: Я ни в коем не считаю ldap шедевром инженерной/архитектурной мысли, просто так исторически сложилось, что поддержка авторизации через него есть практически везде

Установка / Debian

# apt-get install slapd

Лезет стандартное окошко настройки, которое просит установить пароль админа. Рекомендую его сразу поставить правильным, потому что поменять его - много лишних действий.

Дальше начинается чёрная магия.

Схема дерева

Будем делать дерево вот по такой простенькой схеме:

dc=org
`-> dc=company
    `+-> ou=users
     |   `+-> uid=user1
     |    `-> uid=user2
     `-> ou=groups
         `+-> cn=group1
          `-> cn=group2

Для юзера, образующий элемент - inetOrgPerson, для группы - groupOfUniqueNames.

Настройка slapd

Нужно создать саму базу, корень в ней, основные ou'шки и пользователя admin для дальнейшей работы.

openldap после 2.4.27 поставляется с динамическим конфигом. Что бы там не говорили разработчики, править его намного сложнее.

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

  • остановить slapd: service slapd stop
  • перейти в /etc/ldap/slapd.d/cn=config, найти там файлик вида olcDatabase={X}hdb.ldif
  • убедиться, что он именно тот, что нужно: olcSuffix: dc=nodomain
  • если он последний по порядку: переместить его куда-нибудь, например в /tmp
  • если он НЕ последний - см ниже
  • проверить конфиг через slaptest, в случае успеха - запустить slapd обратно

Сначала нужно определить порядковый номер для новой базы. Смотрим в /etc/ldap/slapd.d/cn=config/ на предмет файлов olcDatabase*. Находим последнее по порядку значение в {N}, добавляем к нему единицу.

$ export RDN="dc=company,dc=org" # поменять на правильный
$ export N=2                     # номер базы
$ export ADMIN="cn=admin,$RDN"   # юзер для правки базы
$ PASS=$(slappasswd -h '{SSHA}')
New password:
Re-enter new password:
$
$ cat > 01-create-db.ldif <<EOF
dn: olcDatabase={$N}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {$N}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: $RDN
olcAccess: {0}to attrs=userPassword,shadowLastChange
  by dn="$ADMIN" write
  by anonymous auth
  by self write
  by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="$ADMIN" write by * read
olcLastMod: TRUE
olcRootDN: $ADMIN
olcRootPW: $PASS
olcDbCheckpoint: 512 30
olcDbConfig: set_cachesize 0 2097152 0
olcDbConfig: set_lk_max_objects 1500
olcDbConfig: set_lk_max_locks 1500
olcDbConfig: set_lk_max_lockers 1500
olcDbIndex: objectClass eq
EOF
$ ldapadd -Y EXTERNAL -H ldapi:/// -f 01-create-db.ldif

Предполагается, что slapd запущен с -h ldap://127.0.0.1:389/ ldapi:///, т.е. слушает на loopback'е и разрешены обращения через локальный сокет.

Создаём корень базы. Обратите внимание, авторизация меняется с -Y EXTERNAL на обычный -D $ADMIN -W

$ cat > 02-create-rdn.ldif <<EOF
dn: $RDN
objectClass: top
objectClass: dcObject
objectclass: organization
o: company.org
dc: company
description: -
EOF
$ ldapadd -D "$ADMIN" -W -H ldapi:/// -f 02-create-rdn.ldif

Создаём основные ou'шки:

$ cat > 03-create-ou.ldif <<EOF
dn: ou=users,$RDN
objectClass: organizationalUnit
ou: users

dn: ou=groups,$RDN
objectClass: organizationalUnit
ou: groups
EOF
$ ldapadd -D "$ADMIN" -W -H ldapi:/// -f 03-create-ou.ldif

Создаём юзера, из под которого будем править базу:

$ cat > 04-create-admin.ldif <<EOF
dn: $ADMIN
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: $PASS
EOF
$ ldapadd -D "$ADMIN" -W -H ldapi:/// -f 04-create-admin.ldif

Этого должно быть достаточно. Проверяем работу:

$ ldapsearch -LL -D $ADMIN -b $RDN -W 'dn'
Enter LDAP Password:
version: 1

dn: dc=company,dc=org
dn: ou=users,dc=company,dc=org
dn: ou=groups,dc=company,dc=org
dn: cn=admin,dc=company,dc=org

Работа с базой

TODO: LDIF'ы типовых операций с базой.

Дополнительно / Багфиксы

Добавляем прав обычному юзеру. Обращаю внимание: перед "by" - ДВА пробела. это связано с тем, что при разборе продолжения линии парсером - первый пробел отбрасывается.

$ cat > tmp.ldif <<EOF
dn: olcDatabase={$N}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: to *
  by self write
  by * read
  by anonymous none
EOF
$ ldapadd -Y EXTERNAL -H ldapi:/// -f tmp.ldif

Багфикс №2 - добавляем индекс для (uid=*)

$ cat > tmp.ldif <<EOF
dn: olcDatabase={$N}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: uid eq
EOF
$ ldapadd -Y EXTERNAL -H ldapi:/// -f tmp.ldif

Дополнительно / Удаление типовой базы

Задание со звёздочкой. Если мы прошляпили момент и хотим удалить типовую базу после создания своей - последовательность действий такая:

  • Останавливаем slapd
  • делаем бэкапы /etc/ldap
  • идём в /etc/ldap/slapd.d/cn=config/, убираем оттуда файлик olcDatabase, отвечающий за тестовую базу.
  • исправляем имена файлов, чтобы число в {} было последовательным, начиная с нуля.
  • исправляем то же число в {} внутри переименованных файлов
  • исправляем чексумму в заголовке файла (нужно посчитать CRC32 для файла, пропуская первые 2 строки с заголовком, и вписать её в заголовок). Например так: tail -n +3 olcDatabase={3}hdb.ldif | rhash --crc32 -
  • осеняем себя пентаграммой, запускаем slaptest, читаем вывод, исправляем
  • запускаем обратно slapd