Un certificat auto-signé pour MQTT permet de chiffrer un broker de laboratoire ou hors ligne sans autorité de certification publique. Fait naïvement, il échoue à la vérification sur chaque client ou incite à désactiver complètement la vérification. Ce tutoriel présente la bonne méthode, une petite AC privée créée avec OpenSSL, puis configure Mosquitto sur le port 8883, connecte des clients Python et en ligne de commande, et explique quand un certificat reconnu publiquement vous évite ces tracas.
Certificat auto-signé ou AC privée
L'expression « certificat auto-signé » désigne deux configurations différentes :
- Un unique certificat serveur auto-signé : le certificat du broker se signe lui-même. Les clients doivent faire confiance à ce certificat précis. Quand il expire ou change, chaque client doit être mis à jour.
- Une AC privée : vous créez votre propre certificat d'AC racine (auto-signé) et l'utilisez pour signer le certificat du broker. Les clients font confiance à l'AC, vous pouvez donc réémettre librement le certificat du broker tant que l'AC reste la même.
L'approche par AC privée est presque toujours celle qu'il vous faut. Elle coûte deux commandes OpenSSL de plus et vous évite de redistribuer la confiance à chaque changement du certificat serveur.
Quand un certificat auto-signé a du sens pour MQTT
| Scénario | Auto-signé / AC privée | Certificat reconnu publiquement |
|---|---|---|
| Tests sur un portable ou en laboratoire | Bien adapté | Possible mais inutile |
| Réseau d'usine isolé (air gap), sans DNS public | Souvent la seule option | Impossible sans DNS public |
Broker interne joint par IP ou par un nom .local |
Faisable | Les AC publiques ne peuvent pas émettre pour ces noms |
| Broker exposé à Internet pour des appareils et des applications | À éviter | Fortement recommandé |
| Tableaux de bord dans le navigateur via WSS | Pénible (avertissements du navigateur) | Fonctionne d'emblée |
| Clients tiers que vous ne maîtrisez pas | Pénible (ils doivent installer votre AC) | Fonctionne d'emblée |
Étape 1 : créer l'AC privée
Créez un répertoire de travail ainsi qu'une clé et un certificat d'AC. Protégez ca.key : quiconque la détient peut usurper votre broker.
mkdir -p ~/mqtt-ca && cd ~/mqtt-ca
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
-subj "/O=Example Lab/CN=Example Lab MQTT CA" -out ca.crt
Étape 2 : créer le certificat du broker avec un SAN
Les clients TLS modernes ignorent le common name du certificat pour la vérification du nom d'hôte et ne regardent que le Subject Alternative Name (SAN). Omettre le SAN est la raison la plus fréquente pour laquelle une configuration MQTT auto-signée échoue à la vérification. Incluez chaque nom et chaque adresse IP qu'utiliseront les clients.
openssl genrsa -out broker.key 2048
openssl req -new -key broker.key \
-subj "/O=Example Lab/CN=mqtt.lab.local" -out broker.csr
cat > broker.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:mqtt.lab.local, DNS:localhost, IP:192.168.1.50
EOF
openssl x509 -req -in broker.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 397 -sha256 -extfile broker.ext -out broker.crt
Vérifiez le résultat avant de l'utiliser :
openssl x509 -in broker.crt -noout -subject -issuer -dates -ext subjectAltName
openssl verify -CAfile ca.crt broker.crt
La seconde commande doit afficher broker.crt: OK. Remplacez les noms et l'adresse IP par les vôtres.
Étape 3 : configurer Mosquitto pour TLS
Copiez les fichiers sur le broker et créez une configuration de listener :
sudo mkdir -p /etc/mosquitto/certs
sudo cp ca.crt broker.crt broker.key /etc/mosquitto/certs/
sudo chown mosquitto: /etc/mosquitto/certs/broker.key
sudo chmod 600 /etc/mosquitto/certs/broker.key
# /etc/mosquitto/conf.d/tls.conf
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key
# Exiger aussi des identifiants MQTT
allow_anonymous false
password_file /etc/mosquitto/passwd
Créez un utilisateur avec sudo mosquitto_passwd -c /etc/mosquitto/passwd labuser, puis redémarrez avec sudo systemctl restart mosquitto et consultez journalctl -u mosquitto pour repérer des erreurs comme des fichiers de clé illisibles.
Étape 4 : connecter les clients
Chaque client a besoin de ca.crt, jamais de la clé de l'AC. Avec les outils mosquitto :
mosquitto_sub -h mqtt.lab.local -p 8883 --cafile ca.crt \
-u labuser -P 'your-password' -i lab-sub-1 -t "lab/#" -v
mosquitto_pub -h mqtt.lab.local -p 8883 --cafile ca.crt \
-u labuser -P 'your-password' -i lab-pub-1 -t "lab/test" -m "hello private CA"
En Python avec paho-mqtt 2.x :
import paho.mqtt.client as mqtt
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="lab-python-1")
client.tls_set(ca_certs="ca.crt") # ne faire confiance qu'à l'AC privée
client.username_pw_set("labuser", "your-password")
client.connect("mqtt.lab.local", 8883)
client.loop_start()
client.publish("lab/test", "verified against private CA", qos=1).wait_for_publish()
client.loop_stop()
client.disconnect()
En Node.js, passez ca: fs.readFileSync("ca.crt") dans les options de MQTT.js. Sur un ESP32, embarquez le contenu de ca.crt et appelez setCACert(). Remarquez que la vérification reste pleinement activée dans chaque exemple : le client fait simplement confiance à votre AC plutôt qu'à une AC publique. Si vous rencontrez des erreurs de vérification, notre guide sur SSL CERTIFICATE_VERIFY_FAILED avec MQTT liste les causes habituelles.
Faire confiance à l'AC privée à l'échelle du système
Passer --cafile à chaque outil devient fastidieux sur les machines de laboratoire. Sur un poste Linux, vous pouvez ajouter l'AC au magasin du système d'exploitation pour que les outils qui l'utilisent, comme mosquitto_sub --capath /etc/ssl/certs, curl et la plupart des environnements d'exécution, fassent automatiquement confiance au broker de laboratoire :
# Debian / Ubuntu / Raspberry Pi OS
sudo cp ca.crt /usr/local/share/ca-certificates/example-lab-mqtt-ca.crt
sudo update-ca-certificates
Sous Windows, importez ca.crt dans le magasin « Autorités de certification racines de confiance » avec certutil -addstore -f Root ca.crt depuis une invite élevée ; sous macOS, ajoutez-le au trousseau Système et marquez-le comme approuvé. Faites-le en connaissance de cause. Tout ce qui est signé par votre AC de laboratoire devient digne de confiance pour cette machine, pour tous les usages et pas seulement MQTT : protégez donc la clé de l'AC en conséquence et retirez l'AC des machines qui quittent le laboratoire. Notez que les clients Python basés sur certifi et Node.js ignorent le magasin du système sauf configuration contraire ; ils ont donc toujours besoin du fichier de l'AC.
Pièges à éviter
- SAN manquant : la vérification du nom d'hôte échoue alors que la chaîne est valide.
- Distribuer le mauvais fichier : les clients ont besoin de
ca.crt, pas debroker.crt, et jamais deca.key. - Désactiver la vérification :
--insecure,tls_insecure_set(True)ourejectUnauthorized: falserendent le certificat inutile. - Oublier l'expiration : notez la date d'expiration du certificat du broker dans un calendrier et automatisez le renouvellement si possible. Un certificat expiré met tous les clients hors ligne d'un coup.
- Validité trop longue du certificat serveur : les certificats de longue durée sont pratiques mais augmentent l'impact d'une clé divulguée. Gardez l'AC de longue durée et le certificat du broker plus court.
- Clé de l'AC sur le broker : stockez la clé de l'AC hors ligne. Le broker n'a besoin que de sa propre clé et de son certificat.
- Problèmes d'horloge : les appareils sans heure exacte rejettent des certificats valides.
La même AC privée peut aussi signer des certificats clients si vous voulez du TLS mutuel ; voir le mTLS MQTT avec certificats clients X.509.
Renouveler le certificat du broker
Comme l'AC privée reste la même, le renouvellement ne concerne que le broker. Générez une nouvelle clé (ou réutilisez l'ancienne si votre politique le permet), créez une nouvelle CSR, signez-la avec la même AC et le même fichier broker.ext, puis remplacez les fichiers sur le broker :
openssl genrsa -out broker-new.key 2048
openssl req -new -key broker-new.key -subj "/O=Example Lab/CN=mqtt.lab.local" -out broker-new.csr
openssl x509 -req -in broker-new.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 397 -sha256 -extfile broker.ext -out broker-new.crt
sudo cp broker-new.crt /etc/mosquitto/certs/broker.crt
sudo cp broker-new.key /etc/mosquitto/certs/broker.key
sudo systemctl restart mosquitto
Les clients ne changent pas, car ils font confiance à ca.crt et non au certificat du broker. C'est tout l'avantage de la méthode par AC privée par rapport à un certificat auto-signé isolé, où chaque client aurait besoin du nouveau fichier. Une simple tâche cron qui vous avertit un mois avant l'expiration vaut la peine d'être ajoutée :
openssl x509 -checkend 2592000 -noout -in /etc/mosquitto/certs/broker.crt \
|| echo "MQTT broker certificate expires within 30 days"
Le coût d'exploitation dont personne ne parle
Une AC privée est facile le premier jour. Le coût apparaît plus tard : distribuer ca.crt à chaque nouveau client, expliquer les avertissements du navigateur quand quelqu'un ouvre un tableau de bord WSS, renouveler le certificat du broker avant son expiration, remplacer l'AC elle-même après une décennie ou une compromission de clé, et documenter le tout pour l'ingénieur suivant. Pour un système exposé à Internet, cet effort n'apporte rien qu'un certificat reconnu publiquement ne fournisse déjà.
C'est la principale raison d'utiliser un broker MQTT managé en production. ConnectMQ présente un certificat Let's Encrypt auquel les systèmes d'exploitation, les navigateurs, Python et Node.js font déjà confiance, et le renouvelle automatiquement. Les clients se connectent au port 8883 ou au WebSocket sécurisé sur le port 8084 sans aucun fichier d'AC à distribuer, hormis l'intégration d'une racine publique standard sur les microcontrôleurs. Vous pouvez le vérifier en quelques secondes sur le serveur MQTT public gratuit, réservé aux tests :
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-i pubca-test-3e8b -t "connectmq/demo/3e8b/#" -v
Pour une comparaison des modèles d'hébergement, lisez notre guide du broker MQTT cloud, et pour la liste complète des étapes de durcissement, voir la configuration TLS MQTT.
Démarrer avec ConnectMQ
Passez-vous d'AC privée pour votre broker de production. Inscrivez-vous à ConnectMQ sur app.connectmq.com, choisissez l'offre gratuite Serverless sans carte bancaire, créez un broker et connectez-vous sur le port 8883 avec le nom d'utilisateur, le mot de passe et le client ID générés. ConnectMQ gère les certificats et leurs renouvellements ; gardez votre configuration auto-signée pour le laboratoire, là où elle a sa place.
Questions fréquentes
Peut-on utiliser un certificat auto-signé en production avec MQTT ?
Oui, sur des réseaux fermés où vous maîtrisez chaque client, à condition d'exploiter une véritable AC privée et de gérer les renouvellements. Pour les brokers exposés à Internet, un certificat reconnu publiquement est plus simple et évite de distribuer la confiance à chaque client.
Pourquoi mon client rejette-t-il le certificat même avec le fichier de l'AC ?
La raison la plus fréquente est un Subject Alternative Name manquant ou erroné. Vérifiez-le avec openssl x509 -noout -ext subjectAltName -in broker.crt et assurez-vous qu'il liste le nom d'hôte utilisé par les clients.
Peut-on obtenir un certificat Let's Encrypt pour un broker interne ?
Uniquement pour un nom de domaine public que vous contrôlez, avec une validation DNS. Les AC publiques n'émettent pas de certificats pour des adresses IP privées ni pour des noms .local.
Faut-il redémarrer Mosquitto après le renouvellement du certificat ?
Mosquitto charge les certificats au démarrage : prévoyez donc un redémarrage ou un rechargement après le renouvellement, puis testez avec openssl s_client.



