Неудачная LDAP аутентификация

Введение

Сразу отмечу, что в качестве Веб-интерфейса я использую OpenSearch-Dashboards. И в основном именно для OpenSearch-Dashboards мне нужна доменная авторизация.

Для того, чтобы настроить аутентификацию и авторизацию доменных пользователей Active Directory в OpenSearch по протоколу LDAP необходимо сконфигурировать файл «/plugins/opensearch-security/securityconfig/config.yml» (в моем случае полный путь к этому файлу такой «/opt/opensearch/plugins/opensearch-security/securityconfig/config.yml»).

Предисловие

Эта статья является продолжением статьи

. Однако, тема этой статьи достаточно узкая и практически не зависит от основной настройки всего стека OpenSearch (материала первой статьи). Поэтому эту статью можно считать самостоятельной.

. Послесловие


На этом всё. Всем спасибо за внимание к статье, надеюсь она окажется для кого-то полезной.

Коротко об объектах настройки конфиденциальности в OpenSearch

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

Каждая учетная запись может иметь набор прав доступов, которые наделяют пользователя полномочиями.

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


Например, если дать права администратора и наблюдателя одновременно, то фактически пользователь будет иметь права администратора.

А вот «Backend» роль сущность несколько абстрактная. «Обычная» роль может иметь «Backend» роль или даже несколько «Backend» ролей. Пользователь тоже может иметь «Backend» роль или даже несколько «Backend» ролей. Если «Backend» роль есть у пользователя, и эта же «Backend» роль есть у «обычной» роли, то такой пользователь становится обладателем этой «обычной» роли.

«Backend» роли становятся актуальными для использования при доменной авторизации. Потому как доменные пользователи не доступны для настройки прав или «обычных» ролей, они могут получить только «Backend» роль автоматически, в зависимости от настроенной конфигурации.

Настройка LDAP


Для наглядности я сразу приведу уже сконфигурированный файл «config.yml» целиком (в моем случае это файл «/opt/opensearch/plugins/opensearch-security/securityconfig/config.yml»).

/opt/opensearch/plugins/opensearch-security/securityconfig/config.yml

---
# This is the main OpenSearch Security configuration file where authentication
# and authorization is defined.
_meta: type: "config" config_version: 2
config: dynamic: # Set filtered_alias_mode to 'disallow' to forbid more than 2 filtered aliases per index # Set filtered_alias_mode to 'warn' to allow more than 2 filtered aliases per index but warns about it (default) # Set filtered_alias_mode to 'nowarn' to allow more than 2 filtered aliases per index silently #filtered_alias_mode: warn #do_not_fail_on_forbidden: false #kibana: # Kibana multitenancy #multitenancy_enabled: true #server_username: kibanaserver #index: '.kibana' http: anonymous_auth_enabled: false xff: enabled: false internalProxies: '192.168.0.10|192.168.0.11' # regex pattern #internalProxies: '.*' # trust all internal proxies, regex pattern #remoteIpHeader: 'x-forwarded-for' ###### see https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for regex help ###### more information about XFF https://en.wikipedia.org/wiki/X-Forwarded-For ###### and here https://tools.ietf.org/html/rfc7239 ###### and https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve authc: kerberos_auth_domain: http_enabled: false transport_enabled: false order: 6 http_authenticator: type: kerberos challenge: true config: # If true a lot of kerberos/security related debugging output will be logged to standard out krb_debug: false # If true then the realm will be stripped from the user name strip_realm_from_principal: true authentication_backend: type: noop basic_internal_auth_domain: description: "Authenticate via HTTP Basic against internal users database" http_enabled: true transport_enabled: true order: 4 http_authenticator: type: basic challenge: true authentication_backend: type: intern proxy_auth_domain: description: "Authenticate via proxy" http_enabled: false transport_enabled: false order: 3 http_authenticator: type: proxy challenge: false config: user_header: "x-proxy-user" roles_header: "x-proxy-roles" authentication_backend: type: noop jwt_auth_domain: description: "Authenticate via Json Web Token" http_enabled: false transport_enabled: false order: 0 http_authenticator: type: jwt challenge: false config: signing_key: "base64 encoded HMAC key or public RSA/ECDSA pem key" jwt_header: "Authorization" jwt_url_parameter: null roles_key: null subject_key: null authentication_backend: type: noop clientcert_auth_domain: description: "Authenticate via SSL client certificates" http_enabled: false transport_enabled: false order: 2 http_authenticator: type: clientcert config: username_attribute: cn #optional, if omitted DN becomes username challenge: false authentication_backend: type: noop ldap: description: "Authenticate via LDAP or Active Directory" http_enabled: true transport_enabled: false order: 5 http_authenticator: type: basic challenge: false authentication_backend: # LDAP authentication backend (authenticate users against a LDAP or Active Directory) type: ldap config: # enable ldaps enable_ssl: false # enable start tls, enable_ssl should be false enable_start_tls: false # send client certificate enable_ssl_client_auth: false # verify ldap hostname verify_hostnames: true hosts: - server-ad.my.big.domain:389 bind_dn: 'cn=user_for_LDAP,ou=Service Accounts,ou=Moscow,dc=MY,dc=BIG,dc=DOMAIN' password: 'Au5dUJ9q!54S' users: 1-userbase: base: 'CN=Пушкин Александр Сергеевич (PushkinAS),OU=Users,OU=Saint_Petersburg,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' 2-userbase: base: 'CN=Горький Максим (GorkiiM),OU=Users,OU=Nizhny_Novgorod,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' 3-userbase: base: 'CN=Толстой Лев Николаевич (TolstoiLN),OU=Users,OU=Yasnaya_Polyana,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' username_attribute: 'cn' authz: roles_from_myldap: description: "Authorize via LDAP or Active Directory" http_enabled: true transport_enabled: false authorization_backend: # LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too) type: ldap config: # enable ldaps enable_ssl: false # enable start tls, enable_ssl should be false enable_start_tls: false # send client certificate enable_ssl_client_auth: false # verify ldap hostname verify_hostnames: true hosts: - server-ad.my.big.domain:389 bind_dn: 'cn=user_for_LDAP,ou=Service Accounts,ou=Moscow,dc=MY,dc=BIG,dc=DOMAIN' password: 'Au5dUJ9q!54S' users: 1-userbase: base: 'CN=Пушкин Александр Сергеевич (PushkinAS),OU=Users,OU=Saint_Petersburg,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' 2-userbase: base: 'CN=Горький Максим (GorkiiM),OU=Users,OU=Nizhny_Novgorod,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' 3-userbase: base: 'CN=Толстой Лев Николаевич (TolstoiLN),OU=Users,OU=Yasnaya_Polyana,DC=MY,DC=BIG,DC=DOMAIN' search: '(sAMAccountName={0})' username_attribute: 'cn' roles: 1-rolebase: base: 'CN=Department05-Developers,OU=Groups,OU=Moscow,DC=MY,DC=BIG,DC=DOMAIN' search: '(member={0})' 2-rolebase: base: 'CN=Department05-Admins,OU=Groups,OU=Moscow,DC=MY,DC=BIG,DC=DOMAIN' search: '(member={0})' 3-rolebase: base: 'CN=Department05-Analysts,OU=Groups,OU=Moscow,DC=MY,DC=BIG,DC=DOMAIN' search: '(member={0})' userroleattribute: null userrolename: memberOf, SamAccountName rolename: "cn" resolve_nested_roles: false roles_from_another_ldap: description: "Authorize via another Active Directory" http_enabled: false transport_enabled: false authorization_backend: type: ldap

Описание всех параметров вы можете посмотреть на официальном сайте OpenSearch (

Получаем полный путь к объектам в AD

Полный путь к группе в AD через PowerShell можно получить так:

$group = ([adsisearcher]“(&(objectcategory=group)(cn=name_of_group))”).Findall()
$group


Вместо «name_of_group» подставьте название нужной вам группы.

Полный путь к пользователю в AD через PowerShell можно получить так:

Проблема применения настроек

Выполнение команды для применения настроек удаляет все изменения, сделанные в OpenSearch-Dashboards в разделе «Security», то есть все настройки пользователей и ролей. И это является проблемой, так как в конфигурацию со временем будет необходимо добавлять новых пользователей и удалять старых пользователей.

Видимо разработчики OpenSearch всё же подразумевают, что все пользователи в AD лежат в одном каталоге и «лишних» пользователей там нет. Либо всё-таки подразумевается использование проксирующего LDAP сервера. Другого объяснения я не нашел.


Для того чтобы обойти эту проблему можно вносить изменения не в Web-интерфейсе (OpenSearch-Dashboards), а через файлы конфигураций.

Далее опишу настройку конфигурационных файлов.

Разработка тихого монстра

Задача прилетела в работу через месяц. К этому времени я уже немного размялся на формошлёпстве и почитал про LDAP. Первый прототип получился за 1-2 недели.

Он состоял из небольшого количества JS-кода и двух простейших AJAX-запросов на фронте, а также одного простенького servlet’a на бэке. Использовал я SPNEGO/Kerberos, найдя какую-то захудалую JAR’ку в интернете.

При входе пользователя в систему его перекидывало на login-форму, там то фоном и шёл один из AJAX-запросов, который проверял, кто пришёл и привязана ли его учётка Active Directory к учётной записи в приложении.

Серые тучи несовместимости

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

У большинства пользователей фича не просто не работала, но и крашила все приложения. В основном это было связано с очень старыми версиями IE и Windows на компьютерах сотрудников. Ведь тестировал-то всё это дело ИТ-отдел, а у нас у всех свежая винда, обновления, браузеры.

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

Так вот, поговорим про баги и их фиксы или безысходность.

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

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

За всё время работы в компании я периодически мониторил метрики использования данной фичи. Вроде как успешно ей пользовалось не более 5-10% пользователей. Надеюсь, теперь у большинства пользователей эта аутентификация работает. Или хотя бы не мешает им жить. Ещё надеюсь, что я немного сгустил краски и на самом деле всё было не так плохо.

В итоге эти запланированные 10 дней вылились в 1-2 месяца насыщенной разработки и настройки и ещё в полгода-год болезненной поддержки.

***

Эту историю наш пользователь написал в рамках участия в конкурсе, посвящённому #фичавгусту, который мы проводим вместе с OTUS. Его участники рассказывают на страницах нашего сайта про самую интересную/смешную/странную/тупую фичу, которую вам доводилось реализовывать. Победителей мы выберем по рейтингу, который будет сформирован на основании оценок пользователей и редакции сайта.

Если вам понравилась эта история, проголосуйте за неё.

Под постом есть блок с реакциями. Если история вам понравилась, ставьте палец вверх. Только эти реакции будут учитываться при составлении рейтинга. Другие эмоции подсчитываться не будут.

А вот история другого участника — он написал кастомный шрифт ради одного символа. Но сначала неделю страдал.

Похожее:  ✔️ — отзывы о сайте, обсуждение и комментарии, похожие сайты, рейтинг, стоимость, доход и количество посетителей сайта, mylms официальный сайт и форум, вход в личный кабинет, анализ сайта онлайн на RANKW.RU