Один из наших заказчиков пришел к нам с запросом по комплексному импортозамещению — требовалось организовать переход на новую службу каталогов. В качестве основного решения по замене была выбрана система ALD Pro. Но по ходу проработки решения мы столкнулись с рядом сложностей. Самые большие из них были связаны с заменой компонентов AD FS и публикацией веб-сервисов с помощью WAP. В этом посте рассказываем, как мы решали эту задачу.
Основная связка, на которой мы собирали альтернативную схему, представляла собой Keycloak для авторизации и NGINX для балансировки запросов. В ходе проекта использовались реальные системы заказчика, но для тестирования мы выбрали синтетическую систему на базе Grafana — для эмуляции.
Чтобы понять, что к чему, посмотрим на схему нашего кейса. Цифрами обозначена последовательность прохождения запросов-ответов от клиента и обратно для авторизации в Grafana.
![Схема сетевого взаимодействия синтетического пилотного сегмента ALD Pro Схема сетевого взаимодействия синтетического пилотного сегмента ALD Pro](https://habrastorage.org/getpro/habr/upload_files/ff1/98e/467/ff198e467861dfba5cb3ec2230bd6e2d.jpg)
Клиент и все серверы находятся в домене ALD Pro.
Задача следующая: клиенту на PC (172.99.27.12) необходимо авторизоваться и получить доступ к ИС (Grafana, 172.99.26.22) в домене ALD с помощью сервиса Keycloak (172.99.26.21). При этом клиент находится в другой подсети. В качестве прокси-сервера используется NGINX с двумя сетевыми интерфейсами.
Давайте поэтапно пройдемся по настройке всех компонентов.
1. Подключение Keycloak к ALD Pro LDAP
Далее представлена пошаговая настройка для варианта с ALD Pro LDAP.
Переходим в меню: adrealm→ User federation → Add new provider → LDAP.
![](https://habrastorage.org/getpro/habr/upload_files/451/006/178/4510061785062a947ddbf21b42ea9eb2.png)
![](https://habrastorage.org/getpro/habr/upload_files/11d/77b/67f/11d77b67fd0660a1722be6edb52676e6.png)
![](https://habrastorage.org/getpro/habr/upload_files/335/7bd/0db/3357bd0db26b6689d283cc146a27c359.png)
![](https://habrastorage.org/getpro/habr/upload_files/2b1/a77/9b7/2b1a779b7dd396e417366d83eadb53fb.png)
Ниже пример настроек группового маппера для ALD.
![](https://habrastorage.org/getpro/habr/upload_files/bec/e4c/fc4/bece4cfc4e0ea7d3e0462201710b5c1d.png)
![](https://habrastorage.org/getpro/habr/upload_files/502/aa1/223/502aa1223c735319b9a311da42e9d047.png)
После настройки необходимо проверить корректность с помощью меню: Action→ Sync LDAP groups to Keycloak.
![](https://habrastorage.org/getpro/habr/upload_files/b6f/e06/795/b6fe06795cece64d52b8b36627e7a301.png)
2. Настройка авторизации для клиентских приложений
На этом этапе мы ориентировались на инструкцию из статьи на Хабре: Keycloak. Админский фактор и запрет аутентификации (кейс № 2).
Ниже итоговые настройки браузерного потока (они отличаются от предложенных в статье). В процессе настройки потока мы пришли именно к такому порядку шагов:
![](https://habrastorage.org/getpro/habr/upload_files/cee/8f4/c9c/cee8f4c9c354f6e5b8bd394a82d8f535.png)
3. Настройка Keycloak для связки с Grafana
На консоли Keycloak переходим в меню → Clients → Create client.
Далее создаем клиента как на рисунках ниже.
![](https://habrastorage.org/getpro/habr/upload_files/b7b/7bb/749/b7b7bb7496cc2a7562b32edb96611dc3.png)
![](https://habrastorage.org/getpro/habr/upload_files/8f0/faa/954/8f0faa9548f4beb57f48fb978bafdee7.png)
![](https://habrastorage.org/getpro/habr/upload_files/109/19f/5bc/10919f5bc161bcb4b5b063937731bc30.png)
![](https://habrastorage.org/getpro/habr/upload_files/cb5/d4b/688/cb5d4b688cbe98632ba4df5c3cc34dfa.png)
Потом переходим в настройки созданного клиента на вкладку Credentials, сохраняем Client Secret. Он понадобится в дальнейшем при настройке со стороны клиентского приложения.
![](https://habrastorage.org/getpro/habr/upload_files/f5f/0ff/0e0/f5f0ff0e0c9199b35107635634ec65e2.png)
Копируем endpoint-ссылки, куда будет обращаться Grafana для аутентификации пользователей. Для этого переходим в меню → Realm settings → OpenID Endpoint Configuration.
![](https://habrastorage.org/getpro/habr/upload_files/b7c/51d/2fc/b7c51d2fc9e330dc2e420cb6df89f9a6.png)
Нас интересуют те, которые оканчиваются на auth, token, userinfo.
![](https://habrastorage.org/getpro/habr/upload_files/d47/b28/a1e/d47b28a1e1e1215bb4ecf0ef460ada15.png)
4. Запуск Keycloak
Основная настройка заключается в параметре запуска сервиса Keycloak:
/opt/keycloak/keycloak-22.0.1/bin/kc.sh start --hostname aldbln01.int:1024
--http-relative-path /key --hostname-admin-
url=https://aldbln01.int:1024/key/
Если после запуска команды kc.sh start Keycloak попросит выполнить сборку с новыми параметрами, то необходимо выполнить команду: */kc.sh build.
Параметр --hostname означает url, по которому будет работать Keycloak. В параметре --hostname устанавливаем имя нашего прокси-сервера (NGINX) и порт, который он будет прослушивать (aldbln01.int:1024).
Параметр --http-relative-path должен совпадать с названием локации в NGINX (в нашем случае /key), из которой будет работать сервис.
Параметр --hostname-admin-url требуется для доступа к админской консоли. Задаем вручную ее url (https://aldbln01.int:1024/key/).
5. Настройка NGINX
Устанавливаем NGINX из репозитория с помощью команды apt install nginx -y (в нашем стенде ОС Astra SE 1.7.4). В директории etc/nginx/sites-enabled переносим или переименовываем стандартный файл конфигурации, а затем создаем в нем новый файл aldbln.conf. Ниже описание конфигурации в файле aldbln.conf:
server {
listen 80;
listen 1024 ssl default_server;
ssl_certificate /etc/nginx/Cert.pem;
ssl_certificate_key /etc/nginx/Key.pem;
server_name aldbln01.ald.int;
location /key {
proxy_pass https://aldkeycl01.ald.int;
}
location /grafana/ {
proxy_pass http://aldweb01.ald.int:3000;
}
}
Для работы по протоколу https достаточно выпустить ключ и самоподписанный сертификат на его основе.
Для работы с Grafana прослушиваются http 80 и https 1024 порты (порт 1024 взят для теста, по умолчанию можно использовать 443). Запрос пользователя перенаправляется (proxy_pass) на доменное имя Grafana web01:3000 (при указании в адресе запроса http(s):// nlb/grafana).
Пример: https://aldbln01.ald.int/grafana.
Для Keycloak также прослушиваются http 80 и https 1024 порты (порт 1024 взят для теста, по умолчанию можно использовать 443) и перенаправляется в локацию (/key), если такой путь присутствует в http-запросе.
Пример: https://aldbln01.ald.int/key.
6. Настройка Grafana
Все настройки Grafana прописываются в конфигурационном файле /etc/grafana/grafana.ini.
Добавляем раздел с OAuth-аутентификацией в любое место (но не в середину другого раздела). В примере он расположен сразу после секции [server]):
#exampleHeader1 = exampleValue1
#exampleHeader2 = exampleValue2// конец раздела server, копировать не нужно
########ADDED FOR KEYCLOAK############
[auth.generic_oauth]
enabled = true
scopes = profile email openid
email_attribute_path = email
login_attribute_path = username
name_attribute_path = full_name
oauth_allow_insecure_email_lookup = true
name =Keycloak-OAuth
tls_skip_verify_insecure = true
allow_sign_up = true
client_id = grafana2
client_secret = OEHvGwD***********8vHb
auth_url = https://aldbln01.ald.int/realms/adrealm/protocol/openid-connect/auth
token_url = https://aldkeycl01.ald.int/realms/adrealm/protocol/openid-connect/token
api_url = https://aldkeycl01.ald.int/realms/adrealm/protocol/openid-connect/userinfo
__________________________________________
Параметр scopes проверяет области из KeyCloak. Доступные области можно
посмотреть в административной консоли KeyCloak в разделе "Client scopes"
*_attribute_path — пути к атрибутам, которые будет проверять Grafana. При
кастомных названиях можно поменять их в соответствии с названиями атрибутов в KeyCloak.
Параметр client_id должен соответствовать ID клиента в KeyCloak.
Параметр client_secret — необходимо вставить тот секрет, который сохраняли ранее
*_url — скопировать точные ссылки на endpoint, которые ранее видели в KeyCloak.
...
domain = aldweb01.ald.int
...
http_port = 3000
...
root_url = http://aldbln01.ald.int/grafana/
...
serve_from_sub_path = true
...
auth_url = https://aldbln01.ald.int:1024/key/realms/adrealm/protocol/openid-connect/auth
token_url = https://aldkeycl01.ald.int/key/realms/adrealm/protocol/openid-connect/token
api_url = https://aldkeycl01.ald.int/key/realms/adrealm/protocol/openid-connect/userinfo
...
signout_redirect_url = https://aldbln01.ald.int:1024/key/realms/adrealm/protocol/openid-connect/logout?post_logout_redirect_uri=http://aldbln01.ald.int/grafana&client_id=grafana2
__________________________________________
Параметр domain — прописать имя хоста, где работает сервис grafana.
Параметр http_port должен соответствовать тому, который указан на прокси сервере Nginx.
Параметр root_url — из него Grafana генерирует redirect url при запросе в KeyCloack,
а как мы помним пользователь находится в другой подсети, так что здесь
указывается «прокси» имя.
Параметр serve_from_sub_path задается, чтобы Grafana могла работать из
локации /grafana. (как в нашем примере)
Параметр auth_url — та ссылка, по которой Grafana перенаправит пользователя
для аутентификации и ввода логина/пароля. Так что она должна проксироваться.
Параметр token_url ,api_url — бэковые endpoint, по которым Grafana будет обращаться
напрямую в Keycloack. Скопировать их из OpenID endpoint из консоли
администратора Keycloack.
Параметр signout_redirect_url (если что, это все одна строка) — ссылка, по которой
Grafana перенаправит пользователя, когда он нажмет кнопку signout. Чтобы успешно
попасть на форму логаута в KeyCloack, затем вернуться в Grafana (а не застрять
в межинтернетном пространстве) и проксировать оба адреса.
Также важно внести изменения в секцию Server, т. к. настройки по умолчанию будут редиректить на localhost. Необходимо не только записать нужное значение, а также убрать «;» в начале строки.
[server]
# Protocol (http, https, h2, socket)
protocol = http
# This is the minimum TLS version allowed. By default, this value is empty.
Accepted values are: TLS1.2, TLS1.3. If nothing is set TLS1.2 would be taken
;min_tls_version = ""
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
# The http port to use
http_port = number of your port
# The public facing domain name used to access grafana from a browser
domain = yourhostname.example.com
# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false
# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
Далее нужно сохранить все изменения и перезагрузить Grafana. На странице входа должна появиться новая кнопка с OAuth-аутентификацией:
![](https://habrastorage.org/getpro/habr/upload_files/f63/954/fe3/f63954fe341bdb774d83011c55b08dec.png)
7. Проверка работы
![](https://habrastorage.org/getpro/habr/upload_files/05d/b43/a1d/05db43a1d9d9057d029eb366f6aa6e54.png)
По адресу прокси /grafana должна открыться консоль Grafana с сервера aldweb01. Остается нажать кнопку «Sign in with Keycloak».
![](https://habrastorage.org/getpro/habr/upload_files/575/e63/425/575e6342578f4d6c4a7420c696d4ce18.png)
Откроется страница аутентификации, которая указана в настройках Grafana (auth_url). Далее вносим учетные данные пользователя ALD Pro.
![](https://habrastorage.org/getpro/habr/upload_files/39d/8f7/e82/39d8f7e829b40b69266e87673d26f7a7.png)
Благодаря параметру root-url в настройках Grafana Keycloak успешно вернет пользователя назад в Grafana уже авторизованным. Теперь осталось нажать кнопку «Выйти из аккаунта».
![](https://habrastorage.org/getpro/habr/upload_files/e97/d06/8bb/e97d068bb6568d4974c27135a27c1c43.png)
Grafana переведет по ссылке, которая указана в параметре signout_redirect_url.
![](https://habrastorage.org/getpro/habr/upload_files/5c0/8aa/e18/5c08aae18baad76e1e45e96cd1c11b2a.png)
Выход произведен успешно! Ура!
Вместо заключения
В этой статье мы рассмотрели только основной костяк решения. Для боевых внедрений надо настраивать кластер балансировщиков, реализовывать роуминг VIP-адресов, выбирать метод балансировки между бекэндами. Сам Keycloak необходимо реализовывать в режиме высокой доступности, но это уже детали.
На выходе мы получили решение, которое помогло разобраться с основной задачей. Появилась возможность публиковать корпоративные сервисы c использованием службы единого входа. Это позволяет нашим заказчикам переходить на импортозамещенные службы каталогов, в частности, ALD Pro, и при этом не беспокоиться за работу сервисов, которые с ней интегрированы.
Это решение и многие другие можно детально посмотреть на нашем стенде импортозамещения.
Александр Козлов
Инженер-проектировщик вычислительных комплексов
Григорий Эктов
Инженер внедрения отдела биометрических технологий и систем аутентификации