Автор Тема: Как подключить модуль memberOf  (Прочитано 12390 раз)

manik207

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Как подключить модуль memberOf
« : 19 Март 2017, 12:12:46 »
Здравствуйте, Егор. С OpenLDAP и каталогами разбираюсь недавно.

Есть сервер с Redmine 3.1.7, есть сервер OpenLDAP, установлен на Centos 7 из yum, версия 2.4.40. Управляю через phpldapadmin.

Задача: в OpenLDAP создать свыше 50 пользователей (с последующим увеличением до 200 человек), и пять групп Каждой группе разрешен доступ к определенному сервису (Redmine, Asterisk и т.д.). Тестирую на Redmine.

Создаю ou=redmine, в ней cn=redmine-group (posixGroup), в группе создаю пользователей user1, user2 и т.д. При такой схеме авторизация в Redmine проходит замечательно. В Redmine указываю путь до каталога cn=redmine-group,ou=redmine,dc=my,dc=domen. 
Но, насколько я поняла, это из-за того, что группа "родная", т.е. пользователь создан в этой группе, и группа записана в атрибутах пользователя как gid.

Если этих же пользователей добавлять в другие аналогичные группы (для авторизации на других сервисах только членам группы), то это делать нужно через подключенный модуль memberOf.

Как проверить подключен ли он? Нашла здесь как подключить его, по адресу /usr/lib нет директории ldap (или не там ищу?). Добавить атрибут пользователю через phpldapadmin не могу, его нет в выпадающем списке атрибутов.
Как его найти и/или подключить?

Файла slapd.conf есть только в /usr/lib/tmpfiles.d/slapd.conf, его содержимое:
# openldap runtime directory for slapd.arg and slapd.pid
d /var/run/openldap 0755 ldap ldap -

есть cn=config:
ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
dn: 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: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}monitor,cn=config
dn: olcDatabase={2}hdb,cn=config
« Последнее редактирование: 19 Март 2017, 12:45:27 от manik207 »

egor

  • Администратор
  • Старожил
  • *****
  • Сообщений: 486
    • Просмотр профиля
Re: Как подключить модуль memberOf
« Ответ #1 : 20 Март 2017, 01:24:58 »
Здравствуйте, Анна!
Задача: в OpenLDAP создать свыше 50 пользователей (с последующим увеличением до 200 человек), и пять групп Каждой группе разрешен доступ к определенному сервису (Redmine, Asterisk и т.д.). Тестирую на Redmine.

Создаю ou=redmine, в ней cn=redmine-group (posixGroup), в группе создаю пользователей user1, user2 и т.д. При такой схеме авторизация в Redmine проходит замечательно. В Redmine указываю путь до каталога cn=redmine-group,ou=redmine,dc=my,dc=domen. 
Но, насколько я поняла, это из-за того, что группа "родная", т.е. пользователь создан в этой группе, и группа записана в атрибутах пользователя как gid.

Если этих же пользователей добавлять в другие аналогичные группы (для авторизации на других сервисах только членам группы), то это делать нужно через подключенный модуль memberOf.
Если я правильно понял, у Вас примерно такая структура каталога:
...
\ ou=redmine
    \ cn=redmine-group     # группа
         |\ user1
         |\ user2
          \ user3
Если так, то это не самое удачное решение. Обычно пользователей заводят отдельно в своём ou, группы -- в другом ou, а связь между пользователями и группами делают в виде атрибутов записи группы, ссылающейся на запись пользователя. То есть примерно так:
...
|\ ou=Users
      |\ uid=user1
      |\ uid=user2
       \ uid=user3
\ ou=Groups
      |\ cn=redmine-group
      |\ cn=asterisk-group
       \ ...

А записи группы, соответственно, будут выглядеть так (posixGroup):
dn: cn=redmine-group,ou=Groups,dc=mycompany,dc=ru
objectClass: posixGroup
cn: redmine-group
gidNumber: 2001
memberUid: user1
memberUid: user2

dn: cn=asterisk-group,ou=Groups,dc=mycompany,dc=ru
objectClass: posixGroup
cn: asterisk-group
gidNumber: 2002
memberUid: user2
memberUid: user3
Тогда, обычно, memberOf не нужен, да и с posixGroup его (memberOf) нельзя использовать. Если Вы думаете использовать memberOf, то группы нужно строить на объектном классе groupOfNames:
dn: cn=redmine-group,ou=Groups,dc=mycompany,dc=ru
objectClass: groupOfNames
cn: redmine-group
member: uid=user1,ou=Users,dc=mycompany,dc=ru
member: uid=user2,ou=Users,dc=mycompany,dc=ru

Вообще, лучше бы Вы подробнее объяснили задачу, тогда бы я Вам подсказал более-менее оптимальную структуру каталога.

Как проверить подключен ли он? Нашла здесь как подключить его, по адресу /usr/lib нет директории ldap (или не там ищу?). Добавить атрибут пользователю через phpldapadmin не могу, его нет в выпадающем списке атрибутов.
Как его найти и/или подключить?
Там приводятся примеры для Ubuntu, в red hat, судя по этой странице, модули находятся в /usr/lib64/openldap/ (в 32-битных дистрибутивах в /usr/lib/openldap/). Судя по приведённому Вами cn=config, модулей там ещё не было подключено, поэтому нужно создавать cn=module и прописывать туда модули, как описано в той статье, которую Вы упоминаете.

Егор
« Последнее редактирование: 20 Март 2017, 08:51:29 от egor »

manik207

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Как подключить модуль memberOf
« Ответ #2 : 20 Март 2017, 15:55:06 »
Егор, спасибо за ответ!
Вы правы, дерево используется не совсем правильное, меня оно тоже не устраивает, (по принципу "пользователь - только в одной группе"), но только при таком подходе в редмине удалось авторизоваться.

Задача - организовать гибкую систему управления пользователями в общественной организации. Есть уже упомянутый редмин, астериск, хотим добавить jabber и CRM (ее тоже к лдапу подключать). Пока самая актуальная проблема - с редмином.
Как я это вижу: 
1. Зарегистрировался пользователь - через ldif создаю его в ou=People. Всё, на пользователя есть имя, емайл и uid (или cn?). А, еще пароль.
2. Захотел поучаствовать в работе (взять задачу в редмине) - добавляю его в группу  redmine и в группу jabber (через запись в его данных или в группе его прописать - тут мне не видно, как удобнее и проще) - пользователь получает доступ до редмина и джаббера.
3. Проявил интерес дальше - добавляю в группу астериска - у пользователя появляется доступ до ip-телефонии.
4. Ушел он после первого дня - удаляю его из группы  redmine, jabber и asterisk.
5. Вернулся и хочет только в чате атмосферу поддерживать - опять группа jabber
6. Если пойдет поток пользователей, веб-интерфейсом можно не управится, поэтому предполагаю загнать это в скрипты, но это же не шестое, а десятое))

Это моя идеальная картинка))) На деле, бьюсь с редмином. На LOR'e подсказали, что разные сервисы смотрят у пользователя разные атрибуты: redmine смотрит

  Login     = sAMAccountName
  Firstname = givenName
  Lastname  = sN
  Email     = mail

По правильному, как описано в мануале редмина для адекватной работы с лдапом нужно модуль memberOf подгрузить, при этом не до конца понятно, с какими минимальными атрибутами создавать пользователя (posix или еще какие-то варианты), чтобы они работали по этой  схеме, в этой группе.

По описанной вами правильной схеме (пользователей - в ou=People, группы - в ou=Group), пользователь user1 группы redmine, хоть и является member'ом, но авторизоваться не может, пароль не подходит... В самом редмине прописываю путь cn=redmine,ou=Group,dc=ldap,dc=centos... cn=redmine создавала и как posixGroup, и как groupOfNames. Скорее, пытаюсь связать не подходящие элементы конструктора)))

Вчера пробовала в SuiteCRM - пользователь из той же группы redmine (не стала новую создавать, протестила на имеющейся) тоже не может авторизоваться, пароль не подходит...

Установила модуль memberOf по предложенной вами инструкции, она совпасам модуль загрузился без ошибок, только загружен два раза (очень надеюсь, что это не критично)
ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
dn: cn=config
dn: cn=module{1}{0},cn=config
dn: cn=module{1},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: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}monitor,cn=config
dn: olcDatabase={2}hdb,cn=config
Добавление его как overlay тоже прошло на ура.

Теперь вопрос: с какими атрибутами создать пользователя, который сможет от имени редмина читать пароли от пользователей в лдапе?
« Последнее редактирование: 20 Март 2017, 18:27:15 от manik207 »

egor

  • Администратор
  • Старожил
  • *****
  • Сообщений: 486
    • Просмотр профиля
Re: Как подключить модуль memberOf
« Ответ #3 : 21 Март 2017, 02:55:29 »
Здравствуйте, Анна! Так много нужно рассказать. что даже не знаю с чего начать =) .
Скорее всего в redmine (проверить мне не на чем) при аутентификации используется обыкновенное простое подсоединение (Simple Bind) к каталогу. Это значит, что пользователь для аутентификации должен предъявить DN (уникальное имя, типа uid=user1,ou=People,dc=mycompany,dc=ru) своей записи и пароль.  Обычно же в интерфейсе аутентификации пользователи вводят только имя учётной записи (user1), следовательно, нужно как-то сопоставить user1 с uid=user1,ou=People,dc=mycompany,dc=ru. Для этого выполняется поиск в каталоге (обычно анонимный, но если он запрещён, то поиск от имени того пользователя, у кого есть права на чтение каталога). Если запись найдена в каталоге, то от её имени выполняется попытка простого подсоединения. Если простое подсоединение удалось, то считается, что пользователь прошёл аутентификацию, в противном случае -- нет.

Каталог для примера:
# Корневая запись
dn: dc=mycompany,dc=ru
objectClass: organization
objectClass: dcObject
dc: mycompany
o: My Company

# Ветка "Люди"
dn: ou=People,dc=mycompany,dc=ru
objectClass: organizationalUnit
ou: People

dn: uid=ivanov,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: ivanov
cn: Ivan Ivanov
givenName: Ivan
sn: Ivanov
mail: ivanov@mycompany.ru
userPassword: ivanovPassword

dn: uid=petrov,ou=People,dc=mycompany,dc=ru
objectClass: inetOrgPerson
uid: petrov
cn: Pert Petrov
givenName: Petr
sn: Petrov
mail: petrov@mycompany.ru
userPassword: petrovPassword

Тогда настройки Redmine должны быть:
Name   = Mycompany Catalog
Host   = ldap-server.mycompany.ru
Port   = 389
LDAPS  = no # или yes, если настроен
Account  = <пусто> # или, если анонимный поиск запрещён, то DN пользователя с правами, например, cn=admin,dc=mycompany,dc=ru
Password = <пусто> # или, если анонимный поиск запрещён, то пароль пользователя из пункта Account
Base DN  = dc=mycompany,dc=ru
LDAP Filter = <пусто>

On-the-fly user creation = yes
Attributes
  Login     = uid
  Firstname = givenName
  Lastname  = sn
  Email     = mail

При такой настройке пользователи должны проходить аутентификацию.

Теперь добавим группу:
# Ветка "Группы"
dn: ou=Groups,dc=mycompany,dc=ru
objectClass: organizationalUnit
ou: Groups

dn: cn=redmine-group,ou=Groups,dc=mycompany,dc=ru
objectClass: groupOfNames
cn: redmine-group
member: uid=ivanov,ou=People,dc=mycompany,dc=ru

Усли у Вас корректно настроилось наложение memberOf, то у пользователя ivanov должен появить операционный (невидимый) атрибут memberOf с группой cn=redmine-group,ou=Groups,dc=mycompany,dc=ru. Чтобы его просмотреть, нужно явно указать его в запросе:

# ldapsearch -x -LLL -H ldap://ldap-server.mycompany.ru -b 'dc=mycompany,dc=ru' '(uid=*)' memderOf
dn: uid=ivanov,ou=People,dc=mycompany,dc=ru
memberOf: cn=redmine-group,ou=Groups,dc=mycompany,dc=ru

dn: uid=petrov,ou=People,dc=mycompany,dc=ru

То есть у ivanov он есть, а у petrov -- нет, что логично, т.к. последний не является членом этой группы.

Тогда в поле LDAP Filter настроек redmine можно указать:
LDAP Filter = (&(objectClass=inetOrgPerson)(memberOf=cn=redmine-group,ou=Groups,dc=mycompany,dc=ru))
То есть отбор пользователей с объектным классом inetOrgPerson И атрибутом memberOf с указанным значением. В тексте мануала упоминается переменная $login, если её можно использовать в поле LDAP Filter (что из мануала не очевидно), то будет вообще красиво:
LDAP Filter = (&(objectClass=inetOrgPerson)(uid=$login)(memberOf=cn=redmine-group,ou=Groups,dc=mycompany,dc=ru))

Попробуйте. Егор

manik207

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Как подключить модуль memberOf
« Ответ #4 : 22 Март 2017, 18:48:24 »
Егор, спасибо вам огромное, за ваши развернутые ответы!

Всё оказалось проще. Даже чем  в мануале. Наложение memberof работает. Действительно нужен простой фильтр, работает даже простое указание LDAP Filter = memberOf=cn=redmine,ou=Group,dc=ldap,dc=centoc Первый вариант из мануала тоже работает, а вот с добавлением uid - не хочет
Цитировать
LDAP Filter = (&(objectClass=inetOrgPerson)(uid=$login)(memberOf=cn=redmine-group,ou=Groups,dc=mycompany,dc=ru))
Оставила простой вариант. Спасибо!

Егор, тема openLDAP"а мне интересна для развития своего проекта, остались вопросы, которые выходят за рамки этой темы. Возможно получить от вас оплачиваемую консультацию по своим "недопоняткам"? Если возможно, стукните мне в ВК.

Собственно, вопросы общего плана:
1. Я добавляю пользователей списком через ldif-файл. Например, 100 пользователей. Куда они попадают? Где хранятся? ldif-файл, насколько я поняла, это карточка с записями. Он заносит данные в лдап. После этого сам файл можно удалять или он и есть основа каталога и удалять его нельзя?
2. Из ответа на первый вопрос вытекает второй. Мне нужно удалить 25 пользователей (особенность общественной организации). И откорректировать еще 25 записей. Знаю, что это делается тоже через ldif - командой ldapmodify.  Создала я этот файл (по его синтаксису - отдельный вопрос))), загрузила изменения, этот ldif тоже - хранить, или удалить можно...?
2. Как закрыть анонимный доступ до лдапа. Чтобы никто не мог читать дерево каталога, не авторизовавшись. А можно ли закрыть от простых пользователей и оставить чтение каталога только для админа?
3. Какие атрибуты (или нахождение в каких группах) разрешают пользователю читать пароли пользователей (хочу закрыть  анонимный доступ, а прописывать пароль от главного менеджера ldap-каталога боязно, я кроме консоли его нигде не ввожу).

Я так понимаю каждый вопрос - это отдельная тема для форума. Могу раскидать по темам - форум станет больше)))

egor

  • Администратор
  • Старожил
  • *****
  • Сообщений: 486
    • Просмотр профиля
Re: Как подключить модуль memberOf
« Ответ #5 : 22 Март 2017, 23:05:37 »
1. Я добавляю пользователей списком через ldif-файл. Например, 100 пользователей. Куда они попадают? Где хранятся? ldif-файл, насколько я поняла, это карточка с записями. Он заносит данные в лдап. После этого сам файл можно удалять или он и есть основа каталога и удалять его нельзя?
2. Из ответа на первый вопрос вытекает второй. Мне нужно удалить 25 пользователей (особенность общественной организации). И откорректировать еще 25 записей. Знаю, что это делается тоже через ldif - командой ldapmodify.  Создала я этот файл (по его синтаксису - отдельный вопрос))), загрузила изменения, этот ldif тоже - хранить, или удалить можно...?
После того, как записи добавлены (изменены, удалены) в каталоге, файл LDIF больше не нужен. Вообще, LDIF разработан для экспорта/импорта данных каталога, соответственно, данные в каталоге отдельно, а их тестовое представление в LDIF-файлах -- отдельно.Так что удаляйте смело. Насчёт синтаксиса LDIF для модификаций -- можно посмотреть главу 8 LFRS и примеры в RFC 2849. Если что, спрашивайте.

2. Как закрыть анонимный доступ до лдапа. Чтобы никто не мог читать дерево каталога, не авторизовавшись. А можно ли закрыть от простых пользователей и оставить чтение каталога только для админа?
3. Какие атрибуты (или нахождение в каких группах) разрешают пользователю читать пароли пользователей (хочу закрыть  анонимный доступ, а прописывать пароль от главного менеджера ldap-каталога боязно, я кроме консоли его нигде не ввожу).
Всё это делается с помощью ACL в настройках OpenLDAP,то есть Вам потребуется иметь возможность менять настройки самого сервера каталогов, а не только работать с каталогом. ACL -- очень обширная тема, в двух словах не расскажешь, предлагаю для начала, опять же, почитать документацию:
Глава 8 OLAG, в частности в примере 8.4.1 дан "стандартный" подход к ограничению анонимного доступа,
настройки ACL в учебнике LFRS,
man-страница slapd.access(5).

Если будут вопросы, пишите. Платных консультаций я не даю, только бесплатные =) .

Егор