jMQTT et paramètres de sécurité broker

Bonjour,
Autant depuis jMQTT (tout frais installé) et sans sécurité sur le port 1883, j’arrive à me connecter sans problème à mon broker déporté mais autant là, je bloque sur la configuration sécurité de l’équipement « broker » dans le plugin jMQTT via le port 8883 en mqtts.

Je ne vois pas ce qu’il faut mettre/renseigner exactement dans les champs Autorité Personalisée, Certificat Client et Clé Privée Client.
Je m’attendais à avoir la possibilité d’aller chercher/désigner les fichiers .crt et .key correspondants mais que nenni !

J’ai aussi essayé de renseigner chaque champ avec le contenu respectif de chacun des fichiers du certificat mais cela ne semble pas marcher, du moins pas de connexion sur le serveur MQTT alors qu’avec les même fichiers, j’établi dans MQTT Explorer une connexion au serveur MQTT certes (au passage) seulement si je n’active pas la validation du certificat. ??? à voir ensuite … car il n’y a pas cette nuance dans jMQTT @Domochip p’tre une évolution future ?

J’ai épluché la doc mais rien trouvé de probant … sur ce point.

Alors aux « barbus » :rofl: de jMQTT, sauriez-vous SVP m’expliquer ce que je dois mettre effectivement dans ces champs ?

Merci de vos réponses et de m’aider à sécuriser ma domotique.
Cordialement
oracle7 :smirk:

2 « J'aime »

Hello,

Est-ce que tu peux nous partager ta configuration jMQTT actuelle et ce que tu as mis dans les champs certificats ? (Capture d’écran)

@Bad
Quelle rapidité ! :rofl:
Pour répondre à ta demande, ci-dessous des copies d’écran :

N’hésites pas si tu veux de plus amples infos

Précision si besoin en est, mon serveur Mosquitto MQTT est sur un RPI3B déporté alors que mon Jeedom est sur un RPI4B avec le plugin jMQTT et Z2M installé en « dur ».

Et bien ça m’a l’air plutôt pas mal du tout !

Le statut du Broker est bien Orange (POK Le Démon jMQTT n’arrive pas à se connecter à ce Broker) ?
Tu confirmes que les clés publiques sont au format PEM ?
Dans « Autorité Personnalisée » tu as bien mis la clé publique de ton Broker ?
Que donnent les logs du Démon (log jMQTTd) ? Des erreurs ?

Si tu veux essayer avec le même mode (pas de vérification du certificat du Broker) tu peux basculer le champ « Vérifier le certificat » en « Désactivé - Non Recommandé ».

OUI la preuve :
image

Sauf erreur de ma part OUI elles ont été créé au format .crt et .key avec openssl selon ces deux excellents sites en exemple :
https://openest.io/linux-embarque/communication-linux/chiffrement-communication-mqtt-tls-ssl-mosquitto-et-paho/
https://www.schaerens.ch/raspi-setting-up-mosquitto-mqtt-broker-on-raspberry-pi-docker/

Qu’entends-tu par clé publique du broker ??? J’ai mis le contenu du certificat CA .crt de l’autorité de certification personnalisée que j’ai créée comme indiqué sur les deux sites sus-cités.

image
image

image

En espérant que cela te cause pour ce log …

C’est pareil le client MQTT est au statut POK
image

Juste une remarque à la vue du dernier log (jMQTTd) :
la ligne
image
semble prendre en compte le paramètre « cert_reqs=reqs » qui selon moi correspondrait à un fichier de certificat .csr , sauf qu’à aucun moment ce type de fichier n’est à renseigner dans le plugin. De plus ce type de fichier .csr est normalement utilisé (sauf erreur de ma part) lors la requête de certification lors de la génération de la clé .key. Donc je dirai hors sujet ici et du coup, quel intérêt/utilité de ce paramètre ici dans l’instruction « self.mqttclient.tls_set (… » ? Ton avis ?

J’en suis arrivé à auditer la même portion de code :wink:
Le paramètre cert_reqs de tls_set() ne correspond pas à un fichier CSR, mais à la façon dont paho.mqtt.python (ou plutôt Lib SSL) va traiter les certificats :

        cert_reqs allows the certificate requirements that the client imposes
        on the broker to be changed. By default this is ssl.CERT_REQUIRED,
        which means that the broker must provide a certificate. See the ssl
        pydoc for more information on this parameter.

Ce paramètre sert à vérifier si le Common Name (CN) du certificat correspond au hostname.
La variable reqs est définie un peu plus haut à ssl.CERT_NONE ou ssl.CERT_REQUIRED.

(Par contre, c’est redondant avec tls_insecure_set(), je me suis mis de check ça dans ma TODO)

L’erreur se produit lors du changement des certificats dans paho.mqtt.python :

J’aurais donc plutôt tendance à dire qu’il y a un souci avec les certificats ou leur transcription dans jMQTT. Peux-tu stp vérifier que :

  • tu as bien -----BEGIN CERTIFICATE----- au début et -----END CERTIFICATE----- à la fin de « Autorité Personnalisée » et « Certificat Client » ?
  • tu as bien -----BEGIN RSA PRIVATE KEY----- au début et -----END RSA PRIVATE KEY----- à la fin de « Clé Privée Client » ?
  • ces lignes ne sont pas présentes qu’une seule fois en début et fin bloc ?

Le log d’erreur est exactement le même ?

Oui il faut le contenu du fichier CA configuré dans le Broker (paramètre cafile dans Mosquitto).

Tu as suivi quel tuto en particulier ? Ils sont effectivement excellents et se recoupent sur pas mal de points, mais je veux bien les commandes que tu as utilisé pour générer ta PKI (morceau choisi de bash_history en privé m’ira bien :wink: )

Mais, si ça marche dans MQTT Explorer avec ces params, ça devrait marcher dans jMQTT :
image

OUI j’ai bien respectivement ces lignes et elles ne sont présentent qu’une et une seule fois en début et fin de fichier. Rien d’anormal à mon sens, j’ai toujours observé les fichier de certificats constitués de cette façon.

OUI exactement le même

En fait les deux pour en faire une synthèse, du fait des quelques écarts qu’ils présentent (les deux ont aussi des erreurs donc attention aux C/C trop rapides !!!).

Je regarde comment te transmettre en MP ma procédure.

1 « J'aime »

Oui, je crois me souvenir que c’était un peu galère de trouver des tuto au poil pour MQTTS.
Il me semble que j’avais utilisé celui-ci pour mon Broker de dev :

Et un morceau de celui-ci pour le SAN du Broker (signer aussi pour l’IP pas que le nom) :

Si tu arrives bien à te connecter à ton Broker avec MQTT Explorer et les 3 certificats, c’est qu’il y a un problème sur jMQTT. Tu as absolument besoin du MQTTS rapidement ou tu peux attendre quelques jours ? (J’ai une grosse semaine de taff avec des déplacements devant moi…)

1 « J'aime »

Merci beaucoup pour ces TUTOs je vais les lire attentivement, sûrement apprendre encore beaucoup de choses … :crazy_face:

Pas de soucis, il n’y a pas « le feu au lac » !
Je suis en pleine découverte de l’environnement MQTT qui est complétement nouveau pour moi. Donc énormément d’informations sont à engranger dans ma petite tête. J’ai de quoi m’occuper en plus d’une part avec le PC de Madame qu’il faille en priorité réinstaller :joy: et je regarde pour monter une instance Home Assistant pour doubler ma domotique Jeedom. Là aussi avec HA, c’est une autre philosophie, mais bon …
Sinon, ne supportant plus l’instabilité du plugin Zigbee je suis en train d’essayer de tout passer sous MQTT afin d’avoir une homogénéité globale et plus d’ouverture.
Sur mon installation sous Jeedom je souhaite donc migrer tout mon monde (environ 80 capteurs Zigbee et essentiellement de l’Aqara à part les ampoules, le Z-Wave sera la seconde étape de migration !). Mais c’est pas simple de trouver des docs pour les nuls dans le domaine. Le problème n’est pas tant de mettre les mains dans le camboui mais plutot de savoir quoi faire et comment le faire tout en assimilant logiques et mécanismes. Les vidéos foisonnent pourtant bien sur youtube mais souvent « lights » à mon gout et en plus, elles datent un peu ou les environnements sont trop éloignés du mien, donc pas simple de trouver chaussure à son pied. Il faut faire tout un tas de synthèses pour arriver à quelque chose qui tienne un peu la route. Enorme boulot ! heureusement j’ai du temps de libre …
Dommage qu’il n’y ait pas non plus de bouquins « pratiques » sur le sujet, oui je sais je rêve éveillé :rofl:

1 « J'aime »

Bonjour

je cherche aussi à sécuriser mes connexions entre JMQTT et mon serveur MQTT, et je suis preneur d’un mode opératoire pour faire cela

d’avance merci

1 « J'aime »

@Bad
Bonjour,
Je reviens vers toi car autant en version NON sécurisée mon client jMQTT se connecte bien à mon broker Mosquitto (déporté sur un RPI3B) :
image

autant en version sécurisée le client jMQTT n’arrive pas à se connecter au même broker :

le plus fort dans tout cela c’est qu’en version sécurisée je me connecte au broker sans problèmes avec MQTT Explorer :

Je te mets log mais il n’apporte pas grand chose de plus :
image

Et le log jMQTTd :

[2022-12-15 17:59:04,272]ERROR Client464       MainThread           start() : Fatal TLS Certificate import Exception, this connection will most likely fail!
Traceback (most recent call last):
File "/var/www/html/plugins/jMQTT/resources/jmqttd/jMqttClient.py", line 218, in start
self.mqttclient.tls_set(ca_certs=certs, cert_reqs=reqs, certfile=cert, keyfile=key)
File "/var/www/html/plugins/jMQTT/resources/jmqttd/venv/lib/python3.7/site-packages/paho/mqtt/client.py", line 796, in tls_set
context.load_cert_chain(certfile, keyfile, keyfile_password)
ssl.SSLError: [SSL] PEM lib (_ssl.c:3845)
[2022-12-15 17:59:04,276]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 17:59:09,282]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 17:59:19,287]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 17:59:34,291]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 17:59:49,296]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 18:00:04,303]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!
[2022-12-15 18:00:05,309]ERROR Client464       MainThread           start() : Fatal TLS Certificate import Exception, this connection will most likely fail!
Traceback (most recent call last):
File "/var/www/html/plugins/jMQTT/resources/jmqttd/jMqttClient.py", line 218, in start
self.mqttclient.tls_set(ca_certs=certs, cert_reqs=reqs, certfile=cert, keyfile=key)
File "/var/www/html/plugins/jMQTT/resources/jmqttd/venv/lib/python3.7/site-packages/paho/mqtt/client.py", line 796, in tls_set
context.load_cert_chain(certfile, keyfile, keyfile_password)
ssl.SSLError: [SSL] PEM lib (_ssl.c:3845)
[2022-12-15 18:00:05,315]ERROR Client464       Brk464Th     on_disconnect() : Unexpected disconnection from broker!

Je précise aussi qu’avec le même certificat CA et un certificat et key privée client générés pour HomeAssistant de la même façon/méthode que ceux pour le présent client jMQTT/Jeedom, la connexion sécurisée de HA avec le broker est bien efficiente. Donc j’en déduit que le problème est du coté jMQTT/Jeedom.

Du coup, impossible pour moi d’aller plus loin dans ma migration vers MQTT/Zigbee2mqtt de mon plugin Zigbee officiel :cry:, aurais-tu une solution STP ?

SInon au passage, il me semble qu’il serait largement plus simple pour l’utilisateur, d’avoir à désigner les fichiers des différents certificats CA et client et clé privée client plutôt que de les ouvrir respectivement pour en copier/coller le contenu dans la configuration du broker dans le plugin jMQTT. Moins de risque d’erreurs … Evolution à faire ??? Mais ce n’est que mon humble avis …

Cordialement
oracle7 :wink:

Bonjour,

Est-ce que la connexion fonctionne en mqtts sans authentification avec un certificat client ?

@tomdom
Bonjour,
Désolé mais NON pas de connexion :

J’ai aussi supprimé le plugin jMQTT puis réinstallé mais toujours pareil.

Autres constatations :
1 - Avec MQTT explorer la connexion sécurisée (avec les mêmes certificats) ne s’établit QUE si je passe en host le nom DNS du serveur Mosquitto (RPI-OUTILS) tandis qu’avec son @IP 192.168.2.52 pas de connexion possible.

2 - Pour jMQTT si je passe en host le nom DNS j’obtiens cette erreur :

[2022-12-19 13:18:03,232]ERROR Client466       MainThread           start() : Could not start MQTT client: [Errno -2] Name or service not known

Bizarre alors qu’au point 1 cela passe ???
Cela dit cela ne passe pas non plus avec l’@IP sur serveur MQTT…

3 - Par ailleurs, si je ne précise pas de certificat client , j’obtiens cette erreur :

[2022-12-19 13:30:36,947]ERROR Client466       MainThread           start() : Could not start MQTT client: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '192.168.2.52'. (_ssl.c:1056)

Mais dans ce cas, c’est peut-être normal, je ne saurais dire …

Merci de BV m’aider à trouver une solution à ce problème de connexion sécurisée.
Cordialement
oracle7 :wink:

1 « J'aime »

Bonjour,

Pour le point 1 et 3, c’est normal. Si tu as fait ton certificat avec un CN pour host.domain.tld, il n’est pas valide pour son ip.

Concernant le point 2, est-ce que la machine hébergeant Jeedom arrive à résoudre le nom de ton serveur Mosquitto ?

@tomdom
Bonjour,
Merci pour ta réponse rapide.
Pour ta question, Oui je ping sans problème depuis la machine Jeedom, la machine supportant le serveur MQTT Mosquitto.

Sinon, avec tous mes tests dans tous les sens j’ai à un moment omis de remettre le port sécurisé 8883 et suis resté sur le port 1883 avec du mqtts. Eh bien aussi étonnant que cela paraisse, ma connexion s’est établie instantanément. Etonnant non ???

Je précise que j’ai bien « Sauvegarder » après chaque changement de paramètre. Dans le doute j’ai refais la bascule de ports 1883 vs 8883 et sauvegardé ensuite.
Donc au final je constate que la connexion sécurisée mqtts @IP s’établie bien sur le port 1883 et pas sur le le port 8883 comme elle devrait normalement le faire.

Bug jMQTT ??? à vérifier …

Tu ping en utilisant le nom et pas l’ip ? Concernant le port, ton serveur est configuré sur quel port (ss -tnlp pour voir quel process écoute sur quel port) ?

Perso, j’utilise aussi un serveur mosquitto en mqtts et je n’ai aucun souci avec le plugin.

Bonjour,

1 - coté RPI Jeedom j’ai ceci :

pi@RPI-JDOM:/etc $ ss -tnlp
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port
LISTEN    0         128                0.0.0.0:22               0.0.0.0:*
LISTEN    0         20               127.0.0.1:25               0.0.0.0:*
LISTEN    0         100                0.0.0.0:1883             0.0.0.0:*
LISTEN    0         5                127.0.0.1:55008            0.0.0.0:*
LISTEN    0         128                0.0.0.0:9123             0.0.0.0:*
LISTEN    0         128              127.0.0.1:33863            0.0.0.0:*
LISTEN    0         80               127.0.0.1:3306             0.0.0.0:*
LISTEN    0         511                0.0.0.0:8080             0.0.0.0:*       users:(("node",pid=25588,fd=22))
LISTEN    0         5                127.0.0.1:34513            0.0.0.0:*
LISTEN    0         128              127.0.0.1:8083             0.0.0.0:*
LISTEN    0         100                0.0.0.0:8883             0.0.0.0:*
LISTEN    0         128                   [::]:22                  [::]:*
LISTEN    0         20                   [::1]:25                  [::]:*
LISTEN    0         100                   [::]:1883                [::]:*
LISTEN    0         128                   [::]:9123                [::]:*
LISTEN    0         511                      *:80                     *:*
LISTEN    0         100                   [::]:8883                [::]:*
pi@RPI-JDOM:/etc $ ping RPI-OUTILS
ping: RPI-OUTILS: Nom ou service inconnu
pi@RPI-JDOM:/etc $ ping 192.168.2.52
PING 192.168.2.52 (192.168.2.52) 56(84) bytes of data.
64 bytes from 192.168.2.52: icmp_seq=1 ttl=64 time=0.743 ms
64 bytes from 192.168.2.52: icmp_seq=2 ttl=64 time=0.689 ms
64 bytes from 192.168.2.52: icmp_seq=3 ttl=64 time=0.734 ms
64 bytes from 192.168.2.52: icmp_seq=4 ttl=64 time=0.726 ms
64 bytes from 192.168.2.52: icmp_seq=5 ttl=64 time=0.775 ms

Comment faire alors pour résoudre le hostname du serveur MQTT ?

2 - coté Serveur MQTT Mosquitto, il est bien configuré sur les ports 1883 et 8883
Extrait « mosquitto.conf »

#
# Config file for mosquitto
#
# See mosquitto.conf(5) for more information.
#
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
#
# =================================================================
# General configuration
# =================================================================

# =================================================================
# Listeners
# =================================================================
listener 1883
protocol mqtt

listener 8883
protocol mqtt

# =================================================================
# Certificate based SSL/TLS support
# =================================================================
certfile /mosquitto/certs/mqtts_server.crt
keyfile /mosquitto/certs/mqtts_server.key

require_certificate true

cafile /mosquitto/certs/maeva56_ca.crt
# capath /mosquitto/certs/

use_identity_as_username true
# use_subject_as_username true

root@RPI-OUTILS:~# ss -tnlp
State   Recv-Q  Send-Q    Local Address:Port     Peer Address:Port  Process
LISTEN  0       4096            0.0.0.0:9443          0.0.0.0:*      users:(("docker-proxy",pid=7296,fd=4))
LISTEN  0       4096            0.0.0.0:9000          0.0.0.0:*      users:(("docker-proxy",pid=7397,fd=4))
LISTEN  0       4096            0.0.0.0:2222          0.0.0.0:*      users:(("docker-proxy",pid=7263,fd=4))
LISTEN  0       4096            0.0.0.0:8883          0.0.0.0:*      users:(("docker-proxy",pid=411996,fd=4))
LISTEN  0       128             0.0.0.0:22            0.0.0.0:*      users:(("sshd",pid=488,fd=3))
LISTEN  0       4096            0.0.0.0:1880          0.0.0.0:*      users:(("docker-proxy",pid=10363,fd=4))
LISTEN  0       4096            0.0.0.0:1883          0.0.0.0:*      users:(("docker-proxy",pid=412024,fd=4))
LISTEN  0       4096               [::]:9443             [::]:*      users:(("docker-proxy",pid=7323,fd=4))
LISTEN  0       4096               [::]:9000             [::]:*      users:(("docker-proxy",pid=7413,fd=4))
LISTEN  0       4096               [::]:2222             [::]:*      users:(("docker-proxy",pid=7307,fd=4))
LISTEN  0       4096               [::]:8883             [::]:*      users:(("docker-proxy",pid=412006,fd=4))
LISTEN  0       128                [::]:22               [::]:*      users:(("sshd",pid=488,fd=4))
LISTEN  0       4096               [::]:1880             [::]:*      users:(("docker-proxy",pid=10370,fd=4))
LISTEN  0       4096               [::]:1883             [::]:*      users:(("docker-proxy",pid=412031,fd=4))

Pour le point 1, si RPI-OUTILS ne peut pas être résolu par la machine Jeedom, le plugin ne peut pas le résoudre non plus. Soit tu l’ajoutes dans ton dns local si tu en a 1, autrement dans le fichier /etc/hosts de ta machine Jeedom.

Pour le point 2, je vois que c’est du docker : les ports sont bien mappés ? Avec MQTT Explorer, tu te connectes bien au port 8883 ?

OK, j’ai ajouté la ligne 192.168.2.52 RPI-OUTILS au fichier /etc/hosts de la machine Jeedom.
Merci je n’avais pas pensé à cette solution tout bête …

OUI les ports sont bien mappés dans docker (extrait docker-compose) :

version: "3"

services:

    mqtt:
        image: arm64v8/eclipse-mosquitto:1.6.15-openssl
        container_name: mosquitto
        restart: unless-stopped
        mac_address: d2:ca:ab:cd:20:02
        networks:
            domotique:
                ipv4_address: 172.20.0.2
        ports:
          - 1883:1883
          - 8883:8883

Ma connexion MQTT Explorer :

C’est bon maintenant avec le hostname plutot que l’@IP du server MQTT :
image

Mais toujours impossible sur le port sécurisé 8883 !!!

Ok. Donc sans certificat client (Certificat client non coché), ça doit fonctionner avec jmqtt sur le port 8883 en utilisant le nom RPI-OUTILS