Jitsi-meet: авторизация по JWT-токену

от автора

Подключение к jitsi с отсутствием авторизации может стать небезопасным. Для того, чтобы избежать незваных гостей во время встречи, совещания или личной беседы стоит задуматься об авторизации. Под катом я подробно расскажу как нам улучшить наш сервис jitsi-meet с помощью JWT-токена.

Ниже я описал пошаговую инструкцию для установки и настройки JWT-токена на debian. Весь процесс можно провести как на уже работающем сервисе jitsi-jibri (с моего мана точно работает), так и в новой установке после завершения настройки jitsi.

apt install git cmake luarocks libssl-dev liblua5.2 wget http://packages.prosody.im/debian/pool/main/p/prosody-trunk/prosody-trunk_1nightly1273-1~buster_amd64.deb dpkg -i prosody-trunk_1nightly1273-1~buster_amd64.deb

apt install prosody -y echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add - apt update apt upgrade apt-get install jitsi-meet-tokens prosody-modules lua5.2 liblua5.2 luarocks libssl-dev

В процессе установки будет запрошен Application ID и Application secret. Указываем их и обязательно запоминаем, они нужны будут для генерации токена (если вдруг забыли их, то не страшно, их можно будет посмотреть/поменять в конфигурационном файле prosody)

luarocks install basexx

В конец файла /etc/prosody/prosody.cfg.lua добавим строчку:

vim /etc/prosody/prosody.cfg.lua

Include "conf.d/*.cfg.lua"

Так же находим строку начинающуюся «s2s_» и перед ней добавляем:

c2s_require_encryption = false

Продолжаем установку:

luarocks download lua-cjson luarocks unpack lua-cjson-2.1.0.6-1.src.rock

В файле lua-cjson-2.1.0.6-1/lua-cjson/lua_cjson.c поменяем строку 743:

vim lua-cjson-2.1.0.6-1/lua-cjson/lua_cjson.c

len = lua_objlen(l, -1); на len = lua_rawlen(l, -1);

Сохраняем файл и продолжаем установку:

cd lua-cjson-2.1.0.6-1/lua-cjson luarocks make --force cd .. git clone https://github.com/ASolomatin/luajwt.git cd luajwt/

Внесём изменения в файл luajwtjitsi-1.3-7.rockspec:

package = "luajwtjitsi" version = "1.3-7"  source = {         url = "git://github.com/ASolomatin/luajwt/",         tag = "replace_luacrypto" }  description = {         summary = "JSON Web Tokens for Lua",         detailed = "Very fast and compatible with pyjwt, php-jwt, ruby-jwt, node-jwt-simple and others",         homepage = "https://github.com/jitsi/luajwt/",         license = "MIT <http://opensource.org/licenses/MIT>" }  dependencies = {         "lua >= 5.2",         "luaossl >= 20190731-0",         "lua-cjson >= 2.1.0",         "lbase64 >= 20120807-3" }  build = {         type = "builtin",         modules = {                 luajwtjitsi = "luajwtjitsi.lua"         } }

Продолжаем:

luarocks install luajwtjitsi 2.0-0 systemctl restart prosody

Проверяем на наличие ошибок, если есть, то чистим файл и перезапускаем просодию:

vim /var/log/prosody/prosody.err systemctl restart prosody vim /var/log/prosody/prosody.err

Для генерации токена можно перейти на сайт и там задав параметры сгенерировать его, а после вставить в URL в формате https:///name_room?jwt=token .

На сайте вводим следующие данные:

HEADER:ALGORITHM & TOKEN TYPE  {   "typ": "JWT",   "alg": "HS256" } PAYLOAD:DATA  {  "context": {     "user": {       "name": "<user>",       "id": "<user>@gmail.com",   #optional       "email": "<user@gmail.com>",  #optional       "avatar": "<link to user's avatar>"  #optional     }   },   "aud": "jitsi",   "iss": "<Application_ID>",   "sub": "<FQDN>",   "room": "*",   "exp": 98753496345768,   "moderator": true } VERIFY SIGNATURE  HMACSHA256(   base64UrlEncode(header) + "." +   base64UrlEncode(payload),  <Application_secret>  ) secret base64 encoded

image

Привести к такому виду с подстановкой своих значение вместо <…>

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

Редактируем виртуальные хосты просодии. Для того, чтобы к нашей конференции могли подключаться участники по приглашению модератора без токена мы создадим гостевой хост. По умолчанию мы установили модуль модератора, однако этот модуль не позволяет передать права модератора, мы поменяем его на другой. Так же установим модуль, который включает лобби по умолчанию. Эта функция позволит администратору контролировать входящих в комнату, а те в свою очередь должны будут «представиться».

vim /etc/prosody/conf.avail/<FQDN>.cfg.lua

Находим наш виртуальный хост и приводим его к следующему значению:

VirtualHost "<FQDN>"             authentication = "token"     app_id="<APP_ID>"     app_secret="<APP_SECRET>"     allow_empty_token = false     allow_unencrypted_plain_auth = true   …     ssl = {         key = "/etc/prosody/certs/<FQDN>.key";         certificate = "/etc/prosody/certs/<FQDN>.crt";     }     av_moderation_component = "avmoderation.<FQDN>"     speakerstats_component = "speakerstats.<FQDN>"     conference_duration_component = "conferenceduration.<FQDN>"     -- we need bosh     modules_enabled = {         "bosh";         "pubsub";         "ping"; -- Enable mod_ping         "speakerstats";         "external_services";         "conference_duration";         "muc_lobby_rooms";         "muc_breakout_rooms";         "presence_identity";         "av_moderation";     }     c2s_require_encryption = false     lobby_muc = "lobby.<FQDN>"     breakout_rooms_muc = "breakout.<FQDN>"     main_muc = "conference.<FQDN>"     muc_lobby_whitelist = { "recorder.<FQDN>" } -- Here we can whitelist jibri to enter lobby enabled rooms  VirtualHost "guest.<FQDN>"     authentication = "anonymous"     modules_enabled = {             "bosh";             "pubsub";             "ping"; -- Enable mod_ping             "speakerstats";             "conference_duration";         }     c2s_require_encryption = false  Component "conference.<FQDN>" "muc"     restrict_room_creation = true     storage = "memory"     modules_enabled = {         "muc_meeting_id";         "muc_domain_mapper";         "polls";         "token_verification";         "token_moderation";         "muc_rate_limit";     }     admins = { "focus@auth.<FQDN>" }     muc_room_locking = false     muc_room_default_public_jids = true  Component "breakout.<FQDN>" "muc"     restrict_room_creation = true     storage = "memory"     modules_enabled = {         "muc_meeting_id";         "muc_domain_mapper";         "token_verification";         "muc_rate_limit";         "polls";     }     admins = { "focus@auth.<FQDN>" }     muc_room_locking = false     muc_room_default_public_jids = true  -- internal muc component Component "internal.auth.<FQDN>" "muc"     storage = "memory"     modules_enabled = {         "ping";     }     admins = { "focus@auth.<FQDN>", "jvb@auth.<FQDN>" }     muc_room_locking = false     muc_room_default_public_jids = true     muc_room_cache_size = 1000  VirtualHost "auth.<FQDN>"     ssl = {         key = "/etc/prosody/certs/auth.<FQDN>.key";         certificate = "/etc/prosody/certs/auth.<FQDN>.crt";     }     modules_enabled = {         "limits_exception";     }     authentication = "internal_hashed"  -- Proxy to jicofo's user JID, so that it doesn't have to register as a component. Component "focus.<FQDN>" "client_proxy"     target_address = "focus@auth.<FQDN>"  Component "speakerstats.<FQDN>" "speakerstats_component"     muc_component = "conference.<FQDN>"  Component "conferenceduration.<FQDN>" "conference_duration_component"     muc_component = "conference.<FQDN>"  Component "avmoderation.<FQDN>" "av_moderation_component"     muc_component = "conference.<FQDN>"  Component "lobby.<FQDN>" "muc"     storage = "memory"     restrict_room_creation = true     muc_room_locking = false     muc_room_default_public_jids = true     modules_enabled = {         "muc_rate_limit";         "polls";     }  В конец файла добавляем следующее (это понадобится для jibri)  -- internal muc component, meant to enable pools of jibri and jigasi clients -- Component "internal.auth.<FQDN>" "muc" -- Данный блок уже может быть выше в конфиге --    modules_enabled = { --        "ping"; --    } --    storage = "memory" --    muc_room_cache_size = 1000  VirtualHost "recorder.<FQDN>"     modules_enabled = {         "ping";     }     authentication = "internal_plain"

Клонируем репозиторий с модулями и устанавливаем:

cd ~ git clone https://github.com/nvonahsen/jitsi-token-moderation-plugin.git mv jitsi-token-moderation-plugin/mod_token_moderation.lua /usr/share/jitsi-meet/prosody-plugins/bak.mod_token_moderation.lua git clone https://github.com/dumasti/jitsi_mods.git mv /usr/share/jitsi-meet/prosody-plugins/mod_muc_lobby_rooms.lua /usr/share/jitsi-meet/prosody-plugins/bak.mod_muc_lobby_rooms.lua mv jitsi_mods/*.lua /usr/share/jitsi-meet/prosody-plugins/ mv /usr/share/jitsi-meet/prosody-plugins/mod_token_moderation_grand.lua /usr/share/jitsi-meet/prosody-plugins/mod_token_moderation.lua

Меняем настройки в файле /etc/jitsi/meet/-config.js для включения гостевого хоста и другие полезности (опционально).

cp /etc/jitsi/meet/<FQDN>-config.js /etc/jitsi/meet/bak.<FQDN>-config.js vim /etc/jitsi/meet/<FQDN>-config.js

/* eslint-disable no-unused-vars, no-var */  var config = {     hosts: {         domain: '<FQDN>',          anonymousdomain: 'guest.<FQDN>',         muc: 'conference.<FQDN>'     },      bosh: '//<FQDN>/http-bind',      testing: {     },     flags: {     },      enableNoAudioDetection: true,      enableNoisyMicDetection: true,      startAudioOnly: true,      startWithAudioMuted: false,      resolution: 1080,      constraints: {         video: {             height: {                 ideal: 720,                 max: 1080,                 min: 360             }         }     },      disableSimulcast: true,      fileRecordingsEnabled: true,     liveStreamingEnabled: true,     hiddenDomain: 'recorder.<FQDN>',      channelLastN: -1,      enableWelcomePage: true,      defaultLanguage: 'en',      enableUserRolesBasedOnToken: true,      p2p: {         enabled: true,         stunServers: [              { urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' }         ]     },      analytics: {     },      deploymentInfo: {     },      mouseMoveCallbackInterval: 1000,     makeJsonParserHappy: 'even if last key had a trailing comma' };  /* eslint-enable no-unused-vars, no-var */

vim /etc/jitsi/jicofo/sip-communicator.properties

org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.<FQDN> org.jitsi.jicofo.jibri.PENDING_TIMEOUT=90 org.jitsi.jicofo.auth.URL=EXT_JWT:<FQDN>

systemctl restart jitsi-videobridge2 jicofo prosody

Все готово. Идем проверять.

Если jibri еще не установлен, но необходимо иметь возможность записывать или транслировать конференции, то идем сюда и продолжаем установку jibri.

Благодарю за внимание!

Благодарности за помощь

Благодарю за редакторские правки Дарью Гулькович. Так же выражаю благодарность за техническую поддержку (пендаль в нужном направлении) Никиту Суклич.


ссылка на оригинал статьи https://habr.com/ru/company/timeweb/blog/666156/


Комментарии

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

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