Une ACL MQTT (access control list, ou liste de contrôle d'accès) est l'ensemble des règles qu'un broker utilise pour décider quel client authentifié peut publier ou s'abonner sur quels topics. Cet article explique les concepts, montre à quoi ils ressemblent dans une vraie configuration de broker avec Mosquitto, décrit ce qui se passe lorsqu'un client est refusé et propose des modèles de conception de topics qui gardent l'autorisation simple, que vous utilisiez des ACL fines ou une isolation au niveau du tenant.
Authentification ou autorisation
Les deux notions se confondent facilement, et les brokers les traitent à des étapes différentes :
- L'authentification répond à la question « qui êtes-vous ? ». Elle a lieu une seule fois, au CONNECT, à l'aide d'un nom d'utilisateur et d'un mot de passe, d'un certificat client ou d'un jeton. Consultez l'authentification MQTT par nom d'utilisateur et mot de passe pour les détails.
- L'autorisation répond à la question « qu'avez-vous le droit de faire ? ». Elle est vérifiée à chaque SUBSCRIBE et, selon le broker, à chaque PUBLISH. Les ACL sont la manière la plus courante de l'exprimer.
Un client authentifié sans règle d'autorisation peut généralement lire et écrire tout ce que son broker ou son tenant autorise. Les ACL restreignent cela par utilisateur, par client ID ou par rôle.
Ce que contient une règle d'ACL MQTT
Quelle que soit la syntaxe du broker, chaque règle combine les mêmes éléments :
| Élément | Exemples |
|---|---|
| Sujet | Un nom d'utilisateur, un client ID, un rôle ou « tout le monde » |
| Action | Lecture (s'abonner et recevoir), écriture (publier) ou les deux |
| Filtre de topic | factory/line1/#, devices/+/cmd, devices/%u/# |
| Décision | Autoriser ou refuser |
Les règles sont comparées au topic de chaque opération. Pour les abonnements, de nombreux brokers vérifient le filtre demandé lui-même ; un client autorisé à lire devices/sensor-01/# ne peut donc pas glisser un abonnement plus large à devices/# au travers du contrôle.
Exemple d'ACL MQTT avec Mosquitto
Mosquitto est une référence pratique, car son ACL sous forme de fichier est courte et lisible. L'authentification et le fichier ACL s'activent dans mosquitto.conf :
# mosquitto.conf
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
Le fichier ACL lui-même :
# /etc/mosquitto/acl
# Les règles placées avant toute ligne "user" s'appliquent aux clients anonymes (aucune ici)
# Un service backend qui lit toute la télémétrie et envoie des commandes
user backend
topic read factory/+/+/telemetry/#
topic write factory/+/+/cmd/#
# Un tableau de bord en lecture seule
user dashboard
topic read factory/#
# Les règles pattern s'appliquent à tous les utilisateurs.
# %u = nom d'utilisateur, %c = client ID
pattern write factory/+/%c/telemetry/#
pattern read factory/+/%c/cmd/#
pattern write factory/+/%c/status
Avec ces règles, un appareil qui se connecte avec le client ID cnc-07 peut publier factory/line2/cnc-07/telemetry/spindle et recevoir factory/line2/cnc-07/cmd/stop, mais il ne peut ni lire les commandes d'une autre machine ni publier en se faisant passer pour une autre machine. Les règles pattern passent à l'échelle de milliers d'appareils sans une entrée par appareil, ce qui est la principale raison de placer le client ID dans le chemin du topic. Mosquitto prend aussi en charge des lignes topic deny et un plugin de sécurité dynamique avec rôles et groupes ; la documentation de Mosquitto couvre les deux.
Rechargez le broker après avoir modifié le fichier, puis testez :
# Autorisé : cnc-07 publie sa propre télémétrie
mosquitto_pub -h localhost -p 8883 --cafile ca.crt -V mqttv5 \
-i cnc-07 -u cnc-07 -P "$PW" -t 'factory/line2/cnc-07/telemetry/spindle' -m 1200 -q 1
# Refusé : cnc-07 publie en tant que cnc-08
mosquitto_pub -h localhost -p 8883 --cafile ca.crt -V mqttv5 \
-i cnc-07 -u cnc-07 -P "$PW" -t 'factory/line2/cnc-08/telemetry/spindle' -m 1200 -q 1
Ce qui se passe lorsqu'un client est refusé
Les opérations refusées ne produisent pas toujours une erreur évidente, ce qui explique pourquoi les problèmes d'ACL sont réputés difficiles à déboguer.
| Opération | MQTT 3.1.1 | MQTT 5.0 |
|---|---|---|
| SUBSCRIBE refusé | Code de retour SUBACK 0x80 (échec) | Reason code SUBACK 0x87 Not authorized |
| PUBLISH QoS 0 refusé | Ignoré silencieusement | Ignoré silencieusement |
| PUBLISH QoS 1/2 refusé | Généralement acquitté puis ignoré | PUBACK/PUBREC peut porter 0x87, selon le broker |
Conseils pratiques de débogage :
- Inspectez toujours les codes de SUBACK. De nombreuses bibliothèques les exposent dans un callback ; journalisez-les au démarrage.
- Utilisez MQTT 5 et QoS 1 pendant les tests. Les reason codes des acquittements rendent les refus visibles.
- Testez avec l'identité de l'appareil. Tester avec un compte administrateur ne prouve rien sur les règles de l'appareil.
- Consultez le journal du broker. La plupart des brokers journalisent les publications et abonnements refusés au niveau debug.
Concevoir des namespaces de topics pour une autorisation simple
De bonnes ACL commencent par de bons topics. Si l'identité et la direction sont visibles dans le chemin du topic, les règles se résument à quelques patterns. Sinon, vous vous retrouvez avec une longue liste de cas particuliers.
Placer l'identité dans le chemin
Incluez le client ID ou l'ID de l'appareil à un niveau fixe : factory/<line>/<deviceId>/.... Les règles pattern comme %c ne fonctionnent que si l'identité occupe un niveau de topic entier.
Séparer les directions
Utilisez des branches distinctes pour les données qui remontent et les commandes qui descendent : .../telemetry, .../status, .../cmd. Les appareils reçoivent l'écriture sur les deux premières et la lecture sur la troisième.
Séparer les tenants ou les clients au sommet
Si un broker sert plusieurs clients, faites du client le premier niveau : <tenant>/.... Les identifiants de chaque tenant sont alors limités à un seul sous-arbre.
Garder les données partagées dans une branche clairement nommée
La configuration diffusée à tous les appareils va dans broadcast/... ou config/..., avec un accès en lecture seule pour les appareils.
L'article exemples de hiérarchie de topics MQTT présente des arborescences complètes construites sur ces principes.
Checklist de conception des ACL
- Refuser par défaut ; n'autoriser que ce dont chaque rôle a besoin.
- Donner aux appareils l'écriture sur leur propre télémétrie et leur statut, la lecture sur leurs propres commandes, et rien d'autre.
- Donner aux tableaux de bord un accès en lecture seule.
- Donner aux services backend l'écriture sur les branches de commandes, et auditer qui détient ces identifiants.
- Ne jamais accorder
#à un identifiant d'appareil. - Conserver le fichier de règles ou les définitions de rôles sous contrôle de version et relire les modifications.
- Tester chaque rôle avec ses vrais identifiants après chaque modification.
L'autorisation sur ConnectMQ
ConnectMQ ne fournit pas d'ACL par topic. Sur ConnectMQ, l'isolation fonctionne au niveau du tenant : le trafic du broker de chaque client est isolé de tous les autres tenants, les identifiants sont générés par broker et les client IDs sont liés au nom d'utilisateur et au mot de passe attribués, de sorte qu'un client ne peut pas usurper l'identité d'un autre. Les quotas par offre, la protection contre le flooding et le blocage d'IP après des échecs de connexion répétés limitent ce qu'un client malveillant ou défaillant peut faire.
Ce que cela implique pour la conception :
- Utilisez des brokers distincts comme frontière de sécurité. Si deux groupes de clients ne doivent jamais voir les données l'un de l'autre, placez-les sur des brokers différents plutôt que de compter sur des règles de topics. Une offre Dedicated vous donne un cluster isolé lorsque cette frontière doit aussi être physique.
- Tenez les clients non fiables à l'écart du broker. Les utilisateurs de navigateurs et les tiers doivent dialoguer avec votre backend, qui détient les identifiants du broker et décide de ce qu'il publie en leur nom.
- Concevez les topics comme si des ACL pouvaient arriver plus tard. L'identité dans le chemin et des branches de commandes séparées ne coûtent rien aujourd'hui et préservent vos options si vous déplacez une partie du système vers un broker doté de règles de topics.
- Validez les commandes sur l'appareil. Un appareil doit vérifier qu'une commande est bien formée et attendue avant d'agir, quelle que soit la façon dont le broker l'autorise.
Cette combinaison d'isolation des tenants et de discipline sur les topics convient bien à de nombreux parcs. Si votre projet exige des restrictions de topics par appareil au sein d'un namespace partagé, prévoyez pour cette partie du système un broker qui prend en charge les ACL au niveau des topics. Pour une vue d'ensemble, consultez les bonnes pratiques de sécurité MQTT et MQTT est-il sécurisé ?.
Démarrer avec ConnectMQ
Faites fonctionner vos appareils sur un broker MQTT managé avec isolation des tenants, TLS, identifiants générés liés aux client IDs et blocage d'IP en cas d'échecs de connexion. Créez gratuitement un broker Serverless sur app.connectmq.com, sans carte bancaire, et prototypez d'abord vos conceptions de topics sur le serveur MQTT public gratuit, réservé aux tests et aux données factices.
Questions fréquentes
Qu'est-ce qu'une ACL MQTT ?
C'est une liste de règles qui indique à un broker quels utilisateurs ou clients peuvent publier ou s'abonner sur quels filtres de topics. Elle est vérifiée une fois que le client s'est authentifié.
ConnectMQ prend-il en charge les ACL par topic ?
Non. ConnectMQ isole les tenants les uns des autres et lie les client IDs aux identifiants (nom d'utilisateur et mot de passe) attribués, mais il n'applique pas de règles de lecture et d'écriture par topic au sein d'un broker.
Pourquoi ma publication refusée ne renvoie-t-elle pas d'erreur ?
En MQTT 3.1.1, le broker n'a aucun moyen de signaler une publication refusée ; elle est donc ignorée silencieusement. Les brokers MQTT 5 peuvent renvoyer le reason code 0x87 dans les acquittements QoS 1 et 2.
Les règles d'ACL doivent-elles utiliser le nom d'utilisateur ou le client ID ?
Utilisez l'identifiant qui est unique par appareil et que le client ne peut pas choisir librement. Si le broker lie les client IDs aux identifiants, les deux conviennent ; sinon, préférez le nom d'utilisateur.



