error=Поиск Ldap соответствует более чем одной записи, проверьте настройки фильтра в Grafana LDAP

Я использую Графану 4.2.0. Я пытаюсь интегрировать функциональность LDAP в приложение. У меня есть пользователь ldapuser1, созданный в LDAP, но когда я пытаюсь войти в Grafana, используя это имя пользователя, я получаю сообщение об ошибке: «ошибка = «Поиск Ldap соответствует более чем одной записи, проверьте настройки фильтра»».

Сообщение об ошибке из grafana.log выглядит следующим образом:

t=2017-05-26T05:59:28-0700 lvl=eror msg="Error while trying to authenticate user" logger=context userId=0 orgId=0 uname= error="Ldap search matched more than one entry, please review your filter setting"
t=2017-05-26T05:59:28-0700 lvl=eror msg="Request Completed" logger=context userId=0 orgId=0 uname= method=POST path=/login status=500 remote_addr=127.0.0.1 time_ms=68ns size=53

Пожалуйста, найдите ниже файл ldap.toml для справки.

# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
# [log]
verbose_logging = true

# filters = ldap:debug

[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "127.0.0.1"
# Default port is 389 or 636 if use_ssl = true
port = 389
# Set to true if ldap server supports TLS
use_ssl = false
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = false
# set to true if you want to skip ssl cert validation
ssl_skip_verify = false
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert = /path/to/certificate.crt

# Search user bind dn
bind_dn = "dc=cloudera,dc=com"
# Search user bind password
bind_password = 'cloudera'

# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
search_filter = "(uid=%s)"

# An array of base dns to search through
search_base_dns = ["dc=cloudera,dc=com"]

# In POSIX LDAP schemas, without memberOf attribute a secondary query must be made for groups.
# This is done by enabling group_search_filter below. You must also set member_of= "cn"
# in [servers.attributes] below.

# Users with nested/recursive group membership and an LDAP server that supports LDAP_MATCHING_RULE_IN_CHAIN
# can set group_search_filter, group_search_filter_user_attribute, group_search_base_dns and member_of
# below in such a way that the user's recursive group membership is considered.
#
# Nested Groups + Active Directory (AD) Example:
#
#   AD groups store the Distinguished Names (DNs) of members, so your filter must
#   recursively search your groups for the authenticating user's DN. For example:
#
#     group_search_filter = "(member:1.2.840.113556.1.4.1941:=%s)"
#     group_search_filter_user_attribute = "distinguishedName"
#     group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
#
#     [servers.attributes]
#     member_of = "distinguishedName"

## Group search filter, to retrieve the groups of which the user is a member (only set if memberOf attribute is not available)
# group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
## Group search filter user attribute defines what user attribute gets substituted for %s in group_search_filter.
## Defaults to the value of username in [server.attributes]
## Valid options are any of your values in [servers.attributes]
## If you are using nested groups you probably want to set this and member_of in
## [servers.attributes] to "distinguishedName"
# group_search_filter_user_attribute = "distinguishedName"
## An array of the base DNs to search through for groups. Typically uses ou=groups
# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]

# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "ldapuser1"
surname = "ldapuser1"
username = "ldapuser1"
#member_of = "People"
email =  "[email protected]"

# Map ldap groups to grafana org roles
[[servers.group_mappings]]
group_dn = "cn=admins,dc=grafana,dc=org"
org_role = "Admin"
# The Grafana organization database id, optional, if left out the default org (id 1) will be used
# org_id = 1

[[servers.group_mappings]]
group_dn = "cn=users,dc=grafana,dc=org"
org_role = "Editor"

[[servers.group_mappings]]
# If you want to match all (or no ldap groups) then you can use wildcard
group_dn = "*"
org_role = "Viewer"

Пожалуйста, также найдите ниже результат команды поиска LDAP.

ldapsearch -x -b "dc=cloudera,dc=com" | less

# extended LDIF
#
# LDAPv3
# base <dc=cloudera,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# cloudera.com
dn: dc=cloudera,dc=com
dc: cloudera
objectClass: top
objectClass: domain
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Hosts, cloudera.com
dn: ou=Hosts,dc=cloudera,dc=com
ou: Hosts
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Rpc, cloudera.com
dn: ou=Rpc,dc=cloudera,dc=com
ou: Rpc
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Services, cloudera.com
dn: ou=Services,dc=cloudera,dc=com
ou: Services
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# netgroup.byuser, cloudera.com
dn: nisMapName=netgroup.byuser,dc=cloudera,dc=com
nisMapName: netgroup.byuser
objectClass: top
objectClass: nisMap
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Mounts, cloudera.com
dn: ou=Mounts,dc=cloudera,dc=com
ou: Mounts
objectClass: top
objectClass: organizationalUnit
associatedDomain: cloudera.com

# Networks, cloudera.com
dn: ou=Networks,dc=cloudera,dc=com
ou: Networks
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# People, cloudera.com
dn: ou=People,dc=cloudera,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Groups, cloudera.com
dn: ou=Groups,dc=cloudera,dc=com
ou: Groups
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Netgroup, cloudera.com
dn: ou=Netgroup,dc=cloudera,dc=com
ou: Netgroup
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Protocols, cloudera.com
dn: ou=Protocols,dc=cloudera,dc=com
ou: Protocols
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# Aliases, cloudera.com
dn: ou=Aliases,dc=cloudera,dc=com
ou: Aliases
objectClass: top
objectClass: organizationalUnit
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# netgroup.byhost, cloudera.com
dn: nisMapName=netgroup.byhost,dc=cloudera,dc=com
nisMapName: netgroup.byhost
objectClass: top
objectClass: nisMap
objectClass: domainRelatedObject
associatedDomain: cloudera.com

# ldapuser1, People, cloudera.com
dn: uid=ldapuser1,ou=People,dc=cloudera,dc=com
uid: ldapuser1
cn: ldapuser1
sn: ldapuser1
mail: [email protected]
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSQ2JHUxVTE3SnR4JEN1a05HeEZXYmIyOG9NckRyRkpJeEQuR3ZjYmd
 jWXd2WFlrMGtTRE1YZW9zOEZVSVE3dUdYdkxsS3E3aTd5MnVIS1lpSnEzZnU5N0paWmE0SWlZNUcx
shadowLastChange: 17309
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 502
gidNumber: 504
homeDirectory: /home/guests/ldapuser1

# ldapuser2, People, cloudera.com
dn: uid=ldapuser2,ou=People,dc=cloudera,dc=com
uid: ldapuser2
cn: ldapuser2
sn: ldapuser2
mail: [email protected]
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSQ2JFplS3VyRllaJG9VSmVGNktTRThiQWZWem1rVk8wMGNGUjQyUWt
 oT0ZuZVpVc1IzUG51c0R2eXZubXJEN3dDU2tPOC9sb2dIeHRSSGxZVVp3dTlIZXpEd3QxVHhKRjAw
shadowLastChange: 17309
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 503
gidNumber: 505
homeDirectory: /home/guests/ldapuser2

# ldapuser1, Groups, cloudera.com
dn: cn=ldapuser1,ou=Groups,dc=cloudera,dc=com
objectClass: posixGroup
objectClass: top
cn: ldapuser1
userPassword:: e2NyeXB0fXg=
gidNumber: 504

# ldapuser2, Groups, cloudera.com
dn: cn=ldapuser2,ou=Groups,dc=cloudera,dc=com
objectClass: posixGroup
objectClass: top
cn: ldapuser2
userPassword:: e2NyeXB0fXg=
gidNumber: 505

# search result
search: 2
result: 0 Success

# numResponses: 18
# numEntries: 17 

Я использую локальный сервер OpenLDAP. Я не могу понять основную причину проблемы. Я новичок в LDAP и настраиваю его впервые.


person Ankur Bahre    schedule 26.05.2017    source источник


Ответы (2)


У вас есть две записи ldapuser1 и ldapuser2 соответственно (один пользователь и одна группа для каждой). Когда вы выполняете поиск по cn=ldapuser1, openldap не может различить эти две записи, даже если они имеют разные DNS. Вам нужно искать что-то уникальное среди всех записей.

Я вижу два варианта:

1) Поиск по уникальному атрибуту, например uid. Это найдет uid=ldapuser1,ou=People,dc=cloudera,dc=com, но не cn=ldapuser1,ou=Groups,dc=cloudera,dc=com, потому что у группы нет uid.

2) Измените фильтр поиска, чтобы он включал только пользователей, например. (&(objectClass=inetOrgPerson)(cn=%s))

person Ryan    schedule 26.05.2017
comment
В соответствии с первым вариантом я уже использую приведенную ниже конфигурацию # Поиск привязки пользователя dn bind_dn = dc=cloudera,dc=com # Поиск пароля привязки пользователя bind_password = 'cloudera' # Фильтр поиска пользователя, например (cn=%s) или (sAMAccountName=%s) или (uid=%s) search_filter = (uid=%s) Для варианта 2 я попытался изменить поисковый фильтр, как было предложено выше, я получаю сообщение об ошибке «Неверное имя пользователя или пароль». - person Ankur Bahre; 27.05.2017

Первая проблема, похоже, связана с вашей конфигурацией Grafana LDAP. Давайте пройдемся по вашему файлу TOML сверху вниз.

Запрос Bind используется для инициации аутентификации сервером LDAP. Для простой привязки нам нужно различающееся имя (dn) пользователя и пароль. Поскольку вы хотите разрешить пользователям представлять идентификатор пользователя (uid) вместо отличительного имени, Grafana должна сопоставить uid с dn путем поиска в каталоге. bind-dn относится к учетной записи пользователя, которую Grafana будет использовать для получения отличительного имени (DN) аутентифицируемого пользователя. Это определенно не контекст именования dc=cloudera,dc=com, а существующая запись пользователя.

Раздел servers.attributes позволяет сопоставлять внутренние имена Grafana с фактическими именами типов атрибутов LDAP. Я предлагаю следующие сопоставления, даже если вы еще не добавили givenName к своим пользовательским записям:

name = givenName
surname = sn
username = uid
email = mail

Сопоставления групп предназначены для авторизации пользователей. Каждый group_dnдолжен относиться к существующей группе пользователей в каталоге. Членам группы назначается определенная заранее определенная роль Grafana. Ваши группы образцов бесполезны, поскольку в них отсутствует какой-либо атрибут члена.

Кроме того, обязательно настройте свои group_dn (...,dc=grafana,dc=org) в соответствии с контекстом LDAP (dc=cloudera,dc=com).

person marabu    schedule 27.05.2017