Ceci est une ancienne révision du document !
Table des matières
Déploiement Jitsi Meet (paquets Debian) derrière Caddy
Guide d'installation d'une instance Jitsi Meet auto-hébergée pour réunions clients, sans Docker, avec Caddy en reverse proxy frontal et TURN configuré proprement.
- Cible : réunions clients en ligne (2 à ~20 participants)
- OS : Debian 12
- Reverse proxy : Caddy (gère le TLS)
- FQDN d'exemple :
meet.makeitsimple.be
1. Prérequis
| Élément | Détail |
|---|---|
| FQDN | meet.makeitsimple.be pointant vers l'IP publique |
| Port 443/tcp | Web + WebSocket (via Caddy) |
| Port 10000/udp | Média JVB — direct vers la VM, ne passe PAS par Caddy |
| Port 5349/tcp+udp | TURN over TLS (fallback NAT restrictif) |
| Ressources | 4 vCPU / 4–8 Go RAM recommandés |
<note warning> Le média audio/vidéo (10000/udp) et le TURN ne transitent jamais par Caddy. Caddy ne proxifie que le HTTP/WebSocket. C'est la source de confusion n°1. </note>
2. Préparation système
hostnamectl set-hostname meet.makeitsimple.be # Vérifier /etc/hosts : # 127.0.0.1 meet.makeitsimple.be meet apt update && apt upgrade -y apt install -y gnupg2 curl
3. Dépôts Jitsi
curl -sL https://download.jitsi.org/jitsi-key.gpg.key \ | gpg --dearmor -o /usr/share/keyrings/jitsi-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" \ > /etc/apt/sources.list.d/jitsi-stable.list apt update
4. Installation
apt install -y jitsi-meet
Pendant l'installation :
- Hostname : saisir
meet.makeitsimple.be - Certificat : choisir « I want to use my own certificate » — c'est Caddy qui gère le TLS, il ne faut PAS laisser Jitsi tenter Let's Encrypt. On peut pointer vers un certificat existant ou bidon, il sera contourné.
Cette commande installe : jitsi-meet (web), jicofo (focus/orchestration), jitsi-videobridge2 (JVB/média), prosody (XMPP), un nginx local et un coturn local.
5. Basculer le web Jitsi en HTTP local
Par défaut nginx écoute en 443 et se battra avec Caddy. On le fait écouter en local uniquement.
Éditer /etc/nginx/sites-available/meet.makeitsimple.be.conf :
server { listen 127.0.0.1:8000; server_name meet.makeitsimple.be; # ... conserver tout le reste de la conf générée par Jitsi ... # (locations /, /http-bind, /xmpp-websocket, etc.) }
- Faire écouter nginx sur
127.0.0.1:8000uniquement. - Supprimer / commenter les blocs
listen 443 ssletlisten [::]:443 ssl.
nginx -t && systemctl restart nginx
6. Caddy en frontal
Dans le Caddyfile :
meet.makeitsimple.be {
reverse_proxy 127.0.0.1:8000
}
caddy validate --config /etc/caddy/Caddyfile systemctl reload caddy
Caddy récupère le certificat Let's Encrypt automatiquement et proxifie HTTP + WebSocket (BOSH/XMPP-WS) vers Jitsi.
7. Configuration du média (JVB)
Point de rupture le plus fréquent. Le JVB doit annoncer les bonnes adresses IP pour la négociation ICE.
Éditer /etc/jitsi/videobridge/sip-communicator.properties :
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=<IP_PRIVEE_VM> org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=<IP_PUBLIQUE>
- VM derrière NAT : renseigner l'IP privée locale ET l'IP publique.
- VM en IP publique directe : les deux valeurs peuvent être identiques (l'IP publique).
Ouvrir 10000/udp de l'extérieur vers la VM (pare-feu + NAT éventuel).
systemctl restart jitsi-videobridge2
8. Configuration TURN (coturn)
Le TURN sert de relais média quand un participant est derrière un NAT/firewall restrictif qui bloque l'UDP direct (10000/udp). Typiquement : clients en réseau d'entreprise. Sans TURN fonctionnel, ces participants se connectent mais n'ont ni son ni vidéo.
Jitsi installe coturn automatiquement. Le conflit vient du fait que le TURN/TLS veut aussi le port 443. Comme Caddy occupe le 443, on bascule le TURN sur 5349.
8.1 Config coturn
Éditer /etc/turnserver.conf (généré par Jitsi). Vérifier / ajuster :
listening-port=3478 tls-listening-port=5349 listening-ip=<IP_PRIVEE_VM> relay-ip=<IP_PRIVEE_VM> external-ip=<IP_PUBLIQUE>/<IP_PRIVEE_VM> # Certificat TLS pour le TURN over TLS cert=/etc/jitsi/meet/meet.makeitsimple.be.crt pkey=/etc/jitsi/meet/meet.makeitsimple.be.key # Auth partagée avec Jitsi use-auth-secret static-auth-secret=<SECRET_GENERE_PAR_JITSI> realm=meet.makeitsimple.be # Durcissement no-tcp-relay no-multicast-peers no-cli
<note>
Le static-auth-secret est généré à l'install. Le récupérer dans /etc/turnserver.conf (existant) ou dans /etc/prosody/conf.d/meet.makeitsimple.be.cfg.lua (bloc turncredentials).
</note>
8.2 Certificat pour le TURN
coturn a besoin d'un vrai certificat pour le TURN/TLS sur 5349. Comme c'est Caddy qui émet les certificats, deux options :
Option A — Copier le cert de Caddy (simple)
Caddy stocke ses certificats dans son data dir, ex :
/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/meet.makeitsimple.be/
Script de synchro (à mettre en cron ou hook de renouvellement) :
#!/bin/bash SRC=/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/meet.makeitsimple.be DST=/etc/jitsi/meet cp "$SRC/meet.makeitsimple.be.crt" "$DST/meet.makeitsimple.be.crt" cp "$SRC/meet.makeitsimple.be.key" "$DST/meet.makeitsimple.be.key" chown turnserver:turnserver "$DST/meet.makeitsimple.be."{crt,key} systemctl restart coturn
Option B — Laisser Jitsi gérer son propre cert
Si un certificat a été fourni à l'install (étape 4), le réutiliser directement dans turnserver.conf.
8.3 Pointer Jitsi vers le bon port TURN
Vérifier dans /etc/prosody/conf.d/meet.makeitsimple.be.cfg.lua que le bloc turncredentials annonce le port 5349 en tls :
turncredentials = { { type = "stun", host = "meet.makeitsimple.be", port = "3478" }, { type = "turn", host = "meet.makeitsimple.be", port = "3478", transport = "udp" }, { type = "turns", host = "meet.makeitsimple.be", port = "5349", transport = "tcp" } }
Ouvrir 3478/udp et 5349/tcp (+udp) de l'extérieur vers la VM.
systemctl restart coturn prosody
9. Redémarrage complet
systemctl restart prosody jicofo jitsi-videobridge2 coturn nginx systemctl reload caddy
10. Récapitulatif pare-feu
| Port | Proto | Sens | Rôle |
|---|---|---|---|
| 443 | tcp | Externe → VM | Web + WebSocket (Caddy) |
| 80 | tcp | Externe → VM | ACME / redirection (Caddy) |
| 10000 | udp | Externe → VM | Média JVB (direct) |
| 3478 | udp | Externe → VM | STUN / TURN |
| 5349 | tcp+udp | Externe → VM | TURN over TLS (fallback corporate) |
11. Checklist de test de bout en bout
- [ ] DNS :
dig +short meet.makeitsimple.berenvoie bien l'IP publique. - [ ] HTTPS : la page d'accueil Jitsi charge en
https://sans alerte de certificat (Caddy). - [ ] Création de salle : créer une réunion, la page se charge, caméra/micro détectés.
- [ ] Test à 2 participants sur réseaux différents (ex. un en 4G, un en fibre) → audio + vidéo OK dans les deux sens.
- [ ] Test NAT restrictif : un participant sur réseau d'entreprise / VPN corporate → valide que le TURN prend le relais (audio/vidéo présents).
- [ ] Partage d'écran fonctionnel.
- [ ] Invité sans compte : ouvrir le lien en navigation privée → accès direct sans login.
- [ ] Vérif média : sur
https://webrtc.github.io/samples/ou via les stats Jitsi (bouton i), confirmer que la connexion passe enudpdirect (host/srflx) et bascule enrelayseulement si nécessaire.
<note tip>
Pour diagnostiquer un problème “je vois mais pas de son” : ouvrir les stats de connexion dans Jitsi (icône i en haut à gauche d'un participant). Si le type de connexion reste bloqué ou vide, c'est côté JVB (10000/udp) ou TURN.
</note>
12. Vérification des logs
journalctl -u jitsi-videobridge2 -f # média journalctl -u jicofo -f # orchestration des conférences journalctl -u prosody -f # XMPP / auth journalctl -u coturn -f # relais TURN journalctl -u caddy -f # reverse proxy / TLS
13. Restreindre la création de réunions (secure domain)
Objectif : seuls les hôtes authentifiés peuvent créer une réunion. Les invités rejoignent librement une salle déjà ouverte par un hôte, sans compte.
Comportement :
- Un invité qui tente de créer une salle → écran « en attente de l'hôte ».
- Un hôte se connecte (login/mot de passe) → la salle s'ouvre → les invités entrent.
13.1 Prosody
Éditer /etc/prosody/conf.d/meet.makeitsimple.be.cfg.lua.
Le VirtualHost principal passe en authentification interne :
VirtualHost "meet.makeitsimple.be" authentication = "internal_hashed"
Ajouter un VirtualHost anonyme pour les invités (à créer s'il n'existe pas) :
VirtualHost "guest.meet.makeitsimple.be" authentication = "anonymous" c2s_require_encryption = false
<note>
guest.meet.makeitsimple.be est un domaine XMPP interne, pas un vrai DNS : aucun enregistrement DNS ni certificat n'est requis pour lui.
</note>
13.2 Jicofo
Éditer /etc/jitsi/jicofo/jicofo.conf :
jicofo {
authentication {
enabled = true
type = XMPP
login-url = "meet.makeitsimple.be"
}
}
13.3 Config web
Éditer /etc/jitsi/meet/meet.makeitsimple.be-config.js :
var config = { hosts: { domain: 'meet.makeitsimple.be', anonymousdomain: 'guest.meet.makeitsimple.be', // ... }, // ... };
13.4 Créer les comptes hôtes
prosodyctl register vincent meet.makeitsimple.be <motdepasse>
- Un hôte = un compte.
- Révoquer un hôte :
prosodyctl deluser vincent@meet.makeitsimple.be - Changer un mot de passe :
prosodyctl passwd vincent@meet.makeitsimple.be
13.5 Redémarrer
systemctl restart prosody jicofo jitsi-videobridge2
13.6 Test
- [ ] En navigation privée (non authentifié), créer une salle → écran « en attente de l'hôte ».
- [ ] Se connecter avec un compte hôte → la salle s'ouvre.
- [ ] Un second onglet anonyme rejoint la salle ouverte → accès direct sans login.
Notes de maintenance
- Renouvellement TLS : le cert TURN (coturn) doit être resynchronisé après chaque renouvellement Caddy → automatiser via le script de l'étape 8.2 en cron quotidien.
- Montée en charge : au-delà de ~20–25 participants simultanés sur une salle, envisager un JVB supplémentaire (scaling horizontal).
- Mises à jour :
apt update && apt upgrade— les paquets Jitsi sont mis à jour régulièrement, tester après upgrade majeur.
