Howto Jitsi

Jitsi est une application de visionconférence utilisable avec les principaux navigateurs web grâce à la technologie WebRTC. Le code source est principalement en TypeScript et Javascript et sous licence libre.

Les principaux composants de Jitsi sont :

  • Meet : application Javascript chargée côté client dans le navigateur ou l’appli mobile des participants
  • Jicofo : JItsi COnference FOcus, gère notamment les sessions Jingle (extension média de XMPP) des participants (Java)
  • Videobridge ou JVB : routeur audio-vidéo compatible WebRTC (Java)
  • Prosody : serveur de messagerie instantanée compatible XMPP (Lua)

Installation

Nous installons Jitsi à partir des packages Debian fournis par jitsi.org.

ATTENTION, /tmp ne doit PAS être monté avec l’option noexec et /usr/share/jitsi doit être en rw.

# curl https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmor > /etc/apt/keyrings/jitsi.gpg
# chmod 644 /etc/apt/keyrings/jitsi.gpg
# echo 'deb [signed-by=/etc/apt/keyrings/jitsi.gpg] https://download.jitsi.org stable/' | tee /etc/apt/sources.list.d/jitsi.list > /dev/null
# chmod 644 /etc/apt/sources.list.d/jitsi.list 

# curl https://prosody.im/files/prosody-debian-packages.key | gpg --dearmor > /etc/apt/keyrings/prosody.gpg
# chmod 644 /etc/apt/keyrings/prosody.gpg
# echo 'deb [signed-by=/etc/apt/keyrings/prosody.gpg] http://packages.prosody.im/debian $(lsb_release -sc) main' | tee /etc/apt/sources.list.d/prosody.list > /dev/null
# chmod 644 /etc/apt/sources.list.d/prosody.list 

# apt update
# apt install jitsi-meet

# curl http://localhost:8080/about/version
{"name":"JVB","version":"2.3.215-gbee626bf","os":"Linux"}
# prosodyctl about
Prosody 0.11 nightly build 182 (2022-12-14, c4b1b5cbc20b)
[…]

# systemctl status jitsi-videobridge2.service
● jitsi-videobridge2.service - Jitsi Videobridge
     Loaded: loaded (/lib/systemd/system/jitsi-videobridge2.service; enabled; preset: enabled)
     Active: active (running) since Sat 2025-05-03 05:20:20 CEST; 4 days ago
   Main PID: 3043968 (java)
      Tasks: 189 (limit: 65000)
     Memory: 3.5G
        CPU: 3d 7h 47min 49.087s
     CGroup: /system.slice/jitsi-videobridge2.service
             └─3043968 java -Xmx3072m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Djdk.tls.ephemeralDHKeySize=2048 -Dconfig.file=/etc/jitsi/videobridge/jvb.conf -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 -cp "/usr/share/jitsi-videobridge/jitsi-videobridge.jar:/usr/share/jitsi-videobridge/lib/*" org.jitsi.videobridge.MainKt

# systemctl status jicofo.service
● jicofo.service - LSB: Jitsi conference Focus
     Loaded: loaded (/etc/init.d/jicofo; generated)
     Active: active (running) since Tue 2025-04-29 03:34:26 CEST; 1 week 1 day ago
       Docs: man:systemd-sysv-generator(8)
      Tasks: 45 (limit: 14340)
     Memory: 424.7M
        CPU: 40min 59.485s
     CGroup: /system.slice/jicofo.service
             └─599 java -Xmx3072m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Djdk.tls.ephemeralDHKeySize=2048 -Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=jicofo […]

# systemctl status prosody.service
● prosody.service - LSB: Prosody XMPP Server
     Loaded: loaded (/etc/init.d/prosody; generated)
     Active: active (running) since Tue 2025-04-29 03:34:27 CEST; 1 week 1 day ago
       Docs: man:systemd-sysv-generator(8)
    Process: 2297130 ExecReload=/etc/init.d/prosody reload (code=exited, status=0/SUCCESS)
      Tasks: 1 (limit: 14340)
     Memory: 598.4M
        CPU: 4h 34min 6.302s
     CGroup: /system.slice/prosody.service
             └─1687 lua5.2 /usr/bin/prosody -D

Réseau

Avec notre manière d’installer, un client a obligatoirement besoin d’accéder au serveur sur le port TCP/443 et de façon facultative sur le port UDP/10000.

Générer un certificat Let’s Encrypt

À l’installation initiale, Jitsi va proposer de créer un certificat Let’s Encrypt pour le domaine choisi, mais il est aussi possible de le faire plus tard avec le script suivant :

# /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

Ce script utilise acme.sh pour la gestion des certificats. Le renouvellement est configuré dans la crontab de root.

Mise à jour

Avant de se lancer dans la mise à jour des paquets, il est une bonne pratique de lire les notes de version.

La mise à jour des packages se fait de la manière habituelle :

# apt upgrade

Configuration

Tableau des principaux fichiers

Fichier(s) Chemin
Conf. Meet /etc/jitsi/meet/meet.example.org-config.js
SSL pour Meet /etc/jitsi/meet/meet.example.org.crt et .key
Conf. Jicofo /etc/jiti/jicofo/jicofo.conf
Conf. Videobridge /etc/jitsi/videobridge/jvb.conf
Conf. Prosody /etc/prosody/conf.d/meet.example.org.cfg.lua
SSL pour Prosody /etc/prosody/certs/*
Conf. Nginx (vhost) /etc/nginx/sites-enabled/meet.example.org.conf
Conf. Nginx (stream) /etc/nginx/modules-enabled/multiplex.conf
Conf. Coturn /etc/turnserver.conf

Serveur TURN (coturn) sur le port TCP/443

Nous configurons Jitsi pour avoir un serveur TURN sur le port TCP/443 au cas où le client ne pourrait pas accéder au port UDP/10000 du serveur. Ce fonctionnement est réputé pour être moins performant que la communication directe via UDP/10000 mais selon nos tests la différence n’est pas significative.

Nous suivons la solution proposée par les développeurs de Jitsi qui s’appuie sur une configuration spéciale de Nginx (module stream), coturn et un nom de domaine secondaire (exemple : turn.meet.example.org).

# cat /etc/nginx/modules-enabled/multiplex.conf

stream {
    map $ssl_preread_server_name $name {
        meet.example.org web_backend;
        turn.meet.example.org turn_backend;
    }
    log_format stream '$remote_addr [$time_local] '
                      '$ssl_preread_server_name '
                      '$protocol $status $bytes_sent $bytes_received $session_time';
    upstream web_backend {
        server 127.0.0.1:8088;
    }
    upstream turn_backend {
        server __your_public_ip__:5349;
    }
    server {
        listen 443;
        listen [::]:443;
        ssl_preread on;
        proxy_pass $name;
        # Increase buffer to serve video
        proxy_buffer_size 10m;
        access_log /var/log/nginx/multiplex_access.log stream;
        error_log /var/log/nginx/multiplex_error.log;
    }
}

Serveur STUN (coturn) sur le port UDP/3478

La configuration initiale de Jitsi fait appel à un serveur STUN externe (meet-jit-si-turnrelay.jitsi.net) qui écoute sur le port UDP/443 (oui UDP, pas TCP).

Si on désire plutôt utiliser son propre serveur, il est possible de le faire avec coturn, qui est déjà installé par défaut et écoute sur le port UDP/3478.

Domaines secondaires

Il est possible de configurer des domaines secondaires pour une instance donnée de Jitsi. Voici comment procéder pour ajouter par exemple le domaine secondaire another-domain.com à une instance dont le nom principal est meet.example.org :

La première étape est la configuration DNS. Il faut faire en sorte que another-domain.com pointe (via CNAME par exemple) sur le serveur qui héberge meet.example.org. Cela fait, il faut se connecter au serveur meet.example.org et dupliquer trois fichiers de cette manière :

# cp --preserve /etc/nginx/sites-available/meet.example.org.conf /etc/nginx/sites-available/another-domain.com.conf
# cp --preserve /etc/jitsi/meet/meet.example.org-config.js /etc/jitsi/meet/another-domain.com-config.js 
# cp --preserve /etc/jitsi/meet/meet.example.org-interface_config.js /etc/jitsi/meet/another-domain.com-interface_config.js 

Dans la configuration du vhost another-domain.com.conf, utiliser votre éditeur préféré pour substituer les instances de meet.example.org par another-domain.com à l’exception des directives proxy_set_header qui ne doivent pas changer. Aussi, commenter temporairement les directives débuttant par ssl_ et retirer le paramètre ssl des directives listen. Ces lignes seront remises à leur état initial après avoir généré le certificat SSL pour another-domain.com via ces commandes :

# ln -s /etc/nginx/sites-available/another-domain.com.conf /etc/nginx/sites-enabled/another-domain.com.conf
# nginx -t
# systemctl reload nginx
# certbot certonly --webroot --webroot-path /var/lib/letsencrypt --non-interactive --agree-tos --email security@another-domain.com -d another-domain.com

Tester le bon fonctionnement de la connexion SSL en décommentant les directives débuttant par ssl_ et en rajouter le paramètre ssl aux directives listen dans le fichier another-domain.com.conf puis en rechargeant la configuration de Nginx comme ceci :

# nginx -t
# systemctl reload nginx

Finalement, ajouter le nouveau domaine à la directive map dans le fichier /etc/nginx/modules-enabled/multiplex.conf :

    map $ssl_preread_server_name $name {
        meet.example.org web_backend;
        another-domain.com.conf web_backend;
        turn.meet.example.org turn_backend;
    }

… et recharger Nginx une dernière fois :

# nginx -t
# systemctl reload nginx

IMPORTANT : Il est à noter que si les domaines sont distincts, les salles de réunion ne le sont pas. Une salle https://meet.example.org/nom-de-la-salle sera aussi accessible à l’adresse https://another-domain.com/nom-de-la-salle. Si cette situation pose problème, il est possible de configurer un mot de passe pour contrôler l’accès à une salle (à partir de l’interface dans votre navigateur ou sur l’appli mobile).

Administration

Conférences actives

Il est possible d’avoir un aperçu des conférences actives grâce à la commande suivante :

# tail -f /var/log/jitsi/jvb.log | grep "conf_name="

Ou bien en faisant une requête locale à VideoBridge :

$ curl -s http://localhost:8080/debug | jq . | grep name

Chat des conférences

Les échanges par chat sont accessibles sur le serveur dans /var/lib/prosody/meet%2eexample%2eorg/offline/

FAQ

API applis mobiles et bureau

Si on désire que l’instance Jitsi soit fonctionnelle avec l’application mobile ou de bureau (Electron), il faut autoriser l’accès à l’API, ce qui est le cas dans le vhost généré automatiquement lors de l’installation. Si vous avez un vhost Nginx personnalisé, vous devrez vous assurer d’avoir ces lignes :

location /external_api.js {
    alias /usr/share/jitsi-meet/libs/external_api.min.js;
}

Il faut aussi vérifier que les Headers suivants ne sont pas activés dans Nginx, car cela bloquera l’accès à l’instance par l’application :

Content-Security-Policy "frame-ancestors 'none'";
X-Frame-Options "DENY";

Options de mountage des partitions

Si /tmp n’est pas “exec”, l’audio/video ne marchera pas. Si /usr/share/jitsi n’est pas accessible en écriture, jicofo se plaindra de ne pas pouvoir acquérir de lock.