Il est important de savoir que laisser communiquer en clair son IoT de sa domotique n’est pas DU TOUT conseillé. C’est important de sécuriser plusieurs choses après avoir compris les bases de MQTT :

  • L’identification du serveur et la sécurisation du flux
  • L’identification du client
  • L’authentification du client

Vous devez faire le bon compromis entre sécurité et flexibilité. Il ne faut pas forcément pousser le bouton à fond pour tous les cas de figures.

Génération des clés et certificats

Pour MQTTS, 2 options s’offre à vous comme pour un serveur HTTPS :

  • générer vos certificats auto-signé
  • via une autorité de certification

Dans mon cas ce n’est que du local, ce sera donc de l’auto-signé.

Je génère toujours les clés et certificats sur ma machine perso et ensuite je copie les certificats/clés sur le serveur et les clients, afin de les archiver. C’est donc à faire dans un dossier à garder sous Linux ou en WSL sous Windows.

Veillez bien à remplacer les DNS suivants par votre domaine externe pointant sur votre serveur ainsi que votre DNS interne ou IP interne pour joindre votre serveur MQTT (dans mon cas installé sur mon serveur Jeedom) : DNS:jeedom.YOURDOMAIN.TLD,DNS:jeedom.home

mkdir ca broker clients

#CA
openssl genrsa -out ca/ca.key 2048
openssl req -new -x509 -days 9999 -subj "/C=BE/CN=MQTT-CA/O=home" -key ca/ca.key -out ca/ca.crt

#broker
openssl genrsa -out broker/mosquitto.key 2048
openssl req -new -subj "/C=BE/O=home/CN=MQTT-mosquitto" -key broker/mosquitto.key -out broker/mosquitto.csr
openssl x509 -req -extfile <(printf "subjectAltName = DNS:jeedom.YOURDOMAIN.TLD,DNS:jeedom.home,DNS:localhost,IP:127.0.0.1,IP:::1") -in broker/mosquitto.csr
 -CA ca/ca.crt -CAkey ca/ca.key -CAcreateserial -out broker/mosquitto.crt -days 9999 -sha256
 
#client (facultatif) si on souhaite une authentification par certificat du client au lieu de password
openssl genrsa -out clients/local-tasmotas.key 2048
openssl req -new -subj "/C=BE/O=home/CN=MQTT-client-tasmotas" -key clients/local-tasmotas.key -out clients/local-tasmotas.csr
openssl x509 -req -in clients/local-tasmotas.csr -CA ca/ca.crt -CAkey ca/ca.key -CAcreateserial -out clients/local-tasmotas.crt -days 9999 -sha256

MQTTS côté broker Mosquitto

Les certificats et clés privées doivent être archivés, ils ne le sont pas dans le backup Jeedom.

La configuration de base du fichier Debian est : /etc/mosquitto/mosquitto.conf

# 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

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

C’est conseillé d’utiliser un fichier dans conf.d : dans mon cas sous Jeedom avec l’installation du plugin jMQTT, le fichier suivant est créé et sera utilisé : /etc/mosquitto/conf.d/jMQTT.conf

Copie des fichiers nécessaires du broker sur le serveur Jeedom :

scp ca/ca.crt broker/mosquitto.crt broker/mosquitto.key jeedom:
ssh jeedom
sudo mv ca.crt mosquitto.crt mosquitto.key /etc/mosquitto/certs/
ls -l /etc/mosquitto/certs

Editer via l’interface web la configuration du fichier jMQTT.conf ou via vim /etc/mosquitto/conf.d/jMQTT.conf

  • on laisse les connexions en clair du port 1883 provenant de localhost uniquement (127.0.0.1), plus d’accès en clair depuis l’extérieur (sert pour jeedom se connecter au broker Mosquitto)
  • on active le port TLS 8883 sur toutes les interfaces
# jMQTT Mosquitto configuration file
listener 1883 127.0.0.1
allow_anonymous true

# jMQTTS
listener 8883 0.0.0.0
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/mosquitto.crt
keyfile /etc/mosquitto/certs/mosquitto.key

# Only allow clients with a valid certificat (false to only trus the broker and not the clients)
require_certificate true


Rédémarrez le service et vérifier que le port 8883 est ouvert pour tous et 1883 n’est plus accessible que par 127.0.0.1 :

sudo systemctl restart mosquitto.service
sudo ss -tlpn | egrep '(1883|8883)'
LISTEN    0         100                0.0.0.0:8883             0.0.0.0:*        users:(("mosquitto",pid=14185,fd=6))
LISTEN    0         100              127.0.0.1:1883             0.0.0.0:*        users:(("mosquitto",pid=14185,fd=5))

A ce moment là, le trafic entre nos clients et notre serveur est sécurisé. Mais n’importe quel client peut se connecter à notre serveur sans mot de passe!

Basé sur la documentation jMQTT officielle, d’autres informations et erreurs courantes sont disponibles sur ce blog.

Authentification

Mes clients étant des ESP32 qui disposent de Wifi ou mon pc avec MQTT explorer pour le debug, tout en local, une authentification par mot de passe est suffisante. Je distingue les clients IoT avec un seul mot de passe et mes 2 pc avec chacun un mot de passe différent.

Pour un serveur MQTTS publique, l’authentification des clients par certificat est recommandé

  1. Créer les fichiers de mot de passe : mosquitto_passwd -c <password file> <username>
    sudo mosquitto_passwd -c /etc/mosquitto/distant.passwd tasmota
  2. Configurer le broker avec la ligne : password_file <path to the configuration file>
  3. Ajout d’un second utilisateur sudo mosquitto_passwd /etc/mosquitto/distant.passwd hp
  4. Redémarrer : sudo systemctl restart mosquitto.service

Le fichier /etc/mosquitto/conf.d/jMQTT.conf

per_listener_settings true

# jMQTT Mosquitto configuration file
listener 1883 127.0.0.1
allow_anonymous true

# jMQTTS
listener 8883 0.0.0.0
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/mosquitto.crt
keyfile /etc/mosquitto/certs/mosquitto.key
allow_anonymous false
persistence false
require_certificate false
password_file /etc/mosquitto/distant.passwd

Si vous préférez utiliser un mot de passe pour Jeedom en local, selon si le plugin vous l’impose, vous pouvez le faire :

per_listener_settings true

# jMQTT Mosquitto configuration file
listener 1883 127.0.0.1
allow_anonymous false
persistence false
password_file /etc/mosquitto/local.passwd

# jMQTTS
listener 8883 0.0.0.0
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/mosquitto.crt
keyfile /etc/mosquitto/certs/mosquitto.key
allow_anonymous false
persistence false
require_certificate false
password_file /etc/mosquitto/distant.passwd

source

Summary
MQTTS sécuriser Mosquitto MQTT
Article Name
MQTTS sécuriser Mosquitto MQTT
Description
MQTTS permet de sécuriser votre domotique, vos périphériques IoT pour communiquer avec le broker MQTT Mosquitto
Author