Installation Prosody sous FreeBSD
Ce document traite de l'installation d'un serveur Prosody sous FreeBSD. Pour nos besoins personnels nous souhaitons avoir un service de messagerie privé que nous pouvons administrer à notre convenance et ne pas dépendre de services tiers pour la disponibilité.
Je dispose pour cela d'un VPS dont les caractéristiques sont très modestes tournant sous FreeBSD 15.0.
Composants
- Prosody 13 avec MAM, MUC et HTTP Upload
- Nginx pour HTTP Upload
- Let's Encrypt pour le certificat
- Un nom de domaine et sa zone DNS
Installation Prosody
FreeBSD ne fournit pas de package précompile pour Prosody via pkg. Il faudra donc passer par les ports et compiler l'outil et ses dépendances directement sur le serveur. Cela se fait facilement avec BSD:
$ cd /usr/ports/net-im/prosody
$ make
Dans mon cas il s'agit de ma première compilation de ports, il y a donc un certains nombre de dépendances à compiler. Le build se déroule toutefois sans aucun problème et aboutit au bout d'une bonne demi heure heure, les capacités très modestes du VPS n'aidant pas. Voici un extrait du build pour la partie Prosody uniquement:
===> License MIT accepted by the user
===> prosody-13.0.6 depends on file: /usr/local/sbin/pkg - found
===> Fetching all distfiles required by prosody-13.0.6 for building
===> Extracting for prosody-13.0.6
=> SHA256 Checksum OK for prosody-13.0.6.tar.gz.
===> Patching for prosody-13.0.6
===> Applying FreeBSD patches for prosody-13.0.6 from /usr/ports/net-im/prosody/files
===> prosody-13.0.6 depends on package: gmake>=4.4.1 - found
===> prosody-13.0.6 depends on executable: lua54 - found
===> prosody-13.0.6 depends on shared library: libicudata.so - found (/usr/local/lib/libicudata.so)
===> prosody-13.0.6 depends on shared library: libicui18n.so - found (/usr/local/lib/libicui18n.so)
===> prosody-13.0.6 depends on shared library: libicuuc.so - found (/usr/local/lib/libicuuc.so)
===> Configuring for prosody-13.0.6
Lua interpreter found: /usr/local/bin/lua54...
Checking if /usr/local/bin/lua54 is Lua version 5.4... yes
Looking for lua.h at /usr/local/include/lua54/lua.h...found
Checking if Lua header version matches that of the interpreter... yes
Writing configuration...
Installation prefix: /usr/local
Prosody configuration directory: /usr/local/etc/prosody
Using Lua from: /usr/local
Done. You can now run 'make' to build.
===> Building for prosody-13.0.6
sed "1s| lua$| lua54|; \
s|^CFG_SOURCEDIR=.*;$|CFG_SOURCEDIR='/usr/local/lib/prosody';|; \
s|^CFG_CONFIGDIR=.*;$|CFG_CONFIGDIR='/usr/local/etc/prosody';|; \
s|^CFG_DATADIR=.*;$|CFG_DATADIR='/var/db/prosody';|; \
s|^CFG_PLUGINDIR=.*;$|CFG_PLUGINDIR='/usr/local/lib/prosody/modules/';|;" < prosody > prosody.install
sed "1s| lua$| lua54|; \
s|^CFG_SOURCEDIR=.*;$|CFG_SOURCEDIR='/usr/local/lib/prosody';|; \
s|^CFG_CONFIGDIR=.*;$|CFG_CONFIGDIR='/usr/local/etc/prosody';|; \
s|^CFG_DATADIR=.*;$|CFG_DATADIR='/var/db/prosody';|; \
s|^CFG_PLUGINDIR=.*;$|CFG_PLUGINDIR='/usr/local/lib/prosody/modules/';|;" < prosodyctl > prosodyctl.install
sed 's|certs/|/usr/local/etc/prosody/certs/|' prosody.cfg.lua.dist > prosody.cfg.lua.install
cp prosody.release prosody.version
/usr/local/bin/gmake -C util-src install
gmake[1]: Entering directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/util-src'
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -DUSE_STRINGPREP_ICU -c -o encodings.o encodings.c
cc -shared -L/usr/local/lib -L/usr/lib -o encodings.so encodings.o -licui18n -licudata -licuuc
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o hashes.o hashes.c
cc -shared -L/usr/local/lib -L/usr/lib -o hashes.so hashes.o -lcrypto
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o net.o net.c
cc -shared -L/usr/local/lib -L/usr/lib -o net.so net.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o pposix.o pposix.c
cc -shared -L/usr/local/lib -L/usr/lib -o pposix.so pposix.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o signal.o signal.c
cc -shared -L/usr/local/lib -L/usr/lib -o signal.so signal.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o table.o table.c
cc -shared -L/usr/local/lib -L/usr/lib -o table.so table.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o ringbuffer.o ringbuffer.c
cc -shared -L/usr/local/lib -L/usr/lib -o ringbuffer.so ringbuffer.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o time.o time.c
cc -shared -L/usr/local/lib -L/usr/lib -o time.so time.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o poll.o poll.c
cc -shared -L/usr/local/lib -L/usr/lib -o poll.so poll.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o compat.o compat.c
cc -shared -L/usr/local/lib -L/usr/lib -o compat.so compat.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o strbitop.o strbitop.c
cc -shared -L/usr/local/lib -L/usr/lib -o strbitop.so strbitop.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o struct.o struct.c
cc -shared -L/usr/local/lib -L/usr/lib -o struct.so struct.o
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -c -o crypto.o crypto.c
cc -shared -L/usr/local/lib -L/usr/lib -o crypto.so crypto.o -lcrypto
cc -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fPIC -I/usr/local/include -I/usr/include -I/usr/local/include/lua54 -DWITH_ARC4RANDOM -c -o crand.o crand.c
cc -shared -L/usr/local/lib -L/usr/lib -o crand.so crand.o
install -m644 encodings.so hashes.so net.so pposix.so signal.so table.so ringbuffer.so time.so poll.so compat.so strbitop.so struct.so crypto.so crand.so ../util/
rm crand.o time.o strbitop.o crypto.o compat.o ringbuffer.o net.o table.o hashes.o poll.o signal.o encodings.o struct.o pposix.o
gmake[1]: Leaving directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/util-src'
===> Staging for prosody-13.0.6
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/lfs.so - found
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/luaevent/core.so - found
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/lunbound.so - found
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/lxp.so - found
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/socket/core.so - found
===> prosody-13.0.6 depends on file: /usr/local/lib/lua/5.4/ssl.so - found
===> prosody-13.0.6 depends on executable: lua54 - found
===> Generating temporary packing list
===> Creating groups
===> Creating users
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util
install -p -m644 util/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util
/usr/local/bin/gmake install -C util-src
gmake[1]: Entering directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/util-src'
install -m644 encodings.so hashes.so net.so pposix.so signal.so table.so ringbuffer.so time.so poll.so compat.so strbitop.so struct.so crypto.so crand.so ../util/
gmake[1]: Leaving directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/util-src'
install -p -m644 util/*.so /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/sasl
install -p -m644 util/sasl/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/sasl
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/human
install -p -m644 util/human/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/human
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/prosodyctl
install -p -m644 util/prosodyctl/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/util/prosodyctl
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net
install -p -m644 net/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/http /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/resolvers /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/websocket
install -p -m644 net/http/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/http
install -p -m644 net/resolvers/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/resolvers
install -p -m644 net/websocket/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/net/websocket
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/core
install -p -m644 core/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/core
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_pubsub /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/adhoc /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/muc /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_mam /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_debug_stanzas
install -p -m644 plugins/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules
install -p -m644 plugins/mod_pubsub/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_pubsub
install -p -m644 plugins/adhoc/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/adhoc
install -p -m644 plugins/muc/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/muc
install -p -m644 plugins/mod_mam/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_mam
install -p -m644 plugins/mod_debug_stanzas/*.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/modules/mod_debug_stanzas
install -d /usr/ports/net-im/prosody/work/stage/usr/local/bin
install -p -m755 ./prosody.install /usr/ports/net-im/prosody/work/stage/usr/local/bin/prosody
install -p -m755 ./prosodyctl.install /usr/ports/net-im/prosody/work/stage/usr/local/bin/prosodyctl
install -d /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody/certs
install -p -m644 certs/* /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody/certs
install -p -m644 prosody.cfg.lua.install /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody/prosody.cfg.lua.sample
install -d /usr/ports/net-im/prosody/work/stage/usr/local/share/man/man1
install -p -m644 man/prosodyctl.man /usr/ports/net-im/prosody/work/stage/usr/local/share/man/man1/prosodyctl.1
test -f prosody.version && install -p -m644 prosody.version /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody/prosody.version
install -d -m750 /usr/ports/net-im/prosody/work/stage/var/db/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
install -p -m644 loader.lua /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
/usr/local/bin/gmake -C tools/migration install
gmake[1]: Entering directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/tools/migration'
sed "1s/ lua$/ lua54/; \
s|^CFG_SOURCEDIR=.*;$|CFG_SOURCEDIR='/usr/local/lib/prosody';|; \
s|^CFG_CONFIGDIR=.*;$|CFG_CONFIGDIR='/usr/local/etc/prosody';|; \
s|^CFG_DATADIR=.*;$|CFG_DATADIR='/var/db/prosody';|; \
s|^CFG_PLUGINDIR=.*;$|CFG_PLUGINDIR='/usr/local/lib/prosody/modules/';|;" \
< prosody-migrator.lua > prosody-migrator.install
sed "s|^local data_path = .*;$|local data_path = '/var/db/prosody';|;" \
< migrator.cfg.lua > migrator.cfg.lua.install
install -d /usr/ports/net-im/prosody/work/stage/usr/local/bin /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody /usr/ports/net-im/prosody/work/stage/usr/local/lib/prosody
install -d /usr/ports/net-im/prosody/work/stage/usr/local/share/man/man1
install -m755 ./prosody-migrator.install /usr/ports/net-im/prosody/work/stage/usr/local/bin/prosody-migrator
install -m644 migrator.cfg.lua.install /usr/ports/net-im/prosody/work/stage/usr/local/etc/prosody/migrator.cfg.lua.sample
gmake[1]: Leaving directory '/usr/ports/net-im/prosody/work/prosody-13.0.6/tools/migration'
====> Compressing man pages (compress-man)
===> Staging rc.d startup script(s)
Une fois compilé, on procède à l'installation usuelle avec make install.
On vérifie ensuite le bon fonctionnement du service:
$ prosodyctl about
Prosody 13.0.6
# Prosody directories
Data directory: /var/db/prosody
Config directory: /usr/local/etc/prosody
Source directory: /usr/local/lib/prosody
Plugin directories:
/usr/local/lib/prosody/modules/
# Operating system
FreeBSD 15.0-RELEASE-p12
# Lua environment
Lua version: Lua 5.4
Lua module search paths:
/usr/local/lib/prosody/?.lua
/usr/local/share/lua/5.4/?.lua
/usr/local/share/lua/5.4/?/init.lua
/usr/local/lib/lua/5.4/?.lua
/usr/local/lib/lua/5.4/?/init.lua
/var/db/prosody/custom_plugins/share/lua/5.4/?.lua
/var/db/prosody/custom_plugins/share/lua/5.4/?/init.lua
Lua C module search paths:
/usr/local/lib/prosody/?.so
/usr/local/lib/lua/5.4/?.so
/usr/local/lib/lua/5.4/loadall.so
/var/db/prosody/custom_plugins/lib/lua/5.4/?.so
LuaRocks: Not installed
# Network
Backend: epoll
# Lua module versions
LuaExpat: 1.5.2
LuaFileSystem: 1.8.0
LuaSec: 1.3.2
LuaSocket: 3.0.0
luaunbound: 1.1.0
# library versions
libcrypto: OpenSSL 3.5.6 7 Apr 2026
libexpat: expat_2.8.2
libunbound: 1.26.0
Restera ensuite à procéder à la configuration du service.
Configuration DNS
On utilise un nom de domaine spécifique pour Prosody. Des JID seront créés sur ce domaine et des sous domaines serviront différents intérêts:
- record xmpp utilisé pour le serveur.
- record conference utilisé pour les salons/MUC
- record upload utilisé pour les transferts de fichiers
La Zone DNS doit ressembler à ça:
le-domaine.com → "A" record vers IP du serveur
xmpp.le-domaine.com → "A" record vers IP du serveur
conference.le-domaine.com → "A" record vers IP du serveur
upload.le-domaine.com → "A" record vers IP du serveur
_xmpp-client._tcp.le-domaine.com
SRV 0 5 5222 xmpp.le-domaine.com.
_xmpp-server._tcp.le-domaine.com
SRV 0 5 5269 xmpp.le-domaine.com.
Le premier record SRV est utilisé pour les clients XMPP, le second pour la fédération entre serveurs.
Nginx pour Let's Encrypt
Mise en place d'un vhost HTTP contenant les quatre noms et permettant le challenge :
server {
listen 80;
server_name le-domaine.com xmpp.le-domaine.com
conference.le-domaine.com upload.le-domaine.com;
location ^~ /.well-known/acme-challenge/ {
root /usr/local/www/acme;
try_files $uri =404;
}
location / { return 404; }
}
Créer /usr/local/www/acme, tester avec nginx -t, puis recharger Nginx.
Certificat Let's Encrypt
certbot certonly --webroot \
-w /usr/local/www/acme \
-d le-domaine.com \
-d xmpp.le-domaine.com \
-d conference.le-domaine.com \
-d upload.le-domaine.com
Prosody recommande d'importer les certificats plutôt que de lui donner directement accès aux clés privées Certbot :
prosodyctl --root cert import /usr/local/etc/letsencrypt/liveAutomatiser les certificats
Mettre en place un cron pour renouveler les certificats en temps voulu:
17 3 * * * /usr/local/bin/certbot renew -q
Créer deux deploy hooks Certbot : l'un exécute service nginx reload, l'autre importe le certificat avec prosodyctl --root cert import .... afin de maintenir les applications à jour après que le certificat a été renouvelé.
Configurer Prosody
Conserver les modules fournis par Prosody 13 et notamment : roster, saslauth, tls, bookmarks, carbons,pep, smacks, vcard4, cloud_notify, csi_simple, mam, register.
Ensuite édition de la configuration dans /usr/local/etc/prosody/prosody.cfg.lua:
admins = { "admin@le-domaine.com"; }
authentication = "internal_hashed"
archive_expires_after = "6 months"
VirtualHost "le-domaine.com"
Component "conference.le-domaine.com" "muc"
Component "upload.le-domaine.com" "http_file_share"
http_host = "upload.le-domaine.com"
http_external_url = "https://upload.le-domaine.com/"
http_file_share_size_limit = 50 * 1024 * 1024
http_file_share_daily_quota = 200 * 1024 * 1024
http_file_share_global_quota = 5 * 1024 * 1024 * 1024
http_file_share_expires_after = "30 days"
Pour rappel: "mam" fournit l'historique/synchronisation et "muc" les salons XMPP. Le module upload implémente XEP-0363 et peut être placé derrière Nginx.
Configurer Nginx
server {
listen 443 ssl;
server_name upload.le-domaine.com;
ssl_certificate /usr/local/etc/letsencrypt/live/le-domaine.com/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/le-domaine.com/privkey.pem;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host upload.le-domaine.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}Premier démarrage
# activation prosody au start systeme
sysrc prosody_enable="YES"
# verification de la configuration
prosodyctl check config
# verification des certificats
prosodyctl check certs
# verification des DNS
prosodyctl check dns
# demarrage
service prosody startCréation d'utilisateurs locaux au domaine
Cela se fait très simplement avec l'outil de controle Prosody:
prosodyctl adduser admin@le-domaine.com
prosodyctl adduser autre@le-domaine.com
...
Le mot de passe est stocké par Prosody avec internal_hashed, indépendamment des comptes Unix. Les utilisateurs peuvent piloter leurs comptes et changer le mot de passe via leurs clients XMPP après la première connexion.
Fin.
