Обновлено 24.05.2023 (Актуально)
Подключение к 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 bullseye 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.10-1.src.rock
В файле lua-cjson-2.1.0.10-1/lua-cjson/lua_cjson.c поменяем строку 743:
vim lua-cjson-2.1.0.10-1/lua-cjson/lua_cjson.c
len = lua_objlen(l, -1);
на
len = lua_rawlen(l, -1);
Сохраняем файл и продолжаем установку:
cd lua-cjson-2.1.0.10-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 = true --false --разрешает подключаться без токена для приглашенных участников, в более ранних версиях это значение должно быть 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.
Сервера поднимал тут и тут. Еще использую сервера здесь, данный хостинг имеет большое разнообразие локаций по приемлемым ценам.
Благодарю за внимание!
Свой сервер видеоконференций Jitsi. Часть 1
Свой мессенджер Matrix-synapse в связке с Jitsi-meet. Часть 3