Nouveau concept, nouveau design, nouveau modèle.

Nous allons voir comment installer la messagerie instantannée la mieux sécurisée de tous les temps. Nous passerons par le serveur Prosody, un routeur Tor, et Gajim comme client. Ces composants seront installés au niveau du système, sur une seule machine : un poste de travail ou un laptop. La sécurité de ce concept repose sur sa simplicité. Le choix du chemin le plus court pour le transit des messages est un choix volontaire, dans le but de réduire le plus possible la latence. Comme un mode de communication de pair-à-pair (P2P). D'après mes tests, la latence fait moins d'une seconde, c'est quasiment-instantanné.

Ce petit guide permet d'installer manuellement un système de messagerie instantannée sur sa machine. Toutes les actions décrites ici sont réversibles. Pour une utilisation sur le long-terme, les données à backuper sont indiquées à la toute-fin. Les containers Docker/Podman ne sont pas à l'ordre du jour. L'architecture serait trop compliquée et difficile à mettre en place.

Design

À qui s'adresse t-il ?

Tout le monde. Pas besoin de posséder un serveur dédié. Cette méthode s'applique au "poste client" ou "poste de travail" de chacun. Nous possédons tous au moins un ordinateur fixe ou un laptop. Si vous n'avez jamais eu de compte Jabber, bienvenue dans le monde de Jabber/XMPP à travers ma méthode.

À l'heure où j'écris ces lignes, le client Poezio ne peut pas être employé avec ma méthode. Les développeurs font tout leur possible pour résoudre les problèmes au niveau de la bibliothèque "slixmpp". Peut-être que ça marchera dans 6 mois, ou dans 1 an. Je publierais un nouvel article si la situation évolue.

J'ai testé avec les clients Gajim et Profanity, mais je ne parlerais ici que de Gajim. Je n'ai pas testé avec Dino non-plus.

Messages en transit

Le transit des messages se fera via le Tor Network. Egalement appelé Dark Net. Le Tor Network est un sous-réseau dans le réseau. Il offre un certain nombre de possibilités que nous allons exploiter dans ce concept. Pour en savoir plus, je vous invite à visionner la vidéo (en anglais) "The Dark Net Isn't what you think. It's actually key to our privacy" d'Alex Winter lors de l'événement TEDxMidAtlantic :

https://youtube.com/watch?v=luvthTjC0O1

Avantages du réseau Tor

En passant par le Tor Network, ce concept s'affranchi des problématiques habituelles. Vous n'avez pas besoin d'acheter un nom de domaine (.org, .net, etc...). Puisqu'il n'y a pas de nom de domaine, il n'y a pas besoin de certificats SSL non-plus. Il n'y a pas de problème de chiffrement des connexions car tout le traffic est chiffré par défaut.

Pour les problématiques liées aux serveurs, avec ma méthode, pas besoin de configurer les règles de routage NAT, ni le parefeu de la machine.

Si vous avez un laptop, la connexion fonctionnera où que vous soyez. Même si vous êtes en déplacement, et même à travers un point d'accès WiFi publique.

Pas de serveurs distant

Le mot clé de ce concept est la légèreté. Ce concept ne réclame aucune infrastructure ni serveur dédié. Prosody est un serveur Jabber extrêmement léger et ne représente aucune charge sur la machine. Sur un poste client, il sera invisible.

Le but est de s'affranchir des serveurs distant. Pas besoin de louer une machine dans un datacenter, et pas besoin d'acheter une seconde unité centrale qu'on laissera tourner 24H/24. Pour la première fois dans l'histoire de Jabber/XMPP, la communication aura lieu en ligne directe.

Il y a un avantage caché : Vous constatez qu'il n'y a pas de serveur intermédiaire entre 2 correspondants. Les 2 correspondants communiquent de pair à pair, et sont reliés par le Tor Network. Les 2 correspondants sont reliés par les routeurs Tor installés sur leur propre machine. C'est une forme de P2P, et je pense sincèrement que le niveau de sécurité est augmenté.

Les 2 correspondants sont en "P2P", en ligne directe, sauf que le Tor Network anonymise la connexion entre-eux. C'est une fonctionnalité de base du réseau Tor.

Toujours à la recherche de légèreté, l'absence de certificats SSL simplifie au maximum les tâches d'administration système. Aucune maintenance ne sera nécessaire. Une fois installé, ce système fonctionnera pendant un bon bout de temps.

De plus, Prosody est un serveur Jabber fiable qui ne pose jamais de problème avec SELinux. C'est un détail, certes, mais ce n'est pas le cas avec d'autres serveurs Jabber. Il est le programme parfait, pour un poste client.

Client XMPP

Techniquement, vous pouvez utiliser n'importe quel client XMPP. La configuration sera un peu différente par rapport à d'habitude, car il ne se connecte pas à Internet, mais directement sur le serveur Prosody sur la même machine, en passant par le chemin le plus court. Les connexions sont établies sur l'interface localhost.

Le port d'écoute C2S (Client-to-Server) est un port qui doit être inaccessible depuis l'extérieur de la machine. La seule connexion attendue est celle de l'utilisateur de la machine. J'ai choisi un port arbitraire 15222, non-standard, et bloqué par défaut au niveau du parefeu.

Lorsque les connexions transitent par l'interface localhost, SSL/TLS est inutile. Dans le cas présent, il est désactivé. Les clients des 2 correspondants pourront activer le chiffrement de bout-en-bout (E2EE) avec OMEMO, mais je rappelle que tout le traffic est déjà chiffré par le réseau Tor. Il n'y a pas de configuration supplémentaire à ajouter au niveau de Prosody pour qu'OMEMO fonctionne correctement.

Jabber ID

Cette méthode offre des garanties au maintien et à la persistance de l'identité Jabber de l'utilisateur. Une identité Jabber, une adresse Jabber, ne peut pas être usurpée.

Le système de sécurité repose sur les noms de domaine .onion fournis par le Tor Network. Dans ce modèle, chaque correspondant possède une adresse Jabber unique grace au nom de domaine .onion. Les adresses onion sont uniques, donc si une adresse n'est plus utilisée, on ne peut pas la récupérer dans le but d'une usurpation d'identité. Elle sera perdue à tout jamais.

Chaque correspondant possède sur sa propre machine le serveur XMPP qui gère le nom de domaine .onion. Il est possible qu'un correspondant constate que le "serveur XMPP" de la personne destinataire ne soit pas joignable. C'est un scénario possible, et ce n'est pas un problème : Les messages seront stockés sur la machine de départ, et seront envoyés au moment où le serveur XMPP distant sera à nouveau joignable. Dans un mode de communication de Pair à Pair, si un pair est hors-ligne, alors la communication ne peut pas avoir lieu. C'est logique.

Le protocole XMPP a tout prévu pour gérer les problèmes d'envoi de message (et les envois en différé).

Un utilisateur peut créer plusieurs adresses Jabber, en ajoutant 2 ou 3 comptes utilisateur sur le serveur Prosody. Toutes les adresses auront le nom de domaine .onion de la machine. Mais cette fonctionnalité ne présente aucun intérêt... Une adresse onion par personne, c'est déjà pas mal.

Inconvénients

Ce design n'est pas parfait, il souffre d'un problème de compatibilité avec le reste du réseau XMPP.

Dans ce modèle minimaliste, un correspondant avec une adresse onion ne peut pas contacter une personne ayant un domaine du clearnet (comme .org, .net, .com, etc...). L'objectif initial de ce modèle est de démocratiser les adresses onion. Si chaque personne possède son adresse sur son poste de travail, alors ce modèle fonctionne. Ce n'est qu'un concept. Un design.

Sa solution sort du cadre de cet article.

Au niveau des adresses Jabber, les noms de domaine .onion ne peuvent pas être personnalisés ou choisis par l'utilisateur. Ils sont générés automatiquement par le routeur Tor, et sont composés de lettres et chiffres mélangés aléatoirement. Mais ils sont uniques.

Place à la technique

Installation et configuration du routeur Tor

C'est un Logiciel Libre, protégé par une license BSD : il ne peut pas être soumis à un brevet. Il faut commencer par l'installer :

dnf install tor

Il existe plusieurs mode pour le routeur Tor. Le plus connu est le mode "relai", il permet de relayer le traffic du réseau Tor sur sa machine. Ce mode ne nous intéresse pas, et nous allons le configurer en mode "routeur" simple. Il sert juste à raccorder notre machine au réseau Tor, sans relayer le traffic.

Mon fichier /etc/tor/torrc :

Log notice stdout
SocksPort [::1]:9050 PreferIPv6
SocksPort 127.0.0.1:9050 PreferIPv6
#SocksPort 172.17.0.1:9050 PreferIPv6 # Optionnel pour Docker
ClientPreferIPv6ORPort 1
HiddenServiceDir /var/lib/tor/hidden_service1/
HiddenServicePort 5269 [::1]:5269

Puis démarrer le processus en arrière-plan :

systemctl enable tor
systemctl start tor

(Le processus met environ 2min à démarrer, ça dépend des machines).

Récupération du nom de domaine .onion

Il faut basculer en utilisateur "root" pour pouvoir accéder à cette info. Comme expliqué précédemment, le routeur Tor va générer automatiquement un nom de domaine onion, unique. Il va l'écrire dans un fichier texte, mais si on modifie le fichier, le nom de domaine ne changera pas. Des clés cryptographiques déterminent les noms de domaines, et on ne peut pas les modifier sans les altérer.

L'ensemble des fichiers sont stockés dans le répertoire :

/var/lib/tor/hidden_service1/

L'info est stockée dans le fichier :

cat /var/lib/tor/hidden_service1/hostname

Il faut la noter, on en aura besoin pour la suite.

Installation et configuration de Prosody

Il est disponible au téléchargement dans le depot Fedora. On commence par l'installer sur la machine :

dnf install prosody

Mon fichier de config :

/etc/prosody/prosody.cfg.lua

Je l'ai mis en ligne pour le récupérer plus rapidement avec curl (il fait 300 lignes).

curl -o /etc/prosody/prosody.cfg.lua https://dl.casperlefantom.net/pub/prosody.cfg.lua.txt

Ou bien (à travers Tor) :

torsocks curl -o /etc/prosody/prosody.cfg.lua http://uhxfe4e6yc72i6fhexcpk4ph4niueexpy4ckc3wapazxqhv4isejbnyd.onion/pub/prosody.cfg.lua.txt

Passons en revue ce qu'il faut modifier et adapter à votre setup :

----------- Virtual hosts -----------
-- You need to add a VirtualHost entry for each domain you wish Prosody to serve.
-- Settings under each VirtualHost entry apply *only* to that host.

--VirtualHost "localhost"
-- Prosody requires at least one enabled VirtualHost to function. You can
-- safely remove or disable 'localhost' once you have added another.

-- Section for VirtualHost onion address

VirtualHost "p4ac3ntp3ai643k3h5f7ubggg7zmdf7ddsnfybn5rejy73vqdcplzxid.onion"
    ssl = { }

Component "rooms.p4ac3ntp3ai643k3h5f7ubggg7zmdf7ddsnfybn5rejy73vqdcplzxid.onion" "muc"
    name = "Hidden Chatrooms"
    modules_enabled = { "muc_mam" }
    restrict_room_creation = "local"
    ssl = { }

La configuration des VirtualHosts est indiquée directement dans le fichier de config principal, pour simplifier au maximum. Il faut remplacer les adresses onion par votre nom de domaine .onion. C'est tout. Le fichier de config est prêt à être utilisé.

Il existe des fichiers inutiles qui ne peuvent pas être supprimés :

  • /etc/prosody/conf.d/example.com.cfg.lua
  • /etc/prosody/conf.d/localhost.cfg.lua

Pour éviter qu'ils interfèrent avec le fichier de config principal, on peut remplacer leur contenu par une ligne de commentaire. Le commentaire indique que le fichier n'est pas utilisé :

echo "-- Fichier vide" > /etc/prosody/conf.d/example.com.cfg.lua
echo "-- Fichier vide" > /etc/prosody/conf.d/localhost.cfg.lua

Si on supprime ces fichiers avec la commande "rm", ils seront recréés plus tard, au moment de la mise à jour du RPM de Prosody. Leur contenu pose problème, si l'on ne fait pas attention à ce détail, tout le projet XMPP onion peut tomber en panne, sans que l'on comprenne pourquoi.

Outils pour gérer les modules

Les modules Prosody ont un gestionnaire de module particulier nommé "luarocks". Sans ce programme, la commande prosodyctl ne peut pas installer de module. Il faut donc l'installer :

dnf install luarocks lua-devel

Scripts Lua à installer

Le module "mod_onions" a besoin de 2 programmes Lua pour marcher. Il sont disponibles dans le depot et il faut les installer sur le système :

dnf install luajit lua-bit32

Esnuite, on peut l'installer :

prosodyctl install --server=https://modules.prosody.im/rocks/ mod_onions

Après avoir exécuté la commande prosodyctl, si vous le souhaitez, vous pouvez supprimer luarocks avec l'historique dnf, car on ne va plus l'utiliser par la suite.

Le module "mod_onions" permet de rediriger vers Tor toutes les connexions sortantes de Prosody. Lors de sa tentative de connexion à un autre serveur, il va envoyer une requête pour établir une connexion TLS. C'est écrit comme ça dans le code, et ce n'est pas configurable. Le serveur du correspondant répond ensuite qu'il ne peut pas établir de connexion TLS, donc la connexion échoue. Pour modifier le comportement de base du programme, on peut passer par un module.

Voici mon module perso à installer dans :

/var/lib/prosody/custom_plugins/share/lua/5.4/mod_s2s_never_encrypt.lua

local libev = module:get_option_boolean("use_libevent")

local function disable_tls_for_baddies_in(event)
    local session = event.origin
    module:log("debug", "disabling tls on incoming stream from %s...", tostring(session.from_host));
    if libev then session.conn.starttls = false; else session.conn.starttls = nil; end
end

local function disable_tls_for_baddies_out(event)
    local session = event.origin
    module:log("debug", "disabling tls on outgoing stream from %s...", tostring(session.to_host));
    if libev then session.conn.starttls = false; else session.conn.starttls = nil; end
end

module:hook("s2s-stream-features", disable_tls_for_baddies_in, 600)
module:hook("stanza/http://etherx.jabber.org/streams:features", disable_tls_for_baddies_out, 600)

Blocages SELinux

On saute la phase d'expérimentation, pour aller directement à la solution.

SELinux bloque 2 choses. Il empèche Prosody d'écouter sur le port 15222, car ce port fait parti d'une plage de ports non-réservés à un service spécifique. Donc SELinux l'empèche de choisir un port "aléatoire". Un service (réseau) doit utiliser un port réservé pour ce service, c'est logique.

Ce mode de fonctionnement est autorisé par le booleen "nis_enabled" :

setsebool -P nis_enabled on

Ou bien, on peut modifier le label SELinux du port 15222, au choix (vérifiez la position du booleen d'abord) :

semanage port -a -t prosody_port_t -p tcp 15222

Le second blocage empèche Prosody d'établir une connexion au proxy SOCKSv5 de Tor. C'est-à-dire que Prosody essaye de se connecter au socket TCP d'un autre service (sur la même machine). Ce n'est pas le mode de fonctionnement habituel d'un service réseau.

Pour résoudre le problème, on va créer un fichier texte (prosody-connect-tor-port.txt) qui contient une seule ligne avec le contenu suivant :

type=AVC msg=audit(1673295193.979:4392): avc:  denied  { name_connect } for  pid=935298 comm="prosody" dest=9050 scontext=system_u:system_r:prosody_t:s0 tcontext=system_u:object_r:tor_port_t:s0 tclass=tcp_socket permissive=0

Puis, on se sert de audit2allow pour générer un module de règles SELinux :

cat prosody-connect-tor-port.txt|audit2allow -M prosody-connect-tor-port

Ensuite, on peut installer le module :

semodule -i prosody-connect-tor-port.pp

Suppression des certificats inutiles

Au moment de l'installation de prosody, un certificat x509 est généré automatiquement. Il contient des informations génériques, il est valide pendant 1 an, et il est auto-signé. Voici un exemple de ce qu'il contient :

Issuer: C = --, ST = SomeState, L = SomeCity, O = SomeOrganization, OU = SomeOrganizationalUnit, CN = vulcain, emailAddress = root@vulcain
Subject: C = --, ST = SomeState, L = SomeCity, O = SomeOrganization, OU = SomeOrganizationalUnit, CN = vulcain, emailAddress = root@vulcain
Validity:
    Not Before: Jun 17 07:02:32 2023 GMT
    Not After : Jun 16 07:02:32 2024 GMT

Il contient n'importe quoi, c'est un fait. Il n'est pas utilisable, et il va générer des problèmes quand il aura expiré dans un an. Donc, je recommande la suppression :

echo "" > /etc/pki/prosody/localhost.crt
echo "" > /etc/pki/prosody/localhost.key

On en a pas besoin, techniquement.

Démarrage de prosody

C'est le moment. Le processus est lancé en arrière-plan.

systemctl enable prosody
systemctl start prosody

Vous constatez qu'il consomme quasiment-pas de resource sur la machine.

Création d'un nom d'utilisateur

Pour créer un compte utilisateur, on peut passer soit par Gajim, soit par la commande prosodyctl. Je ne vais pas détailler la procédure dans Gajim, libre à vous de choisir ce qui vous convient le mieux. Pour le nom, je recommande quelque-chose de court, car l'adresse finale est déjà très longue.

Voici les commandes en passant par prosodyctl :

prosodyctl adduser user@adresse.onion
prosodyctl passwd user@adresse.onion

(Personne peut se connecter au port d'écoute client, donc personne peut tester la résistance/robustesse du mot de passe).

Installation et configuration de Gajim

Du coté de Gajim, la config est relativement simple. C'est encore un Logiciel Libre, protégé par une license GPLv3 : personne peut déposer un brevet sur ce logiciel. Il est présent dans le dépot Fedora et il faut commencer par l'installer :

dnf install gajim

Ensuite, c'est parti pour le parcours fléché. Suivez les fleches !

Aller dans "Comptes" > Modifier le compte > Ajouter un compte

Capture d'écran Capture d'écran Capture d'écran Capture d'écran Capture d'écran Capture d'écran Capture d'écran

L'installation et la configuration d'OMEMO n'est pas traitée dans cet article.

En résumé

Au final, peu-importe quel client vous utilisez, voici les informations clés à renseigner :

  • Nom du compte (nom d'utilisateur@nom d'hôte, également appelé JID)
  • Serveur : localhost
  • Port : 15222
  • Utiliser une connexion non-chiffrée (désactiver TLS)

Données à backuper

Ce système est fiable sur le long-terme seulement si il est backupé. Je vous propose ici de faire le point, afin de garantir la longévité de votre installation.

Pour générer une copie de sauvegarde du système (en root) :

tar -Jcf xmpp-onion-system.tar.xz /etc/tor/torrc /var/lib/tor/hidden_service1/ /etc/prosody/prosody.cfg.lua /etc/prosody/conf.d/example.com.cfg.lua /etc/prosody/conf.d/localhost.cfg.lua /var/lib/prosody/ /etc/pki/prosody/localhost.crt /etc/pki/prosody/localhost.key

Données utilisateur (pas root) :

$ tar -Jcf xmpp-onion-user.tar.xz .config/gajim/ .local/share/gajim/

L'avantage est que, si vous décidez de changer de client, nul-besoin de tout re-backuper.

Pour restaurer depuis la sauvegarde (en root) :

pushd /
tar -Jxf /home/user/xmpp-onion-system.tar.xz
popd

Et pour restaurer les données utilisateur :

$ tar -Jxf xmpp-onion-user.tar.xz

Simple et efficace. Mais il faut aussi créer de la redondance en backupant la $HOME. La redondance, on en a besoin.

Il est possible de restaurer le backup sur un LiveUSB Fedora après avoir booté dessus. Ça fonctionnera aussi.

Et ça marche.

Nous venons de voir la méthode d'installation et de mise en place d'une messagerie décentralisée, acentrée, à travers un réseau d'anonymisation. Aide et support dans le salon de discussion fedora@chat.jabberfr.org (XMPP) où je suis présent en permanance.