Pour effectuer la rotation des identifiants MQTT sans interruption de service, il vous faut deux jeux d'identifiants valides en même temps, des appareils capables de se replier du nouveau vers l'ancien, et une étape de vérification avant toute révocation. Ce guide détaille cette stratégie à double identifiant étape par étape, avec le code côté appareil et l'ordre des opérations pour émettre et révoquer des identifiants sur un broker managé.
Pourquoi faire la rotation des identifiants MQTT ?
Les identifiants statiques ont une longue durée de vie sur les appareils. Au fil des années, ils transitent par les pipelines de build, les ordinateurs du support, le matériel retourné et les passations entre prestataires. La rotation limite la durée pendant laquelle une copie divulguée reste exploitable. Il vous faut aussi un processus de rotation éprouvé pour les événements imprévus :
- Un appareil est volé, retourné ou mis hors service.
- Une image firmware contenant des secrets embarqués a été publiée par erreur.
- Un employé ou un intégrateur ayant accès aux identifiants quitte l'entreprise.
- Un audit de sécurité ou un contrat client exige une rotation périodique.
Le pire moment pour concevoir un processus de rotation, c'est pendant un incident. L'exécuter selon un calendrier régulier garantit qu'il reste fonctionnel.
Pourquoi une rotation naïve provoque des pannes
L'approche tentante consiste à changer le mot de passe sur le broker, puis à envoyer le nouveau aux appareils. Tout appareil qui n'a pas encore reçu la mise à jour se retrouve bloqué, et un appareil bloqué hors de MQTT ne peut souvent pas non plus recevoir la mise à jour, puisque le canal de mise à jour est MQTT. Vous finissez par devoir intervenir sur site pour chaque appareil hors ligne.
L'ordre inverse échoue aussi : si les appareils basculent d'abord alors que le broker ne connaît pas encore le nouvel identifiant, ils ne peuvent pas se connecter. La seule approche sûre est une fenêtre de chevauchement pendant laquelle les deux identifiants fonctionnent.
La stratégie de rotation à double identifiant
| Phase | État du broker | État de l'appareil | Condition de sortie |
|---|---|---|---|
| 1. Émettre | Ancien et nouveau valides | Ancien uniquement | Nouvel identifiant créé et enregistré |
| 2. Préparer | Ancien et nouveau valides | Ancien actif, nouveau stocké | L'appareil confirme le stockage du nouvel identifiant |
| 3. Basculer | Ancien et nouveau valides | Nouveau actif, ancien en repli | Appareil connecté avec le nouvel identifiant |
| 4. Vérifier | Ancien et nouveau valides | Nouveau actif | Aucune connexion avec l'ancien identifiant pendant une période définie |
| 5. Révoquer | Nouveau uniquement | Nouveau uniquement, ancien supprimé | Ancien identifiant supprimé partout |
Ces phases s'appliquent à n'importe quel broker. Ce qui change, c'est la manière d'émettre et de révoquer les identifiants.
Phase 1 : émettre le nouvel identifiant
Sur un broker Mosquitto auto-hébergé, cela revient à ajouter un second utilisateur au fichier de mots de passe. Sur ConnectMQ, émettez un nouveau jeu d'identifiants pour l'appareil dans le portail. Chaque jeu possède ses propres nom d'utilisateur, mot de passe et client ID, car les client IDs sont liés aux identifiants émis. Enregistrez dans votre inventaire la correspondance entre l'appareil physique et ses anciens et nouveaux client IDs avant d'aller plus loin.
Cette liaison a une conséquence pratique : pendant la rotation, l'appareil ne change pas seulement de mot de passe, il change tout son triplet d'identité. Assurez-vous que tous les consommateurs qui s'appuient sur le client ID, comme la surveillance de présence sur $SYS/broker/connection/{clientId}/state ou votre propre inventaire, connaissent les deux IDs pendant le chevauchement.
Phase 2 : le préparer sur l'appareil
Livrez le nouvel identifiant via la connexion existante, authentifiée et protégée par TLS. Un modèle courant est un topic de commande que seul cet appareil écoute :
devices/<deviceId>/cmd/credentials # backend -> device, QoS 1, not retained
devices/<deviceId>/evt/credentials # device -> backend, acknowledgement
Ne publiez jamais d'identifiants sous forme de retained messages, ni sur un topic partagé ou lisible via wildcard. Si votre broker n'applique pas de permissions par topic, tenez totalement les clients non fiables à l'écart, ou livrez les identifiants via un canal séparé comme votre service de mise à jour OTA. L'appareil écrit le nouvel identifiant dans un stockage protégé, dans un emplacement distinct de l'actuel, et accuse réception avec un hash, pas avec le mot de passe lui-même.
Phase 3 : basculer avec repli
L'appareil se reconnecte avec le nouvel identifiant. Si le broker le rejette, l'appareil se replie sur l'ancien et signale l'échec. C'est cette étape qui rend la rotation sûre.
import json
import os
import ssl
import time
import paho.mqtt.client as mqtt
HOST = "YOUR_BROKER_HOST"
STORE = "/var/lib/mydevice/credentials.json" # protéger avec des permissions 0600
def load():
with open(STORE) as f:
return json.load(f) # {"active": {...}, "pending": {...} or null}
def save(data):
tmp = STORE + ".tmp"
with open(tmp, "w") as f:
json.dump(data, f)
os.replace(tmp, STORE) # échange atomique, résiste à une coupure de courant pendant l'écriture
def try_connect(cred, timeout=15):
result = {}
def on_connect(client, userdata, flags, reason_code, properties):
result["rc"] = reason_code
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=cred["client_id"], protocol=mqtt.MQTTv5)
c.username_pw_set(cred["username"], cred["password"])
c.tls_set(cert_reqs=ssl.CERT_REQUIRED)
c.on_connect = on_connect
c.connect(HOST, 8883, keepalive=60)
c.loop_start()
deadline = time.time() + timeout
while "rc" not in result and time.time() < deadline:
time.sleep(0.2)
if result.get("rc") is not None and not result["rc"].is_failure:
return c
c.loop_stop()
c.disconnect()
return None
def connect_with_rotation():
data = load()
if data.get("pending"):
client = try_connect(data["pending"])
if client:
data["previous"] = data["active"] # conservé en repli jusqu'à la révocation
data["active"], data["pending"] = data["pending"], None
save(data)
return client
print("New credential rejected, falling back")
client = try_connect(data["active"])
if client is None and data.get("previous"):
client = try_connect(data["previous"])
return client
Conservez l'ancien identifiant dans previous jusqu'à ce que le backend informe l'appareil qu'il a été révoqué. Supprimez-le alors du stockage.
Phase 4 : vérifier
Avant de révoquer quoi que ce soit, confirmez que le parc a basculé. Signaux utiles :
- L'accusé de réception de chaque appareil sur son topic
evt/credentials. - La présence du nouveau client ID sur
$SYS/broker/connection/{clientId}/stateet l'absence de l'ancien. - Votre rapport d'inventaire : les appareils encore sur l'ancien identifiant après la fenêtre.
Examinez les retardataires un par un. Les appareils hors ligne sont fréquents ; ils basculeront à leur prochaine connexion, tant que vous ne révoquez pas trop tôt.
Phase 5 : révoquer
Supprimez l'ancien jeu d'identifiants dans le portail (ou supprimez l'utilisateur et rechargez Mosquitto). Demandez ensuite aux appareils d'effacer l'emplacement previous. À partir de là, une copie divulguée de l'ancien identifiant est inutile.
Checklist de rotation
- L'inventaire associe chaque appareil à son client ID actuel.
- Le nouvel identifiant est émis et enregistré avant toute modification sur un appareil.
- Les identifiants sont livrés uniquement via TLS, sur un topic ou un canal propre à l'appareil, jamais en retained.
- L'appareil stocke le nouvel identifiant dans un emplacement séparé, avec une écriture atomique.
- L'appareil se replie sur l'ancien identifiant en cas de rejet et le signale.
- La fenêtre de chevauchement est assez longue pour les appareils hors ligne pendant plusieurs jours.
- La révocation n'a lieu qu'après vérification, et la suppression côté appareil après la révocation.
- Le processus est exécuté selon un calendrier, pas seulement lors d'incidents.
Pièges à surveiller
- Boucles de reconnexion serrées avec un mauvais mot de passe. ConnectMQ bloque les adresses IP après des échecs de connexion répétés. Un site entier derrière une seule adresse NAT peut être bloqué par quelques appareils défaillants. Utilisez un backoff exponentiel et repliez-vous rapidement.
- Deux appareils avec un seul identifiant. Comme le client ID est lié à l'identifiant, deux appareils partageant un même jeu s'approprient mutuellement leur session et se déconnectent en boucle. Chaque appareil a besoin de son propre jeu.
- Quota de connexions pendant le chevauchement. Si des appareils maintiennent brièvement les deux connexions, ou si vous testez de nouveaux identifiants depuis un ordinateur portable, comptez-les dans la limite de connexions de votre offre.
- Oublier les clients qui ne sont pas des appareils. Les flows Node-RED, les agents Telegraf et les services backend détiennent aussi des identifiants. Faites-en la rotation selon le même calendrier.
Le stockage sur l'appareil compte autant que le processus de rotation. Consultez sécuriser les identifiants MQTT sur les appareils pour les options ESP32 et Linux, et le provisionnement sécurisé des appareils IoT pour installer le premier identifiant sur l'appareil en toute sécurité.
Démarrer avec ConnectMQ
Un broker MQTT managé vous décharge des fichiers de mots de passe et des renouvellements de certificats, pour que vous puissiez vous concentrer sur la partie appareil de la rotation. Créez gratuitement un broker Serverless sur app.connectmq.com, sans carte bancaire, et testez le flux complet à double identifiant avec quelques appareils avant de le déployer. Le serveur MQTT public gratuit broker.connectmq.com, anonyme, n'a pas d'identifiants à faire tourner : réservez-le aux tests et aux prototypes, jamais aux données de production. Pour comprendre comment les identifiants circulent dans le CONNECT, lisez l'authentification MQTT par nom d'utilisateur et mot de passe, et pour voir comment cela s'intègre à une configuration de production, découvrez l'exploitation d'un broker MQTT cloud.
Questions fréquentes
À quelle fréquence faut-il faire la rotation des identifiants MQTT ?
Il n'existe pas d'intervalle universel. Choisissez-en un que votre processus peut tenir, souvent une fois par an ou à chaque version majeure du firmware, et effectuez toujours une rotation immédiate après une fuite suspectée ou lorsqu'un appareil échappe à votre contrôle.
Peut-on faire la rotation des identifiants sur des appareils hors ligne ?
Oui, à condition que l'ancien identifiant reste valide jusqu'à leur retour. L'appareil bascule lors de sa prochaine connexion, et vous ne révoquez qu'une fois qu'il l'a fait.
Pourquoi le client ID change-t-il pendant la rotation sur ConnectMQ ?
ConnectMQ lie les client IDs aux identifiants émis ; un nouveau jeu d'identifiants s'accompagne donc de son propre client ID. Mettez à jour la surveillance de présence ou l'inventaire qui s'appuient sur le client ID.
Que faire si le nouvel identifiant est rejeté ?
L'appareil doit se replier sur l'ancien identifiant, se reconnecter et signaler l'échec, afin que vous puissiez corriger l'identifiant émis avant de réessayer.



