Matrix Element и Jitsi с прозрачной авторизацией и аватаром

от автора

Введение

В одной небольшой организации, плотно сидевшей на продуктах майкрософт, для коммуникаций использовался lync (skype), интегрированный с AD. В один момент руководству надоел аська-стайл мессенджер. К тому же вызывало дикое раздражение обмен картинками в lync — захотел передал, захотел не передал, в групповых чатах картинки вообще непонятно где прятались. Решили перейти на современные.

Итак, задача — мессенджер и ВКС, но чтобы запускался как lync с полным именем и аватаром, без запроса логинов и паролей.

Выбор пал на matrix element и jitsi. Не буду описывать нудные критерии выбора, в сети много обзоров.

Все данные о пользователях хранятся в AD, значит авторизация по kerberos, а данные получаем по ldap. Нас интересует конкретно только три параметра — полное имя, почта, аватар.

Вводные данные:

  • сервер — linux debian

  • клиент — matrix element

  • matrix сервер — synapse с авторизацией oidc

  • провайдер авторизации — keycloak

  • ВКС — jitsi

  • web сервер — apache

Сервер предварительно вводим в домен и генерируем keytab файл. Я сделал это двумя командами:

$ net ads join $ net ads keytab add http/m.example.local@EXAMLE.LOCAL 

Не принципиально как это делать, главное, чтобы у нас в системе был файл /etc/krb5.keytab с server principal = http/m.example.local@EXAMPLE.LOCAL.
В тексте ниже опустим описание установок задействованных приложений, в интернете уйма руководств, не будем засорять пространство.

Установка keycloak

Устанавливаем согласно официальной документации, ничего сложного нет.
Создаем в интерфейсе администрирования новый realm с именем synapse. В новом realm создаем клиента с именем synapse, включаем Client authentication и Authorization в ON, остальное по-умолчанию. Запоминаем, что во вкладке Credentials находится ClientSecret, который нам пригодится позже.

Идем в Identity providers, создаем новый с Alias=synapse, Client ID=synapse. Остальное по умолчанию.

Идем в User federation, добавляем LDAP провайдера, в нем стандартные параметры топопривязки ldap — server, bind dn и т.д. Главное включаем kerberos, здесь как раз пригодился Server principal из введения.

Не забываем, что нужна фотография для аватара пользователя, поэтому переключаемся на вкладку Mappers и добавляем mapper с именем picture. Ldap атрибут wWWHomePage содержит ссылку на jpeg фото пользователя. Остальные значения имени и почты там уже присутствуют.

Установка synapse

Устанавливаем согласно официальной документации, тут тоже все без сложностей. В данной ситуации нас интересует только интеграция с keycloak. Параметр client_secret берем из установки keycloak. В ip_range_whitelist добавляем локальные сети, без этого synapse не будет качать фото из picture_template.

ip_range_whitelist:   - '172.16.0.0/12'   - '192.168.0.0/16'  oidc_providers:   - idp_id: keycloak     idp_name: "EXAMPLE"     issuer: "https://m.example.local:8443/realms/synapse"     client_id: "synapse"     # секрет берем из установки keycloak     client_secret: "АБРАКАДАБРА"     scopes: ["openid", "profile"]     user_mapping_provider:       config:         localpart_template: "{{ user.preferred_username }}"         display_name_template: "{{ user.given_name }}"         email_template: "{{ user.email }}"         # именно picture как в mapper установки keycloak          picture_template: "{{ user.picture }}"     backchannel_logout_enabled: false     allow_existing_users: true 

Установка jitsi

Ну все как обычно — официальная документация, сложностей ноль. В качестве web сервера выбираем apache с доменным именем v.example.local.

После установки отключаем опцию prejoin. Нам не надо запрашивать имя пользователя, ведь мы все делаем автоматически.

На будущее в файле /etc/jitsi/meet/${HOSTNAME}-config.js зададим параметр для gravatar. Просто так.

    prejoinConfig: {          enabled: false,     },      gravatar: {          baseUrl: 'https://va.example.local/avatar/',     }, 

Клиент element

Запускаем с параметром —profile на директорию, содержащую файл config.json:

{     "default_server_config": {         "m.homeserver": {             "base_url": "https://m.example.local",             "server_name": "m.example.local"         }     },     "disable_custom_urls": true,     "disable_guests": true,     "disable_login_language_selector": false,     "disable_3pid_login": true,     "force_verification": false,     "default_country_code": "RU",     "default_federate": false,     "default_theme": "dark",     "permalinkPrefix": "https://m.example.local",     "room_directory": {         "servers": ["m.example.local"]     },     "jitsi": {         "preferred_domain": "v.example.local"     } } 

Запускаем.
Выбираем “Продолжить с EXAMPLE”.

Continue.

Виола!
Клиент запустился, подтянул имя пользователя, почту, аватар и при этом ничего не просил вводить руками, просто два клика. Проверяем виджет с групповой видеоконференцией. Тоже все работает как надо. Имя и аватар на месте.

Можно сдавать проект? А вот и нет. Руководство хочет отдельно пользоваться ВКС без запуска виджета в element.

Настройка jitsi

Вернее до-настройка.
После погружения в тему выяснилось, что jitsi у себя не хранит полное имя, почту и аватар. Даже при настройке авторизации через ldap не подтягивает оттуда ничего. Все эти три параметра динамические и задаются в строке url через якори, а якори не передаются на сторону сервера.
Решаю создать еще один виртуальный хост с авторизацией kerberos — va.example.local. Сначала думал добавить модуль mod_gssapi в apache, он возвращает principal имя и по нему задавать фильтр для выборки из ldap полного имени и фото пользователя и потом перенаправлять на v.example.local с якорями. Но потом вспомнил, что у нас же есть уже настроенный keycloak, значит ставим модуль mod-auth-openidc, который сразу отдает все значения в переменные окружения веб сервера. Пишем временный cgi скрипт для вывода переменных. Вот же они все, начинаются на OIDC_CLAIM_*. Бери и пользуйся.

Запускаем виртуальный хост на apache. Идея такая — пользователь заходит на https://va.example.local, модуль mod-auth-openidc его прозрачно авторизует и сразу работает перенаправление на v.example.local с якорями имени и почты. Аватар jitsi скачает с адреса в параметре gravatar.baseUrl, а он у нас уже задан при установке jitsi.

<VirtualHost *:443>     ServerName va.example.local      DocumentRoot /var/www/va       # ...     # ... стандартные настройки для SSL, логов и т.д.     # ...      OIDCProviderMetadataURL https://m.example.local:8443/realms/synapse/.well-known/openid-configuration     OIDCRedirectURI https://va.example.local/private     OIDCCryptoPassphrase some_password     OIDCClientID synapse     # здесь указываем секрет из установки keycloak,      # он такой же как client_secret в synapse     OIDCClientSecret АБРАКАДАБРА     OIDCProviderTokenEndpointAuth client_secret_basic     OIDCRemoteUserClaim email     OIDCScope "openid email"     OIDCPassClaimsAs environment none      <Location />         AuthType openid-connect         Require valid-user     </Location>      ScriptAlias "/index.cgi" "/var/www/va/index.cgi"     RewriteEngine on     RewriteRule ^/([a-zA-Z0-9]+)$ /index.cgi [PT] </VirtualHost> 

Создаем cgi скрипт /var/www/va/index.cgi. Здесь на bash, но можно написать на чем угодно. Хэш для фейкового gravatar-а считаю MD5, потому что jitsi почему-то по нему обращается, хотя везде в руководствах написано SHA256.

#!/bin/bash  # disable filename globbing set -f  echo "Content-type: text/html; charset=utf-8" echo   # должны быть права на запись в директорию /var/www/va [ -d /var/www/va/avatar/photo ] || mkdir -p /var/www/va/avatar/photo   # качаем jpg файл с фото пользователя /usr/bin/wget -q -nc --timeout=5 --no-proxy --directory-prefix /var/www/va/avatar/photo/ "$OIDC_CLAIM_picture"   # считаем MD5 сумму почтового адреса  HASHMD5=`echo -n "$OIDC_CLAIM_email" | /usr/bin/md5sum | /usr/bin/awk '{print $1}'`   # создаем ярлык на фото пользователя [ -f /var/www/va/avatar/$HASHMD5 ] || \ ln -s /var/www/va/avatar/photo/`basename "$OIDC_CLAIM_picture"` /var/www/va/avatar/$HASHMD5  # перенаправляем клиента на адрес jitsi с параметрами имени и почты echo "<html lang=\"en-US\">     <head>         <meta charset=\"UTF-8\">         <script type=\"text/javascript\">             window.location.href = 'https://v.example.local${REQUEST_URI}#userInfo.displayName=\"${OIDC_CLAIM_given_name}\"&userInfo.email=\"${REMOTE_USER}\"'         </script>         <title>Page Redirection</title>     </head>     <body>     </body> </html>" 

Заходим браузером на https://va.example.local и сразу оказываемся на https://v.example.local. Видим стартовую страницу jitsi. Создаем конференцию и у нас имя, почта и аватар на месте. Ни одного ручного ввода ввода пользователь не сделал.

Но ведь у нас домен для ВКС v.example.local, а не va.example.local. Пользователь зайдет напрямую на v.example.local и увидит пустую заглушку. Вот бы сделать так, чтобы при входе на v.example.local веб сервер понимал когда на него зашли напрямую, а когда с va.example.local. Для этого есть переменная HTTP_REFERER. Пробуем.
Открываем стандартный конфиг jitsi виртуального хоста веб сервера, перед единственной директивой RewriteRule добавляем четыре строки:

<VirtualHost>     # ...     # ... стандартный конфиг для jitsi     # ...     RewriteEngine on      #- начало вставки ----------     RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://va.example.local*'"     RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://m.example.local*'"     RewriteCond expr "! %{HTTP_USER_AGENT} -strmatch '*Element*'"     RewriteRule ^/([a-zA-Z0-9]+)$ https://va.example.local/$1 [R]     #- конец вставки ----------      RewriteRule ^/([a-zA-Z0-9]+)$ /index.html </VirtualHost> 

Проверяем. Заходим браузером на https://v.example.local. Можно после доменного имени сразу указать subdir, в случае jitsi это означает название конференции. В любом случае идет перенаправление на va.example.local и обратно. Это происходит мгновенно, даже не заметно. В итоге пользователь назван и высокохудожественно изображен. При этом как и хотели никакого ручного ввода не было (ну кроме адреса в адресной строке).

Ну и само собой если используются самоподписанные корневые центры сертификации, их сертификаты надо добавить в доверенные на системе:

  1. системное хранилище java — cacerts

  2. скопировать pem файлы в /etc/ssl/certs, потом c_rehash.


ссылка на оригинал статьи https://habr.com/ru/articles/860670/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *