LDAP
Авторизация через существующие системы управления идентификацией
Chef Automate может интегрироваться с существующими службами LDAP для аутентификации пользователей в Chef Automate и, следовательно, использовать их существующие групповые принадлежности для определения их разрешений в Chef Automate.
Chef Automate поддерживает использование как локальных пользователей, так и пользователей, управляемых извне, из внешнего поставщика идентификации (IdP). Можно использовать как одну службу LDAP (или MSAD для упрощенной настройки установок Active Directory), так и одного поставщика SAML IdP. Вам не нужно настраивать внешний IdP, если вы просто хотите создать пользователей и команды локально в Chef Automate. Дополнительную информацию см. в документации по пользователям.
Chef Automate использует Dex для поддержки интеграций LDAP. Для настройки аутентификации для вашей установки Chef Automate создайте файл TOML, содержащий частичную конфигурацию LDAP. Затем выполните chef-automate config patch </path/to/your-file.toml>, чтобы развернуть изменения.
Предупреждение
Переключение между настройкой Microsoft AD и общей настройкой LDAP не повлияет на ваши политики, так как обе они являются конфигурациями LDAP. Однако переключение между любой из этих конфигураций и конфигурацией SAML потребует корректировки членства в политиках IAM.
Примечание
Поддерживаемые системы управления идентификацией
- Azure Active Directory
- Microsoft Active Directory (MSAD)
Обзор
В этом документе описана настройка интеграций Chef Automate с протоколом Lightweight Directory Access Protocol (LDAP) и Microsoft Active Directory (MSAD). LDAP — это устоявшийся и открытый стандартный протокол для взаимодействия с серверами каталогов. Сервер каталогов хранит информацию — в данном случае информацию для аутентификации и авторизации пользователей — в дереве записей. (Это не реляционная база данных.)
Microsoft Active Directory
Microsoft Active Directory (MSAD) — это тип сервера каталогов, который поддерживает LDAP. Chef Automate поставляется с конфигурацией LDAP по умолчанию для MSAD. Конфигурация Chef Automate по умолчанию для MSAD — это минимальная конфигурация для стандартных систем MSAD, которую можно расширить, переопределяя значения по умолчанию и используя дополнительные параметры конфигурации. Конфигурация Chef Automate по умолчанию для Microsoft AD специфична для LDAP. Чтобы настроить Microsoft AD с использованием SAML, см. документацию по SAML.
Изменение конфигурации Chef Automate
Если вам необходимо изменить настройки внешнего поставщика идентификации, следуйте этим шагам:
- Выполните
chef-automate config show config.toml. - Отредактируйте
config.toml, чтобы заменить разделdex.v1.sys.connectorsзначениями конфигурации для нового поставщика идентификации. - Выполните
chef-automate config set config.toml, чтобы установить обновлённую конфигурацию.
Минимальная конфигурация MSAD
- base_user_search_dn
- “ваш базовый DN поиска пользователей”
- base_group_search_dn
- “ваш базовый DN поиска групп”
- bind_dn
- “ваш bind_dn”
- bind_password
- “ваш bind_password”
bind_passwordтакже может быть передан через переменную средыAUTOMATE_SECRET_MSAD_PASSWORD, когда выполняются командыchef-automate. - ca_contents
- Содержимое сертификата вашего центра сертификации (CA). Можно указать несколько сертификатов CA в формате PEM. Необязательно.
# Example ca_contents setting: ca_contents = """-----BEGIN CERTIFICATE----- MIICsDCCAhmgAwIBAgIJAJxMopMJbhPkMA0GCSqGSIb ... X0uRzUPlpTtd5tYFs43nKqxJT6s= -----END CERTIFICATE-----""" - host
- Доменное имя вашего сервера каталогов, например
"ldap.corp.com". Порт по умолчанию:636. Переопределите порт, добавив его к настройке хоста,"ldap.corp.com:10636"
Минимальный config.toml для MSAD
[dex.v1.sys.connectors.msad_ldap]
host = "<your host>"
bind_dn = "<your bind_dn>"
bind_password = "<your bind_password>"
base_user_search_dn = "<your base user search DN>"
base_group_search_dn = "<your base group search DN>"
ca_contents = "<your ca contents>" # optional, but recommended
Полная конфигурация MSAD
Конфигурация MSAD — это конфигурация LDAP с дополнительными значениями по умолчанию, которые часто хорошо подходят для Active Directory. Переопределите любое отдельное значение по умолчанию, раскомментировав его в конфигурации и задав его значение:
- email_attr
- “mail”
- filter_groups_by_user_attr
- “member”
- filter_groups_by_user_value
- “DN”
- group_query_filter
- “(objectClass=group)”
- group_display_name_attr
- “displayName”
- insecure_no_ssl
- false
Предупреждение
- user_display_name_attr
- “displayName”
- user_id_attr
- “sAMAccountName”
- user_query_filter
- “(objectClass=person)”
- username_attr
- “sAMAccountName”
Пример полного config.toml для MSAD
[dex.v1.sys.connectors.msad_ldap]
host = "<your host>"
bind_dn = "<your bind_dn>"
bind_password = "<your bind_password>"
base_user_search_dn = "<your base user search DN>"
base_group_search_dn = "<your base group search DN>"
ca_contents = "<your ca contents>" # optional
# MSAD default values (uncomment to override a specific one)
# insecure_no_ssl = false
# user_query_filter = "(objectClass=person)"
# user_id_attr = "sAMAccountName"
# username_attr = "sAMAccountName"
# email_attr = "mail"
# user_display_name_attr = "displayName"
# group_query_filter = "(objectClass=group)"
# filter_groups_by_user_value = "DN"
# filter_groups_by_user_attr = "member"
# group_display_name_attr = "displayName"
Расширенные настройки LDAP
Для тех, кто не использует Microsoft AD или требует большего контроля над конфигурацией, Chef Automate предоставляет следующие настраиваемые параметры конфигурации LDAP:
- base_group_search_dn
- “ваш базовый DN поиска групп”
- base_user_search_dn
- “ваш базовый DN поиска пользователей”
- bind_dn
- “ваш bind_dn”
- bind_password
- “ваш bind_password”
- ca_contents
- “ваш ca contents”
- email_attr
- “ваш атрибут электронной почты”
- filter_groups_by_user_attr
- “группы для фильтрации по атрибуту пользователя”
- filter_groups_by_user_value
- “группы для фильтрации по значению атрибута пользователя”
- group_display_name_attr
- “атрибут отображаемого имени группы”
- group_query_filter
- “ваш фильтр запроса групп”
- host
- “ваш хост”
insecure_no_ssl :true или false
- user_query_filter
- “ваш фильтр запроса пользователей”
- username_attr
- “ваш атрибут имени пользователя”
- user_id_attr
- “ваш атрибут идентификатора пользователя”
- user_display_name_attr
- “ваш атрибут отображаемого имени пользователя”
Пример extended config.toml для LDAP
[dex.v1.sys.connectors.ldap]
# authentication options
ca_contents = "<your ca contents>"
host = "<your host>"
bind_dn = "<your bind_dn>"
bind_password = "<your bind_password>"
insecure_no_ssl = true or false
# ldapsearch options
base_user_search_dn = "<your base user search DN>"
user_query_filter = "<your user query filter>"
username_attr = "<your username attribute>"
user_id_attr = "<your userid attribute>"
email_attr = "<your email attribute>"
user_display_name_attr = "<your user display name attribute>"
base_group_search_dn = "<your base group search DN>"
group_query_filter = "<your group query filter>"
filter_groups_by_user_attr = "<groups to filter by user attribute>"
filter_groups_by_user_value = "<groups to filter by user value>"
group_display_name_attr = "<group display name attribute>"
См. LDAP для получения дополнительной информации о полях конфигурации. Вы можете использовать весь функционал TOML для объявления полей конфигурации.
Предупреждение
Однако, если вы хотите интегрироваться с сервером LDAP с отключенным TLS:
insecure_no_ssl = true
Вход с помощью LDAP
После того, как пользователь ввел имя пользователя и пароль на экране входа, Chef Automate выполняет ряд операций для завершения входа:
Авторизация с помощью LDAP
Chef Automate поддерживает определение разрешений для LDAP-пользователей и их групп. См. Члены и политики IAM.
Подключение
В первую очередь, Chef Automate должен установить TCP-соединение со службой LDAP, защищенное TLS. Он подключится к хосту, настроенному в вашей конфигурации TOML, например:
host = "ldap.corp.com"
Automate использует порт 636 по умолчанию. Чтобы переопределить порт, добавьте его к настройке хоста, например:
host = "ldap.corp.com:10636"
Вопрос о проверке подлинности сертификата TLS сервера зависит от настройки TLS: если вы предоставите сертификат центра сертификации (CA), Chef Automate будет общаться с службой LDAP только в том случае, если сертификат, предоставленный хостом, может быть проверен с использованием сертификата CA.
Предупреждение
Однако, если вы хотите интегрироваться с сервером LDAP с отключенным TLS:
insecure_no_ssl = true
См. Устранение неполадок соединения для решения распространенных проблем, связанных с Подключением.
Привязка
Затем Chef Automate аутентифицируется (или «привязывается») к службе LDAP с использованием кредитов привязки. В вашем файле конфигурации TOML они должны быть (например):
bind_dn = "cn=service_account,dc=corp,dc=com"
bind_password = "i<3ldap"
Если ваш сервер LDAP поддерживает анонимную привязку и вы хотите использовать её, сбросьте значения bind DN и password:
bind_dn = ""
bind_password = ""
Оборачивайте специальные символы в bind_password в тройные одинарные кавычки.
bind_password = '''$p3c"i'@l ! %#'''
См. Устранение неполадок привязки для решения распространенных проблем, связанных с Привязкой.
Поиск пользователя
После успешной привязки Chef Automate попытается получить имя каталога пользователя, который пытается войти в систему.
Для этого он выполнит поиск, используя настроенный базовый base_user_search_dn, записи, для которой username_attr равно имени пользователя, пытающегося войти в систему.
При необходимости он получит дополнительные атрибуты, используя настроенные имена (user_id_attr, email_attr, и user_display_name_attr). См. Конфигурация: LDAP для обзора.
Примечание
Команда ldapsearch командной строки, соответствующая Поиску пользователя, это
ldapsearch -h $host -D $bind_dn -w $bind_password \
-s sub \
-b $base_user_search_dn \
"($username_attr=$username)" \
$user_id_attr $user_display_name_attr $email_attr
где username — то, что было введено в поле имя пользователя в форме входа.
Предупреждение
См. Устранение неполадок поиска пользователя для решения распространенных проблем, связанных с Поиском пользователя.
Фильтрация пользователей, которые могут войти в систему
Вы можете дополнительно ограничить поиск пользователя, предоставив допустимый фильтр LDAP для user_query_filter. Например,
user_query_filter = "(objectClass=person)"
который будет конкатенирован с фильтром поиска, составленным из предоставленного имени пользователя на экране входа. Содержимое user_query_filter расширяется до (&<user_query_filter_value>), поэтому вы можете передавать несколько фильтров.
Например, если вы хотите разрешить вход только тем пользователям, которые являются членами определённой группы Active Directory, вы можете определить user_query_filter с несколькими фильтрами, такими как:
user_query_filter = "(objectClass=person)(memberof=CN=YourGroupToFilterOn,OU=Users,DC=YourDomain,DC=com)"
Этот фильтр означает «разрешить вход только тем пользователям, которые являются членами группы YourGroupToFilterOn в Chef Automate». Когда пользователь пытается войти, он будет авторизован только в том случае, если будет найден после применения фильтра:
(&(objectClass=person)(memberof=CN=YourGroupToFilterOn,OU=Users,DC=YourDomain,DC=com))
Примечание
Командная строка ldapsearch для Поиска пользователя с ограниченными группами:
ldapsearch -h $host -D $bind_dn -w $bind_password \
-s sub \
-b $base_user_search_dn \
"(&$user_query_filter($username_attr=$username))"
где username — то, что было введено в поле имени пользователя в форме входа.
См. ldapsearch Примеры запросов для примера использования ldapsearch, и различных схем каталогов.
Вход с привязкой
Когда поиск записи пользователя в каталоге завершился успешно, соединитель LDAP попытается выполнить привязку как запись пользователя, используя предоставленный пароль.
Например, если вход с использованием jane:janespassword привёл к успешному поиску пользователя, вернув cn=jane,ou=People,dc=corp,dc=com, следующим шагом будет снова привязаться с использованием этого DN и пароля janespassword.
Примечание
Командная строка ldapsearch для Поиска пользователя:
ldapsearch -h $host -D $user_dn -w $password
где user_dn — DN пользователя, возвращённого в Поиске пользователя, а password — то, что было введено в поле ввода пароля в форме входа.
Обратите внимание, что result: 32 No such object — это успешный ответ здесь, неудачная привязка при входе с использованием ldapsearch возвращает:
ldap_bind: Invalid credentials (49)
additional info: INVALID_CREDENTIALS: Bind failed: Cannot authenticate user uid=test2,ou=users,ou=system
См. Устранение неполадок при привязке входа для распространённых проблем, связанных с Sign_In_Bind.
Поиск групп
Наконец, после аутентификации пользователя его внутренний запрос дополняется группами, предоставленными LDAP. Это происходит путём выполнения другого поиска с использованием того же DN привязки и пароля, что и для поиска пользователя.
Подобно поиску пользователя, необходимо предоставить базовый DN; результат можно ограничить, предоставив дополнительный фильтр:
base_group_search_dn = "ou=Groups,dc=corp,dc=com"
group_query_filter = "(objectClass=group)"
Правильные настройки конфигурации снова зависят от схемы вашего сервера каталогов; см. примеры конфигураций ниже.
Предупреждение
base_group_search_dn необязательна. Однако, если она не предоставлена, пользователи, аутентифицированные через LDAP (или MSAD), не будут являться членами каких-либо команд.Примечание
Командная строка ldapsearch для Поиска групп:
ldapsearch -h $host -D $bind_dn -w $bind_password \
-s sub \
-b $base_group_search_dn \
"($filter_groups_by_user_attr=$user_attr)" \
$group_display_name_attr
где user_attr — $filter_groups_by_user_value пользователя, возвращённого в Поиске пользователя.
См. Устранение неполадок при поиске групп для распространённых проблем, связанных с Поиском групп.
Обзор конфигурации
Ниже представлена полная конфигурация и дополнительные сведения обо всех параметрах конфигурации LDAP.
[dex.v1.sys.connectors.ldap]
###
# Configuration for querying your LDAP server
###
ca_contents = "<your ca contents>"
host = "<your host>"
# The DN and password you wish to bind to your LDAP server to search for
# users to authenticate for Chef Automate (and also to search for their group membership).
# Example: "uid=seviceaccount,cn=users,dc=example,dc=com"
bind_dn = "<your bind_dn>"
# bind_password may also be passed via the AUTOMATE_SECRET_LDAP_PASSWORD environment
# variable when running `chef-automate` commands.
bind_password = "<your bind_password>"
###
# User Query (search for LDAP users to authenticate for Chef Automate)
###
# The base DN to start the user query.
# Chef Automate will use this as the base DN on which to search for users to authenticate against your LDAP server.
# Example: "cn=users,dc=example,dc=com"
base_user_search_dn = "<your base user search DN>"
# The LDAP field used to filter the query for users to authenticate for Chef Automate.
# Example: Setting this to "uid" would result in a filter of "(uid=<username_for_user_trying_to_authenticate>)".
username_attr = "<your username attribute>"
# Optional: LDAP query filter to apply when searching for users to authenticate.
# This will be combined with username_attr filter above.
# Example: Setting this to "(objectClass=person)" will filter on human actors only.
user_query_filter = "<your user query filter>"
###
# Populating the Chef Automate User via LDAP
###
# Determines which LDAP field populates the username in a user's Chef Automate session on successful authentication.
user_id_attr = "<your userid attribute>"
# Optional: determines which LDAP field populates the email in a user's Chef Automate session on successful authentication.
# Defaults to "user_id_attr" if not specified.
email_attr = "<your email attribute>"
# Optional: determines which LDAP field populates the display name in a user's Chef Automate session on successful authentication.
# Defaults to "name" if not specified.
user_display_name_attr = "<your user display name attribute>"
###
# Group Query (search for LDAP group membership for an authenticated user)
###
# The base DN to start the group membership query.
# Chef Automate will use this as the base DN on which to search for LDAP group membership for a specific LDAP user.
# Example: "cn=groups,dc=freeipa,dc=example,dc=com"
base_group_search_dn = "<your base group search DN>"
# The following two fields are used to match a user to a group.
# If the defaults are used, then you end up with a group membership
# filter of "(&(objectClass=group)(member=<user's DN>))".
# Optional: The LDAP field by which you wish to filter group membership.
# Defaults to "member".
filter_groups_by_user_attr = "<groups to filter by user attribute>"
# Optional: The LDAP field from the authenticated user you wish to use as input to the above filter.
# Defaults to "DN".
filter_groups_by_user_value = "<groups to filter by user value>"
# Optional: Additional LDAP filter you can define to further filter group membership results.
group_query_filter = "<your group query filter>"
# The LDAP field on the group you wish to use as the Chef Automate Team name for the group.
# Defaults to "name".
group_display_name_attr = "<group display name attribute>"
Примеры конфигураций
В зависимости от схемы вашего каталога требуются различные настройки поиска групп:
Если ваш каталог выглядит так
dn: dc=corp,dc=com
objectClass: dcObject
objectClass: organization
o: Example Company
dc: corp
dn: ou=People,dc=corp,dc=com
objectClass: organizationalUnit
ou: People
dn: cn=jane,ou=People,dc=corp,dc=com
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: jane
dn: cn=john,ou=People,dc=corp,dc=com
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: john
# Groups
dn: ou=Groups,dc=corp,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=admins,ou=Groups,dc=corp,dc=com
objectClass: groupOfNames
cn: admins
member: cn=john,ou=People,dc=corp,dc=com
member: cn=jane,ou=People,dc=corp,dc=com
dn: cn=developers,ou=Groups,dc=corp,dc=com
objectClass: groupOfNames
cn: developers
member: cn=jane,ou=People,dc=corp,dc=com
то потребуется следующее:
base_user_search = "ou=People,dc=corp,dc=com"
username_attr = "cn"
user_id_attr = "cn"
user_display_name_attr = "cn"
base_group_search = "ou=Groups,dc=corp,dc=com"
filter_groups_by_user_value = "DN"
filter_groups_by_user_attr = "member" # default
group_display_name_attr = "cn"
Однако, если ваша схема выглядит так — без списка членов в записях вашей группы:
dn: dc=corp,dc=com
objectClass: dcObject
objectClass: organization
o: Example Company
dc: corp
dn: ou=People,dc=corp,dc=com
objectClass: organizationalUnit
ou: People
dn: cn=jane,ou=People,dc=corp,dc=com
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: jane
departmentNumber: 1000
departmentNumber: 1001
dn: cn=john,ou=People,dc=corp,dc=com
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: john
departmentNumber: 1000
departmentNumber: 1002
dn: ou=Groups,dc=corp,dc=com
objectClass: organizationalUnit
ou: Groups
dn: cn=admins,ou=Groups,dc=corp,dc=com
objectClass: posixGroup
cn: admins
gidNumber: 1000
dn: cn=developers,ou=Groups,dc=corp,dc=com
objectClass: posixGroup
cn: developers
gidNumber: 1001
dn: cn=designers,ou=Groups,dc=corp,dc=com
objectClass: posixGroup
cn: designers
gidNumber: 1002
Вам потребуются другие настройки для связывания пользователей и групп:
base_user_search = "ou=People,dc=corp,dc=com"
username_attr = "cn"
user_id_attr = "cn"
user_display_name_attr = "cn"
base_group_search = "ou=Groups,dc=corp,dc=com"
filter_groups_by_user_value = "departmentNumber"
filter_groups_by_user_attr = "gidNumber"
group_display_name_attr = "cn"
Устранение неполадок
В этом разделе будут представлены некоторые индикаторы, чтобы определить, какой этап процесса входа не удался.
Устранение неполадок с подключением
Если хост или порт были неверными или Chef Automate не смог подключиться к службе LDAP, на экране входа отобразится
Ошибка внутреннего сервера
Ошибка входа.
В логах (journalctl -u chef-automate) вы найдёте строку из automate-dex.default такого вида — обратите внимание, что для наглядности временная метка и имя службы были удалены из этого примера лога:
level=error msg="Failed to login user: failed to connect: LDAP Result Code 200 \"\": dial tcp 192.168.33.223:10637: getsockopt: connection refused"
Обратите внимание, что лог содержит IP-адрес, даже если сервер LDAP был настроен через имя хоста. Проверка этого может быть полезной для исключения проблем с разрешением доменных имён.
Проблемы с проверкой TLS проявляются таким же образом, но в логе указано, что:
level=error msg="Failed to login user: failed to connect: LDAP Result Code 200 \"\": x509: certificate is valid for localhost, not dex-dev.test"
Устранение неполадок при привязке
Проблемы с привязкой проявляются таким же образом («Ошибка внутреннего сервера») как и проблемы с подключением. Однако они отличаются тем, что регистрируется:
level=error msg="Failed to login user: ldap: initial bind for user \"cn=service_account,dc=corp,dc=com\" failed: LDAP Result Code 49 \"Invalid Credentials\": "
Устранение неполадок поиска пользователя
Есть два основных способа, которыми поиск пользователя может завершиться неудачей, и они приводят к различным ошибкам входа: один — запросы, которые вообще не могут быть выполнены, что приводит к
Ошибка внутреннего сервера
Ошибка входа.
в браузере и строке, подобной
level=info msg="performing ldap search ou=Peoples,dc=example,dc=org sub (cn=jane)"
level=error msg="Failed to login user: ldap: search with filter \"(cn=jane)\" failed: LDAP Result Code 32 \"No Such Object\": "
в журналах.
Одним из возможных причин (из журналов, которые вы видите здесь) является неправильная настройка base_user_search_dn.
Когда поиск пользователя выполняется успешно, но не возвращает полезную запись пользователя, браузер отобразит запрос входа с баннером об ошибке, гласящим
Имя пользователя или пароль неверны.
В журналах вы найдёте больше информации. Есть строка, информирующая вас о фактическом запросе поиска,
level=info msg="performing ldap search ou=People,dc=corp,dc=com sub (cnn=jane)"
вместе с записью о том, что запрошенный запрос ничего не вернул:
level=error msg="ldap: no results returned for filter: \"(cnn=jane)\""
В этом примере вывода username_attr было установлено значение cnn (а не cn).
Поскольку интеграция LDAP не может определить, была ли конфигурация неверной или предоставленный пользователь не существует, пользовательский интерфейс входа может только предположить, что учётные данные неверны.
Обратите внимание, что некорректные значения для user_query_filter также приведут к запросам, возвращающим пустые записи.
Установка
user_query_filter = "(objectClass=person)"
приведёт к следующим журналам:
level=info msg="performing ldap search ou=People,dc=example,dc=org sub (&(objectClass=person(cn=jane))" connector=LDAP
level=error msg="ldap: no results returned for filter: \"(&(objectClass=person(cn=jane))\"" connector=LDAP
Предупреждение
Убедитесь, что поиск username_attr с заданным базовым поиском может вернуть только одного пользователя. Что-то вроде этого может произойти (упрощенно для демонстрации):
dn: cn=jane,ou=Denver,ou=People,dc=corp,dc=com
sn: doe
cn: jane
username: jdoe
dn: cn=john,ou=Boston,ou=People,dc=corp,dc=com
sn: doe
cn: john
username: jdoe
с
base_user_search_dn = "ou=People,dc=corp,dc=com"
username_attr = "username"
ни Джейн Доу, ни её брат не смогли войти в Chef Automate. Было бы сообщение в логах о том, что возвращено несколько пользователей.
Этого можно избежать, установив username_attr = "cn"; или ограничив base_user_search_dn, если вы хотите разрешить вход только жителям одного из этих городов.
Предупреждение
Наконец, успешный поиск пользователя записывает строку, подобную:
level=info msg="username \"jane\" mapped to entry cn=jane,ou=People,dc=corp,dc=com"
Устранение неполадок при привязке входа
Неудачи при привязке входа, которые не вызваны неверными учётными данными, приведут к
Ошибка внутреннего сервера
Ошибка входа.
сопровождаемой строкой в логе с более подробной информацией, начинающейся с Failed to sign in user.
Устранение неполадок при поиске групп
Неудачи при получении групп пользователя препятствуют их входу с
Ошибка внутреннего сервера
Ошибка входа.
и записями в логах, например
level=info msg="performing ldap search ou=Groups,dc=example,dc=org sub (member=cn=jane,ou=People,dc=example,dc=org)"
level=error msg="Failed to login user: ldap: failed to query groups: ldap: search failed: LDAP Result Code 32 \"No Such Object\": "
Это, например, то, что вы видите, когда base_group_search_dn не существует ("ou=Groups,dc=...").
Однако, в отличие от того, как работает Поиск пользователя, пустой результат от Поиска групп не помешает входу, а лишь не заполнит внутреннюю запись пользователя никакими группами.
Успешный вход вызывает записи в журнале, подобные следующим:
level=info msg="performing ldap search ou=People,dc=corp,dc=com sub (cn=jane)"
level=info msg="username \"jane\" mapped to entry cn=jane,ou=People,dc=corp,dc=com"
level=info msg="performing ldap search ou=Groups,dc=corp,dc=com sub (member=cn=jane,ou=People,dc=corp,dc=com)"
level=info msg="login successful: connector \"ldap\", username=\"jane\", email=\"janedoe@example.com\", groups=[\"admins\" \"developers\"]"
и последующие журналы запросов API авторизации, содержащие предметы пользователя:
level=info msg="Authorization Query" action=search resource="compliance:profiles" result=true subject="[team:ldap:admins team:ldap:developers user:ldap:jane]"
ldapsearch Примеры запросов
Для отладки может быть полезно выполнить запросы LDAP вручную с помощью утилиты ldapsearch. В Ubuntu она предоставляется через ldap-utils (т.е. sudo apt-get install ldap-utils). В дальнейшем мы опишем пример структуры каталога и соответствующие запросы ldapsearch для различных фаз.
Запрос Поиск пользователя выглядит так, с комментариями, относящимися к настраиваемым параметрам для интеграции LDAP:
ldapsearch -H ldap://ldap-server:636/ \ # host
-D cn=service_account,dc=corp,dc=com \ # bind_dn
-w admin \ # bind_password
-b ou=People,dc=corp,dc=com \ # base_user_search_dn
-s sub \
'(cn=jane)' # (username_attr=what-was-provided-via-sign-in-form)
При использовании анонимной привязки:
ldapsearch -H ldap://ldap-server:636/ \ # host
-b ou=People,dc=corp,dc=com \ # base_user_search_dn
-s sub \
'(cn=jane)' # (username_attr=what-was-provided-via-sign-in-form)
Если вы настроили user_query_filter, она заключена в аргумент фильтра:
'(&(objectClass=person)(cn=jane))' # (&user_query_filter(username_attr=what-was-provided-via-sign-in-form))
После получения записи пользователя, пароль может быть проверен, и запрос на поиск групп может быть составлен из него:
Предположим, что мы получили запись для пользователя jane:
# jane, People, corp.com
dn: cn=jane,ou=People,dc=corp,dc=com
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: jane
тогда проверка пароля может быть смоделирована с помощью
ldapsearch -H ldap://ldap-server:636/ \ # host
-b cn=jane,ou=People,dc=corp,dc=com \ # always the entry's DN
-w janespassword # as provided via sign in from
где любой результат, отличный от ошибки (например, 32 No such object), указывает на правильные учётные данные.
Наконец, запрос поиска групп для этой записи пользователя выглядит следующим образом:
ldapsearch -H ldap://ldapserver:636/ \ # host
-D cn=service_account,dc=corp,dc=com \ # bind_dn
-w admin \ # bind_password
-b ou=Groups,dc=corp,dc=com \ # base_group_search_dn
-s sub \
'(member=cn=jane,ou=People,dc=corp,dc=com)' # (filter_groups_by_user_attr=[that attr of user entry])
С дополнительным group_query_filter, окончательный фильтр:
'(&(objectClass=group)(member=cn=jane,ou=People,dc=corp,dc=com))' # (&group_query_filter(filter_groups_by_user_attr=[...])
Примечание: если ввод пользователя содержит более одного filter_groups_by_user_attr атрибута, будут выполнены несколько запросов, а их результаты объединены.
Другие распространённые проблемы
Если пользователь, выполнивший вход через LDAP или SAML, видит страницу ошибки
502 Bad Gateway
это означает, что информация о группе, собранная для пользователя, превысила внутренние ограничения.
Это может быть вызвано двумя причинами: у пользователя слишком много групп или ссылки на группы LDAP по их distinguished names (DN). Последнее может привести к тому, что небольшая информация (например, имя группы «admins») будет чрезмерно разрастаться (например, «cn=admins,ou=DeptA,ou=CityB,ou=StateWA,dc=subcorp,dc=corp,dc=com”). Это можно смягчить, изменив group_display_name_attr с DN на cn (общее имя). Обратите внимание, что это также рекомендуется для целей авторизации. Предоставленные LDAP группы упоминаются в политиках с помощью team:ldap:<group-name>. Таким образом, team:ldap:admins удобнее, чем team:ldap:cn=admins,ou=DeptA,ou=CityB,ou=StateWA,dc=subcorp,dc=corp,dc=com.
Другая причина, слишком большое количество групп для пользователя, может быть решена с помощью group_query_filter, чтобы ограничить результаты поиска групп (для всех пользователей). Там можно настроить всё, что выразимо в запросе поиска LDAP и поддерживается службой LDAP. Например, в случае плоского списка групп в службе каталогов, как
cn=group1,ou=Groups,dc=corp,dc=com
cn=group2,ou=Groups,dc=corp,dc=com
cn=group3,ou=Groups,dc=corp,dc=com
cn=group4,ou=Groups,dc=corp,dc=com
cn=group5,ou=Groups,dc=corp,dc=com
a group_query_filter из (|(cn=group1)(cn=group2)) ограничит результаты поиска групп по одной из этих групп. Обратите внимание, что это не влияет на то, какие пользователи проходят аутентификацию; это влияет только на группы, распознаваемые Chef Automate. Например, если у нас есть пользователи Jane и Jack, где Jane является членом group1 и group3, а Jack — group3 и group4, то группы Jane будут разрешены только до group1, а у Jack не будет групп — но он по-прежнему сможет получить доступ к Chef Automate. Аналогичным образом, выбранные группы могут быть исключены из результатов явно, используя фильтр, подобный (!cn=group2)
В случае более структурированной компоновки службы каталогов, включая несколько деревьев групп, становятся возможны дополнительные варианты: Предположим, структура выглядит как
cn=group1,ou=AGroups,dc=corp,dc=com
cn=group2,ou=AGroups,dc=corp,dc=com
cn=group3,ou=BGroups,dc=corp,dc=com
cn=group4,ou=BGroups,dc=corp,dc=com
cn=group5,ou=CGroups,dc=corp,dc=com
вы можете использовать возможности запросов вашего сервера каталогов, чтобы ограничить результаты поддеревом. Конкретные детали зависят от используемого продукта; например, на серверах, поддерживающих расширенный поиск, все записи групп ниже AGroups и BGroups можно получить, используя group_query_filter из (|(ou:dn:=AGroups)(ou:dn:=BGroups)).
См. LDAP Wiki Расширенный поиск по фильтру для получения подробной информации.
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/automate/ldap/