Подключение к 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
Привести к такому виду с подстановкой своих значение вместо <…>
После успешной установки необходимой инфраструктуры нужно прописать конфигурацию для корректной работы. Базовую конфигурацию мы получили в процессе установки, и настройки, которые я приведу ниже являются опциональными.
Редактируем виртуальные хосты просодии. Для того, чтобы к нашей конференции могли подключаться участники по приглашению модератора без токена мы создадим гостевой хост. По умолчанию мы установили модуль модератора, однако этот модуль не позволяет передать права модератора, мы поменяем его на другой. Так же установим модуль, который включает лобби по умолчанию. Эта функция позволит администратору контролировать входящих в комнату, а те в свою очередь должны будут «представиться».
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/
Добавить комментарий