====== Vidéoconférence Jitsi Meet ====== Hadoly à mis en place en Mars 2020 un service de vidéoconférence basé sur le logiciel [[https://github.com/jitsi/jitsi-meet|Jitsi Meet]]. Ce déploiement a été fait dans le contexte de la crise sanitaire du [[https://fr.wikipedia.org/wiki/Maladie_%C3%A0_coronavirus_2019|COVID-19]] ayant entraîné le [[https://fr.wikipedia.org/wiki/Confinement_de_2020_en_France|confinement de la population française]] Ce service est considéré comme temporaire et sera potentiellement éteint à l'issue de la crise. Ce document présente les détails techniques du déploiement de la solution. Il n'a pas vocation à être un tutoriel pas-à-pas d'installation, mais plutôt à mettre en avant les spécificités et les optimisations effectuées. ==== Architecture globale ==== Le service utilise 3 machines virtuelles : * **[[documentation_technique:machines:jitsi2|jitsi2]]** - Installation principale de Jitsi Meet - Debian 10, 4Go de RAM, 8vCPU, 6Go de disque * **jvb2** - Videobridge supplémentaire - Ubuntu 18.04, 8Go de RAM, 8vCPU, 32Go de disque * **jvb3** - Videobridge supplémentaire - Ubuntu 18.04, 8Go de RAM, 8vCPU, 32Go de disque Avec le recul, le dimensionnement des machines n'est pas forcément complètement adapté aux besoins. Pour référence, l'équipe qui développe le logiciel, et qui maintient https://meet.jit.si/, a indiqué utiliser pour ses videobridge des machines Ubuntu 18.04, 6Go de RAM, 8vCPU. Les machines **jvb2** et **jvb3** ont été ajoutées après coup, afin de soulager jitsi2 lors des périodes de forte affluence. Elles hébergent uniquement des videobridge supplémentaires, et peuvent être éteintes à tout moment sans besoin de reconfiguration sur jitsi2. ==== Installation principale ==== L'installation principale, sur la machine [[documentation_technique:machines:jitsi2|jitsi2]] a été faite en suivant [[https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md|la documentation officielle]] . Cette documentation permet d'arriver relativement facilement à un déploiement fonctionnel. ==== Optimisations côté serveur ==== === Java 8 === Officiellement, Jitsi ne fonctionne qu'avec Java 8... qui n'est pas disponible dans les dépôts Debian 10. Sous Ubuntu 18.04, openjdk-8-jre-headless est directement installé. Cette étape est donc inutile. Sous Debian 10, on peut utiliser adoptopenjdk-8: wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add - sudo add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ sudo apt update sudo apt install adoptopenjdk-8-hotspot sudo update-alternatives --config java # Quick fix broken cacerts sudo ln -s /etc/ssl/certs/java/cacerts /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64/jre/lib/security/cacerts === STUN/TURN === Avec l'installation par défaut, un serveur [[https://fr.wikipedia.org/wiki/Simple_Traversal_of_UDP_through_NATs|STUN]]/[[https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT|TURN]] est installé.\\ Cependant, afin de pouvoir utiliser le port TCP 443, il est configuré pour être derrière le serveur web nginx (conf dans ''/etc/nginx/modules-enabled/60-jitsi-meet.conf''). \\ Malheureusement cette configuration n'est pas compatible avec les web-sockets. Nous avons donc fait le choix d'utiliser un [[https://fr.wikipedia.org/wiki/Fully_qualified_domain_name|FQDN]] séparé (turn.hadoly.fr) ainsi que de nouvelles IP publiques. Le serveur coturn, est exposé en direct sans passer par nginx. D'autres choix sont possibles. Comme installer un serveur TURN sur une machine dédiée. Ou changer le port d'écoute pour utiliser le port standard (5349) au lieu du 443... au risque de ne pas passer certains pare-feu. Notre conf coturn: use-auth-secret static-auth-secret=SuperSecret69 realm=turn.hadoly.fr cert=/etc/coturn/certs/turn.hadoly.fr.fullchain.pem pkey=/etc/coturn/certs/turn.hadoly.fr.privkey.pem dh-file=/etc/nginx/dh2048.pem listening-ip=80.67.185.26 listening-ip=2001:912:30aa:300::26 listening-port=443 external-ip=80.67.185.26 external-ip=2001:912:30aa:300::26 verbose syslog no-multicast-peers no-cli no-loopback-peers no-tcp-relay denied-peer-ip=0.0.0.0-0.255.255.255 denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=100.64.0.0-100.127.255.255 denied-peer-ip=127.0.0.0-127.255.255.255 denied-peer-ip=169.254.0.0-169.254.255.255 denied-peer-ip=127.0.0.0-127.255.255.255 denied-peer-ip=172.16.0.0-172.31.255.255 denied-peer-ip=192.0.0.0-192.0.0.255 denied-peer-ip=192.0.2.0-192.0.2.255 denied-peer-ip=192.88.99.0-192.88.99.255 denied-peer-ip=192.168.0.0-192.168.255.255 denied-peer-ip=198.18.0.0-198.19.255.255 denied-peer-ip=198.51.100.0-198.51.100.255 denied-peer-ip=203.0.113.0-203.0.113.255 denied-peer-ip=240.0.0.0-255.255.255.255 Il faut ensuite adapter la conf prosody (''/etc/prosody/conf.d/jitsi.hadoly.fr.cfg.lua'') afin d'indiquer les bons FQDN/port à utiliser turncredentials_secret = "SuperSecret69"; turncredentials_port = 443; turncredentials_ttl = 43200; turncredentials = { { type = "stun", host = "turn.hadoly.fr", port = 443 }, { type = "turn", host = "turn.hadoly.fr", port = 443 , transport = "udp" }, { type = "turns", host = "turn.hadoly.fr", port = 443, transport = "tcp" } } Docs intéressantes sur le sujet, notamment sur la manière de tester un serveur STUN et TURN: * https://meetrix.io/blog/webrtc/coturn/installation.html * https://meetrix.io/blog/webrtc/jitsi/setting-up-a-turn-server-for-jitsi-meet.html === Désactiver TCP === Une fois le serveur TURN fonctionnel, il est possible de désactiver TCP sur le videobridge, pour ne le laisser fonctionner qu'en UDP, ce qui semble recommandé. \\ Le serveur TURN s'occupe alors de faire l'interface avec les clients qui sont derrière un pare-feu bloquant l'UDP, et donc obligés de passer en TCP. Dans le fichier ''/etc/jitsi/videobridge/sip-communicator.properties'', on ajoute le paramètre suivant: org.jitsi.videobridge.DISABLE_TCP_HARVESTER=true === Utiliser les web-sockets à la place de bosh === Par défaut, les paquets actuels ne configurent pas le videobridge pour utiliser les web-sockets pour communiquer avec les clients. C'est pourtant la conf recommandée.\\ Chez Hadoly, la configuration par défaut avec bosh faisait apparaître beaucoup d'erreurs dans les logs (''Sctp send error: : Resource temporarily unavailabl''). La solution de contournement est d'utiliser les web-sockets. https://github.com/jitsi/jitsi-videobridge/blob/master/doc/web-sockets.md La configuration est a faire dans ''/etc/jitsi/videobridge/jvb.conf'' videobridge { http-servers { public { port = 9090 } } websockets { enabled = true tls = true domain = "jitsi.hadoly.fr:443" server-id = jvb1 } } Côté serveur web, on adapte la conf du reverse proxy (dans ''/etc/nginx/sites-available/jitsi.hadoly.fr.conf'') # colibri (JVB) websockets for jvb1 location ~ ^/colibri-ws/jvb1/(.*) { proxy_pass http://127.0.0.1:9090/colibri-ws/jvb1/$1$is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; tcp_nodelay on; } Et pour terminer on active les web-sockets côté client en modifiant ''/etc/jitsi/meet/jitsi.hadoly.fr-config.js'' openBridgeChannel: 'websocket', === Activer l'API pour avoir des statistiques === Afin d'avoir des métriques comme le nombre de personnes connectés ou le nombre de conférences, il est utile d'activer l'API.\\ Dans ''/etc/jitsi/videobridge/config'' on adapte le paramètre suivant: JVB_OPTS="--apis=rest" Et dans ''/etc/jitsi/videobridge/sip-communicator.properties'' : org.jitsi.videobridge.ENABLE_STATISTICS=true org.jitsi.videobridge.rest.private.jetty.host=127.0.0.1 ''curl http://127.0.0.1:8080/colibri/stats | jq'' doit retourner un beau json avec les métriques. \\ La documentation officielle sur le sujet: * https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md * https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest-colibri.md === Limiter logs === La configuration par défaut des paquets a un niveau de log inadapté pour un serveur de production, créant plusieurs 10ène de milliers de messages de logs par seconde (en charge). \\ La création de ces logs consomme beaucoup de ressource CPU, inutilement. La configuration par défaut a été [[https://github.com/jitsi/jitsi-videobridge/pull/1251/commits/0694baf2ef954516b47373dca80ba7b3df99751c|changé récemment]], et devrait arriver prochainement dans les paquets deb. En attendant, il suffit de désactiver ces logs manuellement, dans ''/etc/jitsi/videobridge/logging.properties'': java.util.logging.FileHandler.level = OFF === Limiter le swap === Le videobridge/java a tendance a utiliser la swap. Si la machine a largement suffisamment de RAM, le plus simple est de désactiver le swap. Sinon il est peut être utile de limiter le swap en baissant le paramètre swappiness. === Ajouter de videobridge supplémentaires === Le videobridge est LE composant qui consomme de la ressource (principalement CPU et réseau). C'est lui qui est au centre de chaque conférence et gère le routage des flux video/audio vers l'ensemble des participants.\\ Ajouter des videobridge supplémentaire permet d'héberger d'avantage de conférences simultanément. Lorsque qu'une conférence atteint 2 participants, le composant jicofo détermine le videobridge à utiliser, en se basant sur la charge de chaque bridge à cet instant t. \\ Les conférences se retrouvent réparti entre les différents videobridge. Dans la pratique le load balancing n'est pas parfait mais on obtient tout de même une bonne répartition de la charge. Sur les videobridge supplémentaire, la procédure d'installation est simple, et consiste à: * installer uniquement le paquet ''jitsi-videobridge2'' * Recopier le fichier ''/etc/jitsi/videobridge/sip-communicator.properties'' depuis le serveur principal. * Remplace le ''MUC_NICKNAME'' par un id unique https://github.com/jitsi/jitsi-meet/wiki/jitsi-meet-load-balancing-installation-Ubuntu-18.04-with-MUC-and-JID Comme on utilise des web-sockets, il faut penser a mettre à jour la conf du reverse proxy nginx en ajoutant le nécessaire pour chaque videobridge supplémentaire: # colibri (JVB) websockets for jvb2 location ~ ^/colibri-ws/jvb2/(.*) { proxy_pass http://X.X.X.X:9090/colibri-ws/jvb2/$1$is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; tcp_nodelay on; } ==== Optimisations côté client ==== Changements à effectuer dans ''/etc/jitsi/meet/jitsi.hadoly.fr-config.js'' et visent à réduire la charge (principalement CPU) sur les machines clients. * Video off par defaut : ''startAudioOnly: true'' * Audio off par défaut si plus de 5 personnes dans la conf: ''startAudioOnly: true'' * Diminution de la résolution video préférée: ''resolution: 480'' * Désactive les rond bleu qui gigotent quand quelqu'un parle: ''disableAudioLevels: true'' Changements à effectuer dans ''/usr/share/jitsi-meet/interface_config.js'' (probablement écrasé lors de mises à jour...) * Désactive le flou fondu sur l'arrière plan: 'DISABLE_VIDEO_BACKGROUND: true' ==== Personnalisation ==== Parce que j'ai commencé à faire des trucs chelous pour remettre le logo. La doc kivabien (comme la vérité) est [[https://git.hadoly.fr/CS_CT/Communication/src/branch/master/jitsi.logo|ailleurs]]