Jitsi Meet
Jitsi Meet — веб-приложение на базе технологии WebRTC. Для сигналинга использует XMPP через BOSH с использованием собственного XEP. В системах на базе Альт оно расположено в пакете jitsi-meet-web. Для ведущих мобильных платформ (iOS, Google Play, F-Droid) доступны приложения на React Native.
Jicofo — XMPP-компонент, модератор видеоконференций. Клиенты договариваются о связи, заходя в общую XMPP-комнату с ним, и обмениваются там XMPP-сообщениями. Имеет HTTP API /about/health для опроса о состоянии сервиса.
Jitsi Videobridge — ключевой компонент системы, SFU. Он передаёт видео и аудио между участниками, осуществляя роль посредника, терминирует RTP/RTCP, определяет доступные рамки битрейта в обе стороны на конкретного клиента. Имеет свой внутренний HTTP API для мониторинга (/colibri/debug).
Это SFU, не MCU — он не занимается транскодингом и поэтому потребляет относительно мало CPU.
К системе ВКС Jitsi можно подключить несколько видеобриджей — тогда каждой новой конференции будет поставлен в соответствие один из них.
Jigasi — шлюз для участия в Jitsi-конференциях через SIP-телефонию.
Jibri — appliance для записи конференции. Использует Selenium с Chromium внутри (и тянет за собой зависимости на Xorg, icewm, модуль ядра snd-aloop). Ведёт себя как ничего не передающий участник записываемой конференции, но Jicofo и клиенты его держат на особом положении: не отображают в списке участников и т. п. Также, как и JVB, Jigasi, заходит по отдельному аккаунту в специальную XMPP-комнату для рекордеров. Их можно (и нужно!) воткнуть несколько, если планируется вести запись нескольких конференций одновременно.
Шаблон:Caution В репозиториях Альт есть пакет jitsi, он не имеет никакого отношения к Jitsi Meet.
Как развернуть?
Minimal Viable Product
Вам потребуются пакеты prosody, jitsi-meet-prosody, jitsi-meet-web, jitsi-meet-web-config, jicofo, jitsi-videobridge. Для размещения нужны:
- jitsi-videobridge: хост с доступными портами 10000/udp, 4443/tcp и хорошей пропускной способностью (рекомендуется минимум 100Mbps симметрично)
- веб-сервер: хост с доступным портом 443/tcp
- Шаблон:Caution обратите внимание: веб-сервер должен поддерживать HTTPS, иначе браузеры откажутся поддерживать на нём WebRTC. Лучше всего сначала выписать SSL-сертификат, а потом продолжать настройку веб-сервера.
- xmpp-сервер: хост с доступным портом 5280/tcp для работы XMPP-over-HTTP (BOSH).
Установите пакеты:
apt-get install prosody jitsi-meet-prosody jitsi-meet-web jitsi-meet-web-config jicofo jitsi-videobridge
Теоретически компоненты могут размещаться на разных машинах; на практике мы не рекомендуем устанавливать prosody и jicofo на разные машины — это может привести к низкой производительности сервиса и большим колебаниям задержки связи.
При настройке будем предполагать, что в качестве базового доменного имени выбрано $DOMAIN.
На всех используемых машинах убедитесь, что команда
ping "$(hostname)"
успешно срабатывает: уходят запросы и приходят ответы.
Настройка XMPP-сервера
Создайте дополнительную директорию для конфигурации XMPP-сервера:
# mkdir /etc/prosody/conf.d/
В файл /etc/prosody/conf.d/$DOMAIN.cfg.lua напишите:
plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
-- domain mapper options, must at least have domain base set to use the mapper
muc_mapper_domain_base = "$DOMAIN";
cross_domain_bosh = false;
consider_bosh_secure = true;
VirtualHost "$DOMAIN"
authentication = "anonymous"
--app_id="example_app_id"
--app_secret="example_app_secret"
-- Assign this host a certificate for TLS, otherwise it would use the one
-- set in the global section (if any).
-- Note that old-style SSL on port 5223 only supports one certificate, and will always
-- use the global one.
ssl = {
key = "/etc/prosody/certs/$DOMAIN.key";
certificate = "/etc/prosody/certs/$DOMAIN.crt";
}
speakerstats_component = "speakerstats.$DOMAIN"
conference_duration_component = "conferenceduration.$DOMAIN"
-- we need bosh
modules_enabled = {
"bosh";
"pubsub";
"ping"; -- Enable mod_ping
"speakerstats";
"turncredentials";
"conference_duration";
}
c2s_require_encryption = false
Component "conference.$DOMAIN" "muc"
storage = "memory"
modules_enabled = {
"muc_meeting_id";
"muc_domain_mapper";
-- "token_verification";
}
admins = { "focus@auth.$DOMAIN" }
muc_room_locking = false
muc_room_default_public_jids = true
VirtualHost "auth.$DOMAIN"
ssl = {
key = "/etc/prosody/certs/auth.$DOMAIN.key";
certificate = "/etc/prosody/certs/auth.$DOMAIN.crt";
}
authentication = "internal_plain"
-- internal muc component, meant to enable pools of jibri and jigasi clients
Component "internal.auth.$DOMAIN" "muc"
storage = "memory"
modules_enabled = {
"ping";
}
admins = { "focus@auth.$DOMAIN", "jvb@auth.$DOMAIN" }
muc_room_locking = false
muc_room_default_public_jids = true
Component "focus.$DOMAIN"
component_secret = "xxx" -- достаточно длинный пароль, он же JICOFO_SECRET
Component "speakerstats.$DOMAIN" "speakerstats_component"
muc_component = "conference.$DOMAIN"
Component "conferenceduration.$DOMAIN" "conference_duration_component"
muc_component = "conference.$DOMAIN"
В файл /etc/prosody/prosody.cfg.lua добавьте:
Include "conf.d/*.cfg.lua"
Другими словами, нужно предусмотреть:
- VirtualHost для самих пользователей (здесь: собственно $DOMAIN)
- MUC для пользователей-участников конференции (здесь: conference.$DOMAIN)
- VirtualHost для служебных аккаунтов focus@, jvb@, jibri@, ... (здесь: auth.$DOMAIN)
- MUC для взаимодействия микросервисов, сидящих под этими аккаунтами (здесь: internal.auth.$DOMAIN)
- слот для XMPP-компонента focus (здесь: focus.$DOMAIN)
...а также подключить к ним соответствующие модули, и для двух из них (speakerstats, conference_duration) предусмотреть внутренние XMPP-компоненты.
Сгенерируйте сертификаты для виртуалхостов $DOMAIN и auth.$DOMAIN:
prosodyctl cert generate $DOMAIN prosodyctl cert generate auth.$DOMAIN
Позже их нужно будет зарегистрировать в системе, на которой установлен Jicofo, как доверенные:
ln -s /etc/prosody/certs/$DOMAIN.crt /etc/pki/ca-trust/source/anchors/ ln -s /etc/prosody/certs/auth.$DOMAIN.crt /etc/pki/ca-trust/source/anchors/ update-ca-certs
Настройка Jicofo
Jicofo подключается к XMPP-серверу и как внешний XMPP-компонент, и как юзер-аккаунт с JID focus@auth.$DOMAIN
В /etc/jitsi/jicofo/config укажите:
# Jitsi Conference Focus settings
# sets the host name of the XMPP server
JICOFO_HOST=localhost
# sets the XMPP domain (default: none)
JICOFO_HOSTNAME=$DOMAIN
# sets the secret used to authenticate as an XMPP component
JICOFO_SECRET=xxx
# overrides the prefix for the XMPP component domain. Default: "focus"
#JICOFO_FOCUS_SUBDOMAIN=focus
# sets the port to use for the XMPP component connection
JICOFO_PORT=5347
# sets the XMPP domain name to use for XMPP user logins
JICOFO_AUTH_DOMAIN=auth.$DOMAIN
# sets the username to use for XMPP user logins
JICOFO_AUTH_USER=focus
# sets the password to use for XMPP user logins
JICOFO_AUTH_PASSWORD="[yyy]"
# extra options to pass to the jicofo daemon
JICOFO_OPTS="${JICOFO_FOCUS_SUBDOMAIN:+ --subdomain=$JICOFO_FOCUS_SUBDOMAIN}"
# adds java system props that are passed to jicofo (default are for home and logging config file)
JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jicofo -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi -Djava.util.logging.config.file=/etc/jitsi/jicofo/logging.properties"
"[yyy]" — достаточно длинный пароль для аккаунта focus@auth.$DOMAIN, который нужно завести на машине с prosody:
prosodyctl register focus auth.$DOMAIN "[yyy]"
В /etc/jitsi/jicofo/sip-communicator.properties укажите:
org.jitsi.jicofo.health.ENABLE_HEALTH_CHECKS=true org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.$DOMAIN
Запустите jicofo:
systemctl start jicofo
Убедитесь, что он подключается к XMPP-серверу:
curl -i localhost:8888/about/health
Так как пока что ни одного Jitsi Videobridge к серверу не подключено, jicofo ответит кодом ответа 500 и сообщением No operational bridges available. Если в ответе сообщение об ошибке иного рода — проверьте настройки и связь между prosody и jicofo.
Настройка Jitsi Videobridge (JVB)
В /etc/jitsi/videobridge/config укажите:
# Jitsi Videobridge settings
# extra options to pass to the JVB daemon
JVB_OPTS="--apis=,"
# adds java system props that are passed to jvb (default are for home and logging config file)
JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=videobridge -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi -Djava.util.logging.config.file=/etc/jitsi/videobridge/logging.properties -Dconfig.file=/etc/jitsi/videobridge/application.conf"
Если в файле config есть другие настройки, рекомендуем их убрать — и способ передачи этих настроек, и сами некоторые эти настройки являются устаревшими.
В качестве файлов конфигурации используются /etc/jitsi/videobridge/{application.conf,sip-communicator.properties}.
В файле /etc/jitsi/videobridge/application.conf укажите:
videobridge { stats { enabled = true transports = [ { type = "muc" } ] } apis { xmpp-client { configs { shard { hostname = "localhost" domain = "auth.$DOMAIN" username = "jvb" password = "[yyy-jvb]" muc_jids = "JvbBrewery@internal.auth.$DOMAIN" # The muc_nickname must be unique across all instances muc_nickname = "jvb-mid-123" } } } } }
Вместо слова shard можно использовать любой идентификатор (оно идентифицирует подключение к xmpp-серверу и jicofo).
Аккаунт jvb@auth.$DOMAIN тоже нужно завести на XMPP-сервере:
prosodyctl register jvb auth.$DOMAIN "[yyy-jvb]"
Если JVB-машина отделена от клиентов при помощи NAT, то потребуется донастройка: подробнее здесь.
Запустите JVB:
systemctl start jitsi-videobridge
Если всё сделано правильно и между JVB и jicofo есть связь, jicofo на healthcheck-запрос будет отдавать HTTP-код 200.
Если по тем или иным причинам поддержка health check больше не нужна, из /etc/jitsi/jicofo/sip-communicator.properties свойство org.jitsi.jicofo.health.ENABLE_HEALTH_CHECKS можно убрать.
Настройка web-приложения Jitsi Meet
В пакете jitsi-meet-web-config есть примеры конфигурации для веб-клиента (*-config.js) и веб-сервера. Мы рекомендуем при настройке веб-сервера за основу взять пример оттуда.
Приведём ниже подробный разбор этого примера:
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name $DOMAIN; root /usr/share/jitsi-meet; # ssi on with javascript for multidomain variables in config.js ssi on; ssi_types application/x-javascript application/javascript;
В системе Jitsi Meet нет динамической вебсерверной части, поэтому мы прибегаем к SSI. Риска в использовании SSI нет, потому что пользователь не может заставить веб-сервер отдавать произвольные данные.
Помимо конференций вида https://jitsi-meet.example.com/ConferenceName, Jitsi Meet также поддерживает URL-адреса конференций вида https://jitsi-meet.example.com/Subdomain/ConferenceName, где для разных значений Subdomain используются разные настройки и виртуалхосты на XMPP-сервере. SSI нужны как минимум для динамической подстановки этих значений в config.js.
index index.html index.htm; error_page 404 /static/404.html;
gzip on; gzip_types text/plain text/css application/javascript application/json; gzip_vary on; location = /config.js { alias /etc/jitsi/meet/$DOMAIN-config.js; }
Содержит элементы конфигурации веб-приложения. Его нужно поправить по необходимости, скопировав на место: cp /usr/share/jitsi-meet-web-config/config.js /etc/jitsi/meet/$DOMAIN-config.js
location = /external_api.js { alias /usr/share/jitsi-meet/libs/external_api.min.js; } #ensure all static content can always be found first location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$ { add_header 'Access-Control-Allow-Origin' '*'; alias /usr/share/jitsi-meet/$1/$2; }
Ниже идёт настройка проксирования BOSH. Связь веб-клиента и XMPP-сервера можно организовывать и по вебсокетам, но на июнь 2020 поддержка вебсокетов в Jitsi Meet доступна только в тестовом режиме. Проброс HTTP до XMPP-сервера здесь полезен хотя бы потому, что можно ограничиться настройкой TLS только на веб-сервере. Если XMPP-сервер находится не на той же машине, что и веб-сервер, localhost в директиве proxy_pass нужно соответствующим образом заменить.
# BOSH location = /http-bind { proxy_pass http://localhost:5280/http-bind; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; } # xmpp websockets location = /xmpp-websocket { proxy_pass http://localhost:5280/xmpp-websocket?prefix=$prefix&$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; tcp_nodelay on; }
Не забудьте выписать TLS-сертификат для веб-сервера.
Поправьте /etc/jitsi/meet/$DOMAIN-config.js в соответствии с настройками серверной части:
var config = {
// Connection
//
hosts: {
// XMPP domain.
domain: '$DOMAIN', // Главный VirtualHost на XMPP-сервере
// When using authentication, domain for guest users.
// anonymousdomain: 'guest.$DOMAIN', // Если на главном включена аутентификация: VirtualHost для анонимного доступа
// Domain for authenticated users. Defaults to <domain>.
// authdomain: '$DOMAIN',
// Call control component (Jigasi).
// call_control: 'callcontrol.$DOMAIN',
// Focus component domain. Defaults to focus.<domain>.
// focus: 'focus.$DOMAIN',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.<!--# echo var="subdomain" default="" -->$DOMAIN'
},
// BOSH URL. FIXME: use XEP-0156 to discover it.
bosh: '//$DOMAIN/http-bind',
// Websocket URL
// websocket: 'wss://$DOMAIN/xmpp-websocket',
// The name of client node advertised in XEP-0115 'c' stanza
clientNode: 'http://jitsi.org/jitsimeet',
// The real JID of focus participant - can be overridden here
// focusUserJid: 'focus@auth.$DOMAIN',
[...]
}
Веб-интерфейс Jitsi Meet выкачивает этот скрипт и меняет поведение в зависимости от значений, там указанных.
Некоторые полезные настройки:
- fileRecordingsEnabled: булев тип; если true — включает в интерфейсе кнопку "начать запись".
- liveStreamingEnabled: булев тип; включает в интерфейсе кнопку "начать трансляцию в YouTube".
- noticeMessage: строка; позволяет отображать указанное MOTD в каждой конференции, например, в случае планируемых работ по обслуживанию.
- p2p.enabled: булев тип; если включен — при разговорах тет-а-тет JVB не задействуется (но может потребоваться задействование STUN/TURN).
- disableThirdPartyRequests: булев тип; если включено — Jitsi не будет делать запросов к сторонним серверам.
- Например, обычно Jitsi берёт аватарки с gravatar.com по e-mail участника, если тот в веб-интерфейсе его указал.
Чтобы проверить, всё ли в порядке, зайдите на https://$DOMAIN и присоединитесь к произвольной конференции, а затем 1-2 раза продублируйте вкладку веб-браузера. Трёх (в случае выключенного p2p — двух) анонимных участников достаточно, чтобы начать обмен медиапотоками; если увидите три изображения с камеры — система готова к использованию.
Подключение SIP-шлюза jigasi
Подключение рекордера jibri
FAQ
Можно ли использовать не prosody, а другой XMPP-сервер?
Краткий ответ: нет.
В комплекте с Jitsi идут модули для расширения функциональности XMPP-сервера prosody, написанные на Lua; они считаются частью продукта Jitsi Meet. Без этих модулей или эквивалентных им система ВКС работать не будет. В теории, ничего не мешает написать и поддерживать эти модули для вашего XMPP-сервера; одно время проект Jitsi использовал XMPP-сервер openfire.
Кто может подключиться к созданной конференции?
В приведённой инструкции описана конфигурация, подобная https://meet.jit.si, где, зная URL конференции, в неё может зайти любой желающий. Конференция создаётся, когда в неё заходит первый участник, и существует до выхода последнего. Предотвратить случайных посетителей можно, выбрав достаточно длинный URL на главной странице веб-портала; генератор по умолчанию с этим справляется.
Если система Jitsi Meet развёрнута на ваших собственных ресурсах, вы можете предотвратить неавторизованное создание новых конференций, чтобы сторонние люди не могли перенагрузить систему. Более подробное описание процедуры даёт апстрим.