Как мы реализовали авторизацию пользователей ALD Pro через Keycloack на примере Grafana

Один из наших заказчиков пришел к нам с запросом по комплексному импортозамещению — требовалось организовать переход на новую службу каталогов. В качестве основного решения по замене была выбрана система ALD Pro. Но по ходу проработки решения мы столкнулись с рядом сложностей. Самые большие из них были связаны с заменой компонентов AD FS и публикацией веб-сервисов с помощью WAP. В этом посте рассказываем, как мы решали эту задачу.

Основная связка, на которой мы собирали альтернативную схему, представляла собой Keycloack для авторизации и NGINX для балансировки запросов. В ходе проекта использовались реальные системы заказчика, но для тестирования мы выбрали синтетическую систему на базе Grafana — для эмуляции.

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

Схема сетевого взаимодействия синтетического пилотного сегмента ALD Pro

Схема сетевого взаимодействия синтетического пилотного сегмента ALD Pro

Клиент и все серверы находятся в домене 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.

4510061785062a947ddbf21b42ea9eb2.png11d77b67fd0660a1722be6edb52676e6.png3357bd0db26b6689d283cc146a27c359.png2b1a779b7dd396e417366d83eadb53fb.png

Ниже пример настроек группового маппера для ALD.

bece4cfc4e0ea7d3e0462201710b5c1d.png502aa1223c735319b9a311da42e9d047.png

После настройки необходимо проверить корректность с помощью меню: Action→ Sync LDAP groups to Keycloak.

b6fe06795cece64d52b8b36627e7a301.png

2. Настройка авторизации для клиентских приложений

На этом этапе мы ориентировались на инструкцию из статьи на Хабре: Keycloak. Админский фактор и запрет аутентификации (кейс № 2).

Ниже итоговые настройки браузерного потока (они отличаются от предложенных в статье). В процессе настройки потока мы пришли именно к такому порядку шагов:

cee8f4c9c354f6e5b8bd394a82d8f535.png

3. Настройка Keycloak для связки с Grafana

В консоли Grafana переходим в меню → Clients → Create client.

Далее создаем клиента как на рисунках ниже.

b7b7bb7496cc2a7562b32edb96611dc3.png8f0faa9548f4beb57f48fb978bafdee7.png10919f5bc161bcb4b5b063937731bc30.pngcb5d4b688cbe98632ba4df5c3cc34dfa.png

Потом переходим в настройки созданного клиента на вкладку Credentials, сохраняем Client Secret. Он понадобится в дальнейшем при настройке со стороны клиентского приложения.

f5f0ff0e0c9199b35107635634ec65e2.png

Копируем endpoint-ссылки, куда будет обращаться Grafana для аутентификации пользователей. Для этого переходим в меню → Realm settings → OpenID Endpoint Configuration.

b7c51d2fc9e330dc2e420cb6df89f9a6.png

Нас интересуют те, которые оканчиваются на auth, token, userinfo.

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-аутентификацией:

f63954fe341bdb774d83011c55b08dec.png

7. Проверка работы

05db43a1d9d9057d029eb366f6aa6e54.png

По адресу прокси /grafana должна открыться консоль Grafana с сервера aldweb01. Остается нажать кнопку «Sign in with Keycloak».

575e6342578f4d6c4a7420c696d4ce18.png

Откроется страница аутентификации, которая указана в настройках Grafana (auth_url). Далее вносим учетные данные пользователя ALD Pro.

39d8f7e829b40b69266e87673d26f7a7.png

Благодаря параметру root-url в настройках Grafana Keycloak успешно вернет пользователя назад в Grafana уже авторизованным. Теперь осталось нажать кнопку «Выйти из аккаунта».

e97d068bb6568d4974c27135a27c1c43.png

Grafana переведет по ссылке, которая указана в параметре signout_redirect_url.

5c08aae18baad76e1e45e96cd1c11b2a.png

Выход произведен успешно! Ура!

Вместо заключения

В этой статье мы рассмотрели только основной костяк решения. Для боевых внедрений надо настраивать кластер балансировщиков, реализовывать роуминг VIP-адресов, выбирать метод балансировки между бекэндами. Сам Keycloak необходимо реализовывать в режиме высокой доступности, но это уже детали.

На выходе мы получили решение, которое помогло разобраться с основной задачей. Появилась возможность публиковать корпоративные сервисы c использованием службы единого входа. Это позволяет нашим заказчикам переходить на импортозамещенные службы каталогов, в частности, ALD Pro, и при этом не беспокоиться за работу сервисов, которые с ней интегрированы.   

Это решение и многие другие можно детально посмотреть на нашем стенде импортозамещения.

Александр Козлов

Инженер-проектировщик вычислительных комплексов

Григорий Эктов

Инженер внедрения отдела биометрических технологий и систем аутентификации

© Habrahabr.ru