Galène est un logiciel libre distribué sous licence MIT qui a pour objectif de fournir une solution de visioconférence pour l’enseignement et les exposés scientifiques accessible depuis un navigateur web. Il est développé à l’Université de Paris-Diderot par Juliusz Chroboczek. Il permet de :
Galène n’est pas un concurrent de BBB mais se veut avant tout un logiciel simple, robuste et efficace aux fonctionnalités strictement limitées. Voir le serveur de démonstration.
On trouve dans ce document quelques éléments permettant d’auto-héberger un serveur de visioconférence Galène, c’est-à-dire :
visio.
d’un nom de domaine.Pour la suite, j’utilise les variables :
${VISIO} # le nom de la VM sur laquelle tourne Galène
${PRIVATE_IP} # l'IP privée de cette VM, du type 192.168.1.XX
${PUBLIC_IP} # votre IP publique, celle de votre box
${MONDOMAINE} # votre nom de domaine
J’ai pris l’habitude d’administrer mes machines virtuelles avec KVM. Pour faire de même, sur l’hôte installer :
# apt install qemu-system qemu-system-x86 qemu-utils \
libvirt-clients libvirt-daemon-system \
virtinst bridge-utils
Pour que la VM partage la connexion réseau de l’hôte, il est nécessaire de définir une connexion de type bridge par exemple avec le script (copié ici) :
export MAIN_CONN=enp0s31f6
bash -x << EOF
systemctl stop libvirtd
nmcli c delete "$MAIN_CONN"
nmcli c delete "Wired connection 1"
nmcli c add type bridge ifname br0 autoconnect yes con-name br0 stp off
nmcli c modify br0 ipv4.addresses ${PRIVATE_IP}/24 ipv4.method manual
nmcli c modify br0 ipv4.gateway 192.168.1.1
nmcli c modify br0 ipv4.dns 192.168.1.1
nmcli c add type bridge-slave autoconnect yes con-name "$MAIN_CONN" \
ifname "$MAIN_CONN" master br0
systemctl restart NetworkManager
systemctl start libvirtd
systemctl enable libvirtd
echo "net.ipv4.ip_forward = 1" \
| sudo tee /etc/sysctl.d/99-ipforward.conf
sysctl -p /etc/sysctl.d/99-ipforward.conf
EOF
où enp0s31f6
est le nom de votre carte réseau, obtenu avec :
$ nmcli con show
Sur une machine « correcte », créer une machine virtuelle, ici avec Debian bullseye (on ne se refait pas) à laquelle j’ai alloué 4 coeurs (vcpus
) et 8 Go de RAM (ram
) :
# virt-install \
--name ${VISIO} \
--vcpus 4 \
--ram 8192 \
--disk path=/somewhere/${VISIO}.qcow2,size=10 \
--os-type linux \
--os-variant debian11 \
--network bridge=br0 \
--graphics none \
--console pty,target_type=serial \
--location 'http://ftp.debian.org/debian/dists/bullseye/main/installer-amd64/' \
--extra-args 'console=ttyS0,115200n8 serial'
où br0
est l’interface bridge.
procéder à l’installation avec juste un serveur SSH et le minimum vital des coreutils ;
démarrer et se connecter à la machine virtuelle
# virsh start ${VISIO}
# virsh console ${VISIO}
mettre à jour puis installer le minimum vital
# apt update && apt full-upgrade
# apt install vim git
Avec le paquet golang-go
de Debian bullseye, il y a un problème à la compilation de Galène :
user@${VISIO}:~/galene# CGO_ENABLED=0 go build -ldflags='-s -w'
build github.com/jech/galene: cannot find module for path crypto/ed25519
Pour le contourner, il est nécessaire d’installer une version plus récente, au minimum la 1.17, que l’on trouve sur la page golang.org/dl :
pour installer la version 1.19.3 (la dernière à la date de mise à jour) :
$ wget https://dl.google.com/go/go1.19.3.linux-amd64.tar.gz
# tar -C /usr/local -xzf go1.19.3.linux-amd64.tar.gz
ajouter au PATH
# echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.profile
# source ~/.profile
purger les fichiers temporaires
# rm -rf go*
télécharger Galène
# git clone https://github.com/jech/galene
compiler Galène
# cd galene
# CGO_ENABLED=0 go build -ldflags='-s -w'
ajouter un administrateur du serveur
# mkdir data
# echo "<user>:<password>" > data/passwd
ajouter un groupe
# mkdir groups
# cat > groups/<groupname>.json << EOF
{
"op": [{"username": "<user0>", "password": "<pwd0>"}],
"presenter": [
{"username": "<user1>", "password": "<pwd1>"},
{"username": "<user2>", "password": "<pwd2>"}
]
}
EOF
Pour laisser l’accès libre à tous, il faut mettre
"presenter": [{}]
lancez Galène depuis votre réseau local
# ./galene
puis vérifier que vous pouvez vous connecter à l’adresse
https://<localIP>:8443
puis à <groupname>
.
Vous avez un avertissement de sécurité, c’est normal, on n’a pas encore installé de certificat. Vous pouvez lancer une vidéo, et si vous vous connectez deux fois, vous vous voyez.
installer coturn
# apt install coturn
arrêter le service
# service coturn stop
éditer le fichier de configuration
cat > /etc/turnserver.conf << EOF
listening-port=1194
fingerprint
lt-cred-mech
user=${TURN_USER}:${TURN_PWD}
server-name=visio.${MONDOMAINE}
realm=${MONDOMAINE}
EOF
relancer le serveur
# service coturn start
éditer le fichier de configuration de Galène
cat > galene/data/ice-servers.json << EOF
[
{
"urls": [
"turn:visio.${MONDOMAINE}:1194",
"turn:visio.${MONDOMAINE}:1194?transport=tcp"
],
"username": "${TURN_USER}",
"credential": "${TURN_PWD}"
}
]
Si vous êtes derrière une box Internet, ouvrez les ports du pare-feu et redirigez les vers votre serveur frontal (sur les mêmes ports) :
Dans le cas où Galène n’est pas le seul service hébergé sur ${MONDOMAINE}
, il est nécessaire de définir un reverse proxy pour rediriger les requêtes de votre sous-domaine
visio.${MONDOMAINE}
vers
https://${PRIVATE_IP}:8443
Pour le reverse proxy, on utilise ici NGINX.
Installer NGINX
# apt install nginx
démarrer le service
# systemctl start nginx
puis le rendre actif à chaque démarrage
# systemctl enable nginx
Afin de sécuriser le protocole HTTP avec une couche de chiffrement SSL/TLS et garder privées les communications entre les utilisateurs et le serveur, on utilisera par défaut le HTTPS, en écoute du port TCP 443.
On se réfère aux recommandations de la fondation mozilla qui ne sont pas en contradiction avec celles de l’ANSSI. On utilise en particulier le générateur sur lequel on renseigne la version de NGINX, obtenue avec :
$ nginx -v
et celle de openssl
$ openssl version
Pour intégrer ces recommandations, il faut :
générer dhparam.pem
nécessaire à la configuration SSL avec NGINX
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
éditer le fichier /etc/nginx/nginx.conf
pour
TLSv1
et TLSv1.1
sur la ligne ssl_protocols
pour ne garder que TLSv1.2
et TLSv1.3
;ssl_prefer_server_ciphers
pour off
;et donc avoir les lignes :
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
relancer NGINX
# systemctl reload nginx
# service nginx restart
On se base sur les recommandations de l’ANSII et sur l’article pour durcir les réponses HTTP du serveur, notamment :
iframes
;Pour cela, éditer le fichier de configuration :
# vim /etc/nginx/nginx.conf
en ajoutant les lignes :
server{
...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header 'Referrer-Policy' 'origin';
...
}
puis relancer NGINX :
# service nginx restart
Vérifier ensuite votre configuration en faisant analyser votre site.
créer un fichier de configuration pour le service associé à Galène
# cat > /etc/nginx/conf.d/visio.conf << EOF
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name visio.${MONDOMAINE};
# Tell all requests to port 80 to be 302 redirected to HTTPS
return 302 https://$host$request_uri;
}
server {
listen 443;
ssl on;
server_name visio.${MONDOMAINE};
ssl_certificate /etc/letsencrypt/live/visio.${MONDOMAINE}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/visio.${MONDOMAINE}/privkey.pem;
# Managing literal requests to the Galène front end
location / {
proxy_pass https://${PRIVATE_IP}:8443;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Managing requests to verify letsencrypt host
location ~ /.well-known {
allow all;
}
EOF
Activer le pare-feu
# apt install ufw
# ufw enable
puis ouvrir les ports
# ufw allow ssh
# ufw allow 80/tcp
# ufw allow 443/tcp
# ufw allow 1194/tcp
# ufw allow 1194/udp
# ufw allow 8443/tcp
puis vérifier
# ufw status
qui doit renvoyer
Status: active
To Action From
-- ------ ----
Nginx HTTP ALLOW Anywhere
Nginx HTTPS ALLOW Anywhere
22/tcp ALLOW Anywhere
1194 ALLOW Anywhere
8443/tcp ALLOW Anywhere
Nginx HTTP (v6) ALLOW Anywhere (v6)
Nginx HTTPS (v6) ALLOW Anywhere (v6)
22/tcp (v6) ALLOW Anywhere (v6)
1194 (v6) ALLOW Anywhere (v6)
8443/tcp (v6) ALLOW Anywhere (v6)
arrêter le serveur nginx
# service nginx stop
générer les certificats SSL
# apt install certbot
# certbot certonly --standalone -d visio.${MONDOMAINE}
qui va générer deux fichiers :
/etc/letsencrypt/live/visio.${MONDOMAINE}/fullchain.pem
/etc/letsencrypt/live/visio.${MONDOMAINE}/privkey.pem
puis générer dhparam.pem
nécessaire à la configuration SSL avec nginx
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
relancer nginx
# systemctl reload nginx
# service nginx restart
Relancer Galène
# ./galene
Connectez-vous de l’extérieur avec l’URL
https://visio.${MONDOMAINE}
vous devez maintenant avoir une connexion sécurisée.
Si l’étape cette échoue, alors il y a un problème de port forwarding. Il vous faut dans ce cas vérifiez que vous ne vous êtes pas trompé, et que le port 1194 est bien accessible depuis l’extérieur.
Vérifiez que vous pouvez voir des vidéos entre deux clients externes, et entre un client interne et un client externe.
Regardez dans le log de Galène si le relay test côté serveur marche aussi ; si ce n’est pas le cas, il y a un problème de “hairpinning”…
Essayer de taper dans le chat
/relay-test
Galène doit vous dire que le test est réussi.
Pour définir un service qui permette de lancer Galène avec systemd
dès le lancement de la VM :
virsh start ${VISIO}
éditer le fichier de service
# cat > /srv/galene/galene.service << EOF
[Unit]
Description=Galene
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/srv/galene
ExecStart=/srv/galene/galene
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
faire un lien symbolique vers systemd
# ln -s /srv/galene/galene.service /etc/systemd/system/.
relancer le daemon
# systemctl daemon-reload
activer puis démarrer le service
# systemctl enable galene.service
# systemctl start galene.service
et vérifier son statut avec
# systemctl status galene.service
Pour mettre à jour Galène, par exemple pour galene-0.6.2
du 11/01/2023, on peut procéder de deux façons :
se placer dans le répertoire galene
;
# cd galene
# git checkout master
télécharger la mise à jour
# git fetch -p https://github.com/jech/galene galene-0.6.2
# git checkout galene-0.6.2
compiler
# CGO_ENABLED=0 go build -ldflags='-s -w'
relancer le service
# systemctl restart galene.service
ou alors :
cloner le dépot :
# git clone -b galene-0.6.2 https://github.com/jech/galene
compiler Galène
# cd galene
# CGO_ENABLED=0 go build -ldflags='-s -w'
copier les répertoires data
et groups
de votre « ancienne » installation ;
copier galene.service
puis recharger le deamon :
# systemctl daemon-reload
# systemctl enable galene.service
# systemctl start galene.service
et vérifier son statut avec
# systemctl status galene.service
Je tiens à remercier chaleureusement Juliusz Chroboczek pour son aide précieuse et rudement efficace pour la configuration de mon serveur ainsi que Fabrice Rouillier pour son aide pour la mise en place d’un service IPv4 avec le serveur coTURN. Une bonne partie de cette documentation n’est qu’une remise en forme de leurs propos.