Jitsi: una piattaforma OpenSource di videoconferenza – Installazione su un server proprio

4

Abbiamo già descritto cosa faccia Jitsi, e vi abbiamo annunciato che può essere installato anche sul computer di casa.
Il progetto Jitsi fornisce una guida rapida per l’installazione, ed anche noi ci rifaremo a quella, ma risulta non aggiornata ad alcuni cambiamenti dei valori di default.
Vi faremo vedere passo passo le varie fasi, ed ggiungeremo anche un pezzetto in più: l’autenticazione dell’host, ovvero poter creare delle utenze che si autentichino con userid e password, e solo queste abbiano il potere di iniziare una videoconferenza (creare una stanza).

Prerequisiti

Come la maggioranza dei prodotti open-source, il sistema operativo richiesto è Linux.
Il progetto fornisce un repository e i paccchetti .deb già compilati, per cui qualunque distribuzione basata su Debian è usabile: Ubuntu, Mint, Debian stesso. Noi, per l’appunto, abbiamo scelto Debian.

Jitsi è basato su linguaggi interpretati o portabili (Java e LUA), e in sé non richiede grandi risorse. Più persone in contemporanea dovranno usare il servizio, più risorse saranno necessarie. Come riferimento, con il notebook usato dai nostri test casalinghi (AMD A6-3400M con 4GB di RAM) non è stato riscontrato alcun problema con 6 interlocutori. Da notare che in questi casi la banda (in uscita) risulta essere uno dei parametri più decisivi.

Jitsi è composto da 3 componenti server:

  • prosody (gestisce con XMPP le stanze e le utenze in ogni stanza);
  • jicofo (il ripetitore di pacchetti UDP, e si appoggia a prosody per sapere chi è in quale stanza);
  • jitsi-videobridge (il ponte tra i vari componenti).

A questi si aggiunge un server web: i pacchetti forniti da Jitsi di default usano nginx, ma è supportato anche apache2 (noi però non lo abbiamo testato).
Completa l’installazione un file di configurazione del client Javascript (Jitsi Meet), che viene inviato dal server ad ogni partecipante: in questo modo, tutto quello che è necessario per il client è il browser web (Chrome).

Noi partiremo da una macchina con installazione minimale, localizzata in italiano, ma ovviamente controllate voi cosa vi serve.
Tutti i comandi saranno dati con l’utenza di root.

jitsi@jitsi:~$ su -
Password: 
root@jitsi:~$ 

Aggiunta repository

Con la nostra installazione minimale mancano delle componenti usate dal repository Jitsi:

  • gnupgp;
  • supporto al trasporto https per apt.

Per installare entrambi, usiamo il fidato apt-get, usando l’opzione --no-install-recommends per evitare pacchetti non strettamente necessari (mentre -y esegue l’installazione senza ulteriori conferme).

root@jitsi:~$ apt-get install --no-install-recommends -y gnupg apt-transport-https
Lettura elenco dei pacchetti... Fatto
Generazione albero delle dipendenze       
Lettura informazioni sullo stato... Fatto
I seguenti pacchetti aggiuntivi saranno inoltre installati:
  dirmngr gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpg-wks-server gpgconf gpgsm libassuan0 libksba8 libnpth0 pinentry-curses
Pacchetti suggeriti:
  dbus-user-session pinentry-gnome3 tor parcimonie xloadimage scdaemon pinentry-doc
I seguenti pacchetti NUOVI saranno installati:
  apt-transport-https dirmngr gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client gpg-wks-server gpgconf gpgsm libassuan0 libksba8 libnpth0
  pinentry-curses
0 aggiornati, 15 installati, 0 da rimuovere e 0 non aggiornati.
È necessario scaricare 7.238 kB di archivi.
Dopo quest'operazione, verranno occupati 15,0 MB di spazio su disco.
[...]
Configurazione di gnupg (2.2.12-1+deb10u1)...
Elaborazione dei trigger per man-db (2.8.5-2)...
Elaborazione dei trigger per libc-bin (2.28-10)...

Il repository fornisce pacchetti firmati con una chiave GPG, che dobbiamo scaricare e importare tra quelle affidabili.
Ci basta una riga, che combina i due comandi:

root@jitsi:~$ wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | apt-key add -
OK

Ora creiamo un nuovo file con sotto la cartella /etc/apt/sources.list.d, con il contenuto deb https://download.jitsi.org stable/. Per farlo, anche in questo, caso basta il comando di una riga:

root@jitsi:~$ echo 'deb https://download.jitsi.org stable/' > /etc/apt/sources.list.d/jitsi-stable.list

E ora update del database locale dei pacchetti (in modo da aggiungere tra i disponibili anche quelli offerti da Jitsi)

root@jitsi:~$ apt-get update
Trovato:1 http://security.debian.org/debian-security buster/updates InRelease
Trovato:2 http://debian.mirror.garr.it/debian buster InRelease             
Trovato:3 http://debian.mirror.garr.it/debian buster-updates InRelease     
Scaricamento di:4 https://download.jitsi.org stable/ InRelease [1.882 B]   
Scaricamento di:5 https://download.jitsi.org stable/ Packages [39,7 kB]                                                                                      
Recuperati 41,6 kB in 26s (1.611 B/s)              
Lettura elenco dei pacchetti... Fatto

Installazione pacchetti

Ora abbiamo tutto per installare Jitsi, che si limita al pacchetto che ha come dipendenza tutti i pacchetti descritti sopra: jitsi-meet.
Durante l’installazione ci saranno fatte delle domande per la configurazione di base di Jitsi, che si occupa anche della creazione della configurazione per il server web.

root@jitsi:~$ apt-get install --no-install-recommends -y jitsi-meet
Lettura elenco dei pacchetti... Fatto
Generazione albero delle dipendenze       
Lettura informazioni sullo stato... Fatto
I seguenti pacchetti aggiuntivi saranno inoltre installati:
  ca-certificates-java fontconfig-config fonts-dejavu-core java-common jicofo jitsi-meet-prosody jitsi-meet-web jitsi-meet-web-config jitsi-videobridge2
  libavahi-client3 libavahi-common-data libavahi-common3 libcups2 libfontconfig1 libgd3 libjbig0 libjpeg62-turbo liblcms2-2 libnginx-mod-http-auth-pam
  libnginx-mod-http-dav-ext libnginx-mod-http-echo libnginx-mod-http-geoip libnginx-mod-http-image-filter libnginx-mod-http-subs-filter
  libnginx-mod-http-upstream-fair libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libnspr4 libnss3 libtiff5 libwebp6 libxi6 libxpm4
  libxrender1 libxslt1.1 libxtst6 lua-bitop lua-expat lua-filesystem lua-sec lua-socket lua5.2 nginx nginx-common nginx-full openjdk-11-jre-headless prosody
  ssl-cert uuid-runtime x11-common
Pacchetti suggeriti:
  default-jre cups-common libgd-tools liblcms2-utils fcgiwrap nginx-doc libnss-mdns fonts-dejavu-extra fonts-ipafont-gothic fonts-ipafont-mincho
  fonts-wqy-microhei | fonts-wqy-zenhei fonts-indic lua-dbi-mysql lua-dbi-postgresql lua-dbi-sqlite3 lua-zlib openssl-blacklist
Pacchetti raccomandati:
  jitsi-meet-turnserver | apache2 lua5.2-event
I seguenti pacchetti NUOVI saranno installati:
  ca-certificates-java fontconfig-config fonts-dejavu-core java-common jicofo jitsi-meet jitsi-meet-prosody jitsi-meet-web jitsi-meet-web-config
  jitsi-videobridge2 libavahi-client3 libavahi-common-data libavahi-common3 libcups2 libfontconfig1 libgd3 libjbig0 libjpeg62-turbo liblcms2-2
  libnginx-mod-http-auth-pam libnginx-mod-http-dav-ext libnginx-mod-http-echo libnginx-mod-http-geoip libnginx-mod-http-image-filter
  libnginx-mod-http-subs-filter libnginx-mod-http-upstream-fair libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libnspr4 libnss3
  libtiff5 libwebp6 libxi6 libxpm4 libxrender1 libxslt1.1 libxtst6 lua-bitop lua-expat lua-filesystem lua-sec lua-socket lua5.2 nginx nginx-common
  nginx-full openjdk-11-jre-headless prosody ssl-cert uuid-runtime x11-common
0 aggiornati, 52 installati, 0 da rimuovere e 0 non aggiornati.
È necessario scaricare 115 MB di archivi.
Dopo quest'operazione, verranno occupati 296 MB di spazio su disco.
[...]

Prima domanda: hostname. Questo è l’identificativo della macchina, e verrà usato per i nomi di alcuni file di configurazione.
Inoltre, di default viene creato un certificato self-signed, ma è fornito anche uno script per generare dei certificati con Let’s Encrypt: l’hostname usato qui sarà quello esposto dal server web e quindi usato per il certificato, ovvero l’hostname con cui sarà raggiungibile da internet.

Noi abbiamo scelto jitsi.mmul.local

Noi, per la nostra installazione useremo solo i certificati self-signed, in quanto solo una macchina di test.
Piccola nota: se volessimo poter usare anche l’app mobile, allora dovremo usare certificati validi: il self-signed è rifiutato.
Nel caso avessimo già i certificati da usare, si potrebbe usare l’altra opzione per indicarne il path.
Ripetiamo un dettaglio dei certificati: servono solo per il server web, la cui configurazione può essere modificata a piacimento successivamente sia per usare un certificato diverso, sia per non usare un certificato (magari perché dietro un bilanciatore che termina la connessione SSL).

A questo punto l’installazione prosegue, con anche generazione delle chiavi e indicazione del già citato script

# [...]
writing new private key to '/etc/jitsi/meet/jitsi.mmul.local.key'
-----
----------------

You can now switch to a Let’s Encrypt certificate. To do so, execute:
/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

----------------
Configurazione di jitsi-meet (2.0.4416-1)...
# [...]

Server web, servizio jitsi e componenti varie saranno già pronte all’uso!

Da notare come la pagina sia simile (praticamente la stessa) di quella offerta da meet.jit.si, ma che è in italiano: avendo localizzato l’installazione del sistema operativo, di default l’applicazione usa lo stesso linguaggio.

Configurazione firewall

Jitsi ha bisogno di sole due porte direttamente raggiungibili da internet (esposte) per poter lavorare:

  • la 443 in TCP per il server web (la classica porta di HTTPS);
  • la 10000 in UDP per i pacchetti del flusso video (per le conferenze da 3 persone in su).

Se volessimo (o dovessimo) cambiare la porta UDP esposta, dovremmo modificare il file di configurazione della componente videobridge, localizzato in /etc/jitsi/videobridge/sip-communicator.properties, aggiungendo una riga:

org.jitsi.videobridge.SINGLE_PORT_HARVESTER_PORT=<port>

Inoltre, a differenza di quanto riportato nella documenazione, la configurazione per un server STUN/TURN è già presente, puntando ad un server di jitsi.

org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=meet-jit-si-turnrelay.jitsi.net:443

Questo permette al server di funzionare anche dietro un firewall con NAT, ovvero la maggioranza dei casi (casalinghi, ma non solo).
Per ora lasciamo quello impostato, ma anche questo servizio è installabile su un server proprio (meglio con IP pubblico statico).

Per quanto riguarda le connessioni in uscita, non dovrebbe avere limitazioni (almeno su porte UDP): deve poter contattare qualunque host su qualunque porta.

Autenticazione membri host

Se il server jitsi è esposto su internet, possiamo limitarne l’uso chiedendo un’autenticazione prima della creazione di una stanza.
Per poter abilitare questa funzione, dobbiamo aggiungere la configurazione adeguata in tre componenti:

  • prosody (per creare un nuovo dominio in cui censire le utenze);
  • jicofo (per definire con quale virtuahost fare l’autenticazione);
  • jitsi-meet (per informare il client che esistono due domini, uno anonimo ed uno ad autenticato).

Prosody

Prosody è un server scritto in LUA che gestisce le utenze XMPP; questo implica che i singoli utenti sono identificati da un username e un dominio di appartenenza.
La configurazione si trova in /etc/prosody/conf.avail/<hostname>.cfg.lua, quindi nel nostro caso /etc/prosody/conf.avail/jitsi.mmul.local.cfg.lua. Qua le prime righe:

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 = "jitsi.mmul.local";

turncredentials_secret = "YgrXTqcbMKXMfQUG";

turncredentials = {
  { type = "stun", host = "jitsi.mmul.local", port = "4446" },
  { type = "turn", host = "jitsi.mmul.local", port = "4446", transport = "udp" },
  { type = "turns", host = "jitsi.mmul.local", port = "443", transport = "tcp" }
};

cross_domain_bosh = false;
consider_bosh_secure = true;

VirtualHost "jitsi.mmul.local"
        -- enabled = false -- Remove this line to enable this host
        authentication = "anonymous"
        -- Properties below are modified by jitsi-meet-tokens package config
        -- and authentication above is switched to "token"
        --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/jitsi.mmul.local.key";
                certificate = "/etc/prosody/certs/jitsi.mmul.local.crt";
        }
        speakerstats_component = "speakerstats.jitsi.mmul.local"
        conference_duration_component = "conferenceduration.jitsi.mmul.local"
        -- we need bosh
        modules_enabled = {
            "bosh";
            "pubsub";
            "ping"; -- Enable mod_ping
            "speakerstats";
            "turncredentials";
            "conference_duration";
        }
        c2s_require_encryption = false

Component "conference.jitsi.mmul.local" "muc"
    storage = "memory"
[...]

Dovremo creare un nuovo VirtualHost (guest.<hostname>) semplicemente copiando quello già presente senza autenticazione (authentication = "anonymous"), e attiveremo l’autenticazione in quello già configurato (authentication = "internal_plain").

Ecco quindi il VirtualHost che andremo ad aggiungere

VirtualHost "guest.jitsi.mmul.local"
        -- enabled = false -- Remove this line to enable this host
        authentication = "anonymous"
-- [...]
        c2s_require_encryption = false

VirtualHost "jitsi.mmul.local"
        -- enabled = false -- Remove this line to enable this host
        authentication = "internal_plain"
-- [...]
        c2s_require_encryption = false

Component "conference.jitsi.mmul.local" "muc"
-- [...]

L’opzione usata salva le password in chiaro: per il nostro server di test è più che sufficiente. Se volete un poco più di segretezza è disponibile anche internal_hashed, che usa SHA1, oppure cyrus per integrazione con sistemi esterni come LDAP: ben oltre le intenzioni di questa guida.

jicofo

Informiamo jicofo (che fa da accentratore delle utenze, per gestire le istanze) che deve puntare al VirtualHost con autenticazione prima di creare una stanza. Basta aggiungere una riga al suo file di configurazione /etc/jitsi/jicofo/sip-communicator.properties

org.jitsi.jicofo.auth.URL=XMPP:jitsi.mmul.local

jitsi-meet

Ora andiamo a modificare il client, o meglio il file di configurazione JavaScript: /etc/jitsi/meet/jitsi.mmul.local-config.js.

/* eslint-disable no-unused-vars, no-var */

var config = {
    // Connection
    //

    hosts: {
        // XMPP domain.
        domain: 'jitsi.mmul.local',

        // When using authentication, domain for guest users.
        // anonymousdomain: 'guest.example.com',
// [...]

Dobbiamo indicare il virtuahost anonimo: basta decommentare la riga e “aggiustare” il dominio:

// [...]
    hosts: {
        // XMPP domain.
        domain: 'jitsi.mmul.local',

        // When using authentication, domain for guest users.
        anonymousdomain: 'guest.jitsi.mmul.local',
// [...]

Ora che abbiamo preparato tutto, riavviamo prosody (giusto per essere sicuri che sia usata la nuova configurazione), jicofo (e visto che ci siamo anche videobridge):

# systemctl restart prosody jicofo jitsi-videobridge2

Infine, le utenze. Prosody ha una interfaccia di controllo (prosodyctl) che accetta vari comandi, e in particolare ci interessa register per creare una nuova utenza.

root@jitsi:~$ prosodyctl register <username> <hostname> [<password>]

Quindi, per creare l’utenza MMMULTutorial nel nostro server

root@jitsi:~$ prosodyctl register MMULTutorial jitsi.mmul.local
Enter new password: 
Retype new password: 

Il comando creerà un file in /var/lib/prosody/<hostname>/accounts, col nome utente (in minuscolo) usato ed estensione .dat. Nel nostro caso, quindi, /var/lib/prosody/jitsi%2emmul%2elocal/accounts/mmmultutorial.dat (notate l’uso di %2e al posto del . nel path).

Bene! Ora, chi vuole creare una stanza (avviare una videconforenza) deve prima autenticarsi.

Cliccando su “sono l’organizzatore” ci verranno chieste userID e password: solo quando convalidate la stanza sarà disponibile.

Ultime note finali

L’installazione così completata ha tutte le funzioni descritte nella breve guida già presentata.
Anche le funzioni solo elencate sono presenti, tranne la registrazione video in Dropbox: per quella c’è bisogno di un altro componente (Jibri), su un host dedicato e di altri step di configurazione, che non tratteremo. Almeno, pero ora!

Ho coltivato la mia passione per l’informatica fin da bambino, coi primi programmi BASIC. In età adulta mi sono avvicinato a Linux ed alla programmazione C, per poi interessarmi di reti. Infine, il mio hobby è diventato anche il mio lavoro.
Per me il modo migliore di imparare è fare, e per questo devo utilizzare le tecnologie che ritengo interessanti; a questo scopo, il mondo opensource offre gli strumenti perfetti.