Petit guide d’installation de XMPP sur une jail FreeBSD.
Niveau : intermédiaire.
Ce billet de blog n’exiterait pas sans celui de ma camarade Codimp
Translate Me
Pré-requis
Outre une jail en état de fonctionner avec les outils de base (vim, sudo, zsh),
Il nous faut :
- un serveur DNS en état de marche et accessible ;
- un nom de domaine
example.com
; - plusieurs sous-domaine :
- conference.example.com : pour les discussions de groupe ;
- proxy.xmpp.example.com : le proxy sock5 ;
- xmpp.example.com : le proxy HTTP pour le transferts de fichiers ;
- les certificats pour votre instance (par exemple prosody.example.com).
nous aurons besoin d’ouvrir certains ports sur le firewall (pf
).
Ces ports ont au nombre de 7 (comme les nains). En voici la liste :
- 5222 : Port de dialogue en les clients et les serveurs (aka c2s) ;
- 5223 : Port de dialogue en les clients et les serveurs sur TLS (aka c2s ausi) ;
- 5269 : Port de dialogue entre les serveurs (aka s2s) ;
- 5270 : Port de dialogue entre les serveurs sur TLS (aka s2s) ;
- 5280 : Proxy HTTP BOSH ;
- 5281 : Proxy HTTP BOSH sur TLS ;
- 5000 : Proxy socks5 pour les transferts.
Il faudra faire des changements sur le DNS.
En cas de doute, référez-vous à la documentation.
Rappel : le signe
%
en début de ligne indique une commande lancée par un utilisatur lambda, le signe#
indique une commande lancée par l’utilisatur root
Installation de prosody
Nous faire cette installation tout doucement en commençant par le logiciel principal, sources ouvertes naturellement, prosody.
# sudo pkg install prosody
Lisez attentivement le message de l’installation. Vous pourrez le retrouver avec la commande
% pkg info -D prosody
.
Configuration de prosody
La configuration se trouve dans /usr/local/etc/prosody
.
On trouve dans ce répertoire les fichiers *.lua
et *.lua.sample
.
Ne supprimez pas les fichiers
*.lua.sample
, ils peuvent à tout moment servir de référence (en plus des pages deman
uel et de la documentation).
Lisez les commentaires du fichier de configuration, ils sont très utiles pour comprendre la syntax.
Éditez le fichier prosody.cfg.lua
.
Je commence par indiquer l’adresse email du ou des administrateurs de l’instance :
admins = { "admin@example.com" }
Il faut indiquer dans plugins_path
, le chemin vers les modules :
/usr/local/lib/prosody/modules
et
/usr/local/lib//prosody/modules-mercurial
.
Viennent ensuite les modules qui vont être utilisés.
J’ai retiré invites
, invites_adhoc
,
invites_register
, register
et ajouté le module mam
. turn_external
Dans les Admin interfaces rien a modifier.
Dans les HTTP modules j’ai activé bosh
et websocket
.
Passons aux Other specific functionality ;
annouce
, server_contact_info
Attention aux modules_disabled, lisez les commentaires.
De nombreuses lignes n’ont pas à être modifiées (selon ma configration).
Par contre, des options décritess dans la documentation ne sont pas présentes dans le fichier.
c2s_direct_tls_ports = { 5223 };
s2s_direct_tls_ports = { 5270 };
et, pour ne pas ouvrir l’enregistrement depuis l’extérieur,
allow_registration=false
Dans la rubrique (à brac) Storage, j’ai choisi sql
et la base de données
SQLite3
, qu’il faudra penser à installer.
Je n’ai pas réussi à faire fonctionner Prosody avec Sqlite3, je suis repassé au stock interne.
Rubrique Audio/video
XMPP à l’aide d’un serveur TURN, qu’il faudra installer ultérieurment.
Mais j’ai besoin de renseigner certains items :
turn_external_host = xmpp.example.com
turn_external_secret=UnSuperSecret
turn_external_port = 3478
Pour la gestion des logs il est possibie de tout confier à syslog
, en
gardant en tête qu’il era nécesaire d’installer et de configurer logrotate
.
Les certificats doivent être accesible à prosody, c’est pourquoi ils sont
dans le répertoire certs
.
Si vous utiliez letencrypt pour obtenir vos certificats, il est important de lire la page de documentation.
Configuration de Virtual hosts
Prosody a beoin d’au moins un virtual hosts. Il faut désativer localhost
pour mieux définir xmpp.example.com.
Ici s’éteingent les commentaires et seule la
documentation peut nous venir en
aide.
Voici une possibilité :
VirtualHost "example.com"
-- Assign this host a certificate for TLS, otherwise it would use the one
-- set in the global section (if any).
ssl = {
key = "/etc/prosody/certs/example.com.key";
certificate = "/ur/local//etc/prosody/certs/example.com.crt";
ciphers = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256";
protocol = "tlsv1_2+";
dhparam = "/ur/local//etc/prosody/certs/dh-2048.pem";
options = {
"cipher_server_preference",
"no_compression",
"no_ticket",
"single_dh_use",
"single_ecdh_use"
};
}
disco_items = {
{ "proxy.xmpp.exemple.com", "SOCKS5 proxy" };
{ "conf.exemple.com", "Chatrooms" };
{ "xmpp.exemple.com", "File sharing service" };
}
Pour terminer, il faut configurer les Components.
Les commentaires sont, là encore très utiles et la documentation est toujours là.
---Set up a MUC (multi-user chat) room server on conf.example.com:
Component "conference.example.com" "muc"
modules_enabled = { "muc_mam", "muc_moderation", "vcard_muc" }
name = "Chatrooms"
restrict_room_creation = "local"
muc_max_rooms = 100
muc_room_default_public = false
-- Set up a SOCKS5 bybasejailream proxy for server-proxied file transfers:
Component "proxy.xmpp.example.com" "proxy65"
proxy65_address = "example.com"
proxy65_acl = { "example.com" }
Component "xmpp.example.com" "http_file_share"
http_file_share_size_limit = 1024 × 1024 × 10
http_file_share_expire_after = 60 × 60 × 24 × 21600
Nous en avons fini avec la Configuration de prosody.
L’installation de l’instance n’est pas termnée pour autant. Il faut :
- installer les modules mercurial ;
- mettre en place les certificats ;
- ~~installer SQLIte3 ~~;
- mettre à jour le DNS ;
- modifier le firewall ;
- tester..
Installation des modules mercurial
Pour installer ces modules, nous allons avoir besoin d’installerle logiciel
mercurial
un « équivalent » de git
.
# pkg install -y mercurial
Puis on clone le dépôt qui propose des modules supplémentaires qui sont déjà utilisés dans le fichier de configuration principal.
# hg clone https://hg.prosody.im/prosody-modules/ /usr/local/lib/prosody/modules
Il y a très peu de chance que nous ayions à utiliser à nouveau mercurial. Pour le désintaller la commande est
# pkg remove mercurial
Mise à jour du DNS
Sur la machine/jail qui gère ma zone DNS il faut que j’ajoute des enregistrements.
; xmpp
_xmpp-client._tcp 3600 IN SRV 0 5 5222 xmpp.example.com.
_xmpps-client._tcp 3600 IN SRV 0 5 5223 xmpp.example.com.
_xmpp-server._tcp 3600 IN SRV 0 5 5269 xmpp.example.com.
_xmpps-server._tcp 3600 IN SRV 0 5 5270 xmpp.example.com.
_xmpp-server._tcp.conf 3600 IN SRV 0 5 5270 xmpp.example.com.
_xmpps-server._tcp.conf 3600 IN SRV 0 5 5270 xmpp.example.com.
Et plus loin (chez moi c’est en fin de fichier de zone, celui-ci étant classé alphabétiquement).
;--- xmpp
xmpp A 192.0.2.124
xmpp AAAA
2001:DB8::1234:1234:1234:1234:1234:1234
conf CNAME xmpp.example.com.
upload CNAME xmpp.example.com.
turn CNAME xmpp.example.com.
Ne pas oublier de changer le serial et les points . en fin de ligne.
Dans une heure, et depuis une autre machine, je pourrais vérifier que mes changements sont pris en compte :
% drill @8.8.8.8 xmpp.example.com
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 4768
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; xmpp.example.com. IN A
;; ANSWER SECTION:
xmpp.example.com. 21600 IN A 192.0.2.214
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 30 msec
;; SERVER: 8.8.8.8
;; WHEN: Wed Mar 26 10:28:57 2025
;; MSG SIZE rcvd: 49
J’utilise le serveur DNS public de Google (8.8.8.8) et j’obtiens la réponse attendue. Si cela n’avait pas été le cas il m’aurait fallu revoir toute cette partie.
Copie des certificats dans cert
Mes certificats sont issus de Let’s Encrypt ils ont un traitement spécifique avec
l’outil prosodyctl
.
# prosodyctl cert import /usr/local/etc/letsencrypt/live/example.com
ATTENTION :
Si vous montez le répertoire letsencrypt
depuis l’hôte, en nullfs
l’outil
ne fonctionnera pas à cause des permissions. Il est hors de question de changer
les permissions du répertoire letsencrypt
.
La solution que j’ai choisie est d’utilier une petit script demon amie
Codimp :
#!/bin/sh
set -e -o pipefail
# certificates after Certbot renewal
certificate_certbot_path="/usr/local/etc/letsencrypt/live/foucry.net"
certificate_prosody_path="/usr/local/etc/prosody/certs"
prosody_user="prosody"
prosody_group="prosody"
cp $(readlink -f ${certificate_certbot_path}/cert.pem) ${certificate_prosody_path}/foucry.net.crt
cp $(readlink -f ${certificate_certbot_path}/chain.pem) ${certificate_prosody_path}/foucry.net.chain.pem
cp $(readlink -f ${certificate_certbot_path}/fullchain.pem) ${certificate_prosody_path}/foucry.net.fullchain.pem
cp $(readlink -f ${certificate_certbot_path}/privkey.pem) ${certificate_prosody_path}/foucry.net.privkey.pem
chown ${prosody_user}:${prosody_group} ${certificate_prosody_path}/*.pem
service prosody restart
Pour les autres fourniseurs de certificats, référez-vous à la documentation.
Je l’ai indiqué dans la fichier de configuration, j’ai besoin d’un fichier
dhparam
. Je le génère sur la ligne de commande :
# openssl dhparam -out [usr local etc prosody certs dh pem](/usr/local/etc/prosody/certs/dh-2048.pem) 2048
Modification du pare-feu
ATTENTION :
Je pars du principe que vous utilisez pf
, que votre configration est NAT opérationelle et que vous avez les compétences
nécesaires pour finir la configuration du pare-feu.
Il suffit, pour cette jail, de définir son adresse IP et les ports à ouvrir :
xmpp_jailv4="192.168.127.3"
xmpp_jailv6="2001:0DB8:1234:5678::3"
xmpp_ports={ "5222 5223 5269 5270 5280 5281 5000 2203 3478 5249" }
Puis j’ajoute la redirection :
rdr on $ext_if inet proto tcp from yyany to $ext_if port $xmpp_ports ->
xmpp_jailv4
rdr on $ext_if inet proto tcp from yyany to $ext_if port $xmpp_ports ->
xmpp_jailv6
J’ajouté tout de suite les ports pour l’audio et la vidéo, à savoir : - 3478 : Port en clair - 5349 : Port en TLS
Je teste le fichier avec la commande pfctl
:
pfctl -nf /etc/pf.conf
Et si tout est bon, il suffit de supprimer l’option n
de la commande
précédente.
Installation du serveur TURN
L’installation est simple, FreeBSD propose un paquet :
# pkg install turnserver
Configuration du serveur TURN
J’ai copié le fichier /usr/local/etc/turnserver.conf.defautl
dans
/usr/local/etc/turnserver.conf
. C’est ce dernier qui contientra la
configration de mon serveur.
Une fois de plus, lisez les commentaires.
J’ai modifié external-ip
pour mettre l’adresse ip externe de mon serveur.
J’ai également indiqué que je voulais que les tilisateurs soient gérés dans une
bae SQLite3, userdb=/var/db/turndb
.
Je dois configurer les chemains vers les certificats et inquiquer que je
proscri l’utilisation d’anciennes versions de tls : no-tlsv1
et
no-tlsv1\_1
.
Sont imortantes aussi le ligne listen-ip
que j’utilie deux fois, pour
l’adresse IPv4 et l’adresse IPv6.
Démarrage du serveur TURN
Le serveur TURN démarre au lancement de la jail. Il faut donc l’activer dans
le fichier /etc/rc.conf
. Pour simplifier cette étape j’utilise : # service turserver enable
Pour démarrer immédiatement le service, j’utilise # service turnserver start
et je regarde les logs dans /var/log/
Démarrage de Prosody
Tout comme pour turnserver quelques étapess sont indispensables avant le démarrage du serveur XMPP :
- créer le premier utilisateur, moi-même :
# prosodyctl adduser jacques@example.com
; - vérification de la configuration :
# prosodyctl check config
; - changer le propriétaire et le groupe du dossier utilisé pour les échanges
de fichiers :
# chown -R prosody:prosody /ur/local/lib/prosody/http_upload
; - ajouter le serveur prosody à la séquence de démarrage de la jail :
# service prosody enable
La suite, c’est le démarrage du service :
# service prosody start
Regardez le fichier de log. J’ai choisi la gestion des logs par syslog
, c’est
donc le fichier /var/log/debug.log
que je dois regarder.
Mar 30 08:58:59 xmpp prosody[91227]: certmanager: Automatically locating certs for host conference.example.com
Mar 30 08:58:59 xmpp prosody[91227]: certmanager: Using cert "/usr/local/etc/prosody/certs/example.com.fullchain.pem" from index for host "conference.example.com"
Mar 30 08:58:59 xmpp prosody[91227]: conference.example.com:tls: Creating context for s2sin
Mar 30 08:58:59 xmpp prosody[91227]: certmanager: Automatically locating certs for host conference.example.com
Mar 30 08:58:59 xmpp prosody[91227]: certmanager: Using cert "/usr/local/etc/prosody/certs/example.com.fullchain.pem" from index for host "conference.example.com"
Mar 30 08:58:59 xmpp prosody[91227]: unbound: Setting up net.server event handling for ub_ctx: 0x1f5113643238
Mar 30 08:59:00 xmpp prosody[91927]: mod_cron: Running periodic tasks for host example.com
Mar 30 08:59:00 xmpp prosody[91927]: mod_cron: Considering daily task mam/remove_expired_messages (function<mod_mam.lua:545>())
Mar 30 08:59:00 xmpp prosody[91927]: runnerdZhnLBlu6n0_: creating new coroutine
Mar 30 08:59:00 xmpp prosody[91927]: runnerdZhnLBlu6n0_: changed state from ready to error (ready)
Le log me suggère d’activer le module mod_cron
pour nettoyer les messages
expirés. Toutefois, mon serveur semble fonctionner, il faut mainteant que je
fasse des tests.
Derniers mots
Il y a de nombreuses étapes dans la mise en place de ce service, mais souvenez-vous que XMPP est à la base de nombreux logiciels de conférences en visio, je pense notamment à jiti meet qui n’est finalement qu’une jolie interface web sur XMPP.
Il reste à trouver des correspondant·es…