Internet des Objets : bien comprendre MQTT
Créé en 1999 par le Dr Andy Stanford-Clark d'IBM, et Arlen Nipper d'Arcom (maintenant Eurotech) MQTT est le protocole qui joue un rôle important dans l'Internet des objets. D'où l'intérêt de bien le connaître.
MQTT permet concrètement aux appareils d'envoyer des informations sur un sujet donné à un serveur qui fonctionne comme un broker de messages. Le broker pousse ces informations vers les clients qui se sont précédemment abonnés. Pour l'utilisateur, un sujet ressemble à un chemin hiérarchique. Les clients peuvent s'abonner à un niveau spécifique de la hiérarchie d'un sujet ou à plusieurs niveaux s'ils utilisent un caractère générique.
Fonctionnement de MQTT
Une session MQTT est divisée en quatre étapes : connexion, authentification, communication et terminaison.
Un client commence par créer une connexion TCP/IP vers le broker en utilisant soit un port standard, soit un port personnalisé défini par les opérateurs du broker. Lors de la connexion, le serveur peut continuer une ancienne session s'il reconnaît une identité client précédemment utilisée.
Les ports standards sont les suivants : 1883 pour la communication non chiffrée et 8883 pour la communication chiffrée utilisant SSL/TLS. Pendant l'établissement de liaison (ou handshake) SSL/TLS initial, le client valide le certificat du serveur afin d'authentifier le serveur. Lors de cet échange, le client peut également fournir au broker un certificat client que le broker pourra ensuite utiliser pour authentifier le client. Bien que cela ne soit pas spécifié dans la norme MQTT, les brokers prennent habituellement en charge l'authentification des clients avec leurs certificats SSL/TLS.
Le protocole MQTT étant avant tout destiné aux appareils disposant de ressources limitées, SSL/TLS n'est pas toujours disponible et dans certains cas, il n'est pas souhaité. Le client s'authentifie alors en envoyant un nom d'utilisateur et un mot de passe en clair au serveur lors de la séquence de paquets CONNECT/CONNACK.
Certains brokers, en particulier les brokers ouverts publiés sur Internet, acceptent les clients anonymes. Dans ce cas, le nom d'utilisateur et le mot de passe sont tout simplement laissés vides.
MQTT est considéré comme un protocole léger parce que les messages ont tous une faible empreinte logicielle. Chaque message se compose d'un en-tête fixe (2 octets), d'un en-tête variable facultatif, d'une charge utile de message limitée à 256 Mo et d'un niveau de qualité de service. Les trois niveaux de qualité de service déterminent la façon dont le protocole MQTT gère le contenu. Bien que les niveaux plus élevés soient plus fiables, ils sont également plus gourmands en termes de latence et de bande passante. Les clients abonnés peuvent spécifier le niveau de QoS maximal qu'ils souhaitent recevoir.
Le niveau de qualité de service le plus simple est le service non confirmé (Unacknowledged Service). Ce niveau utilise une séquence de paquets PUBLISH : l'éditeur envoie un message une seule fois au broker et ce dernier transmet ce message une seule fois aux abonnés. Aucun mécanisme ne garantit la réception du message et le broker ne l'enregistre pas non plus. Ce niveau de qualité de service est également appelé « QoS niveau 0 » ou QoS0, ou encore « At most once » (au plus une fois).
Le deuxième niveau de service est le service confirmé (Acknowledged Service). Ce niveau utilise une séquence de paquets PUBLISH/PUBACK (Publish Acknowledge) entre l'éditeur et son broker, ainsi qu'entre le broker et les abonnés.
Un paquet de confirmation vérifie que le contenu a été reçu et un mécanisme de renvoi du contenu d'origine est déclenché si l'accusé de réception n'est pas reçu en temps voulu. Cela signifie que l'abonné peut recevoir plusieurs copies du même message. Ce niveau de qualité de service est également appelé « QoS niveau 1 » ou QoS1, ou encore « At least once » (au moins une fois).
Le troisième niveau de QoS est le service garanti (Assured Service). Ce niveau délivre le message avec deux paires de paquets. La première est appelée PUBLISH/PUBREC et la seconde, PUBREL/PUBCOMP. Les deux paires s'assurent que quel que soit le nombre de tentatives, le message ne sera délivré qu'une seule fois. Ce niveau de qualité de service est également appelé « QoS niveau 2 » ou QoS2, ou encore « Exactly once » (exactement une fois).
Au cours de la phase de communication, un client peut effectuer les opérations suivantes : publication, abonnement, désabonnement ou ping.
L'opération de publication envoie un bloc binaire de données (le contenu) vers un sujet défini par l'éditeur. MQTT prend en charge les messages de type BLOB d'une taille maximale de 256 Mo. Le format du contenu dépend de l'application. Les abonnements à des sujets sont réalisés au moyen d'une paire de paquets SUBSCRIBE/SUBACK. Le désabonnement est réalisé de manière similaire à l'aide d'une paire de paquets UNSUBSCRIBE/UNSUBACK.
Les chaînes décrivant un sujet forment une arborescence en utilisant la barre oblique (/) comme caractère de séparation. Un client peut s'abonner à des branches entières de l'arborescence d'un sujet (ou se désabonner) à l'aide des deux caractères génériques suivants : le signe plus (+), qui correspond à un seul niveau, et le dièse (#) pour plusieurs niveaux. Un caractère spécial, le dollar ($), permet d'exclure un sujet de tout abonnement utilisant un caractère générique à la racine. En règle générale, le dollar sert à transporter des messages système ou serveur spécifiques.
Un client peut effectuer une quatrième opération au cours de la phase de communication : il peut envoyer une commande ping vers le serveur du broker en utilisant une séquence de paquets PINGREQ/PINGRESP. Grossièrement traduit, cela signifie « ES-TU VIVANT/OUI JE SUIS VIVANT ». Cette opération n'a pas d'autre fonction que de maintenir une connexion active et de s'assurer que la connexion TCP n'a pas été coupée par une passerelle ou un routeur.
Lorsqu'un éditeur ou un abonné souhaite mettre fin à une session MQTT, il envoie un message DISCONNECT au broker, puis met fin à la connexion. On parle d'arrêt progressif, car il permet au client de se reconnecter facilement en fournissant son identité client et de reprendre la session là où il l'avait laissée.
En cas de déconnexion brutale ne laissant pas le temps à l'éditeur d'envoyer un message DISCONNECT, le broker peut envoyer aux abonnés un message de l'éditeur que le broker avait précédemment mis en cache. Le message, appelé dernières volontés et testament, indique aux abonnés les mesures à prendre en cas d'arrêt inopiné de l'éditeur.
Défis liés à l'utilisation de MQTT pour l'Internet des objets
Dans la mesure où MQTT n'intègre pas de mécanismes de sécurité, ce protocole est traditionnellement utilisé dans des réseaux sécurisés à des fins applicatives spécifiques. La structure des sujets MQTT peut facilement devenir une immense arborescence. Or, il n'existe pas de méthode simple permettant de la diviser en domaines logiques plus petits qui pourraient être fédérés. Cela rend difficile la création d'un réseau MQTT évolutif à grande échelle, car dès lors que l'arborescence des sujets grandit, la complexité augmente.
MQTT présente un autre inconvénient : son manque d'interopérabilité. Etant donné que la charge utile des messages est binaire, sans aucune information quant à leur codage, des problèmes peuvent survenir, notamment dans des architectures ouvertes où des applications de différents fabricants sont censées fonctionner de manière transparente les unes avec les autres.
Comme nous l'avons vu plus haut, le protocole MQTT intègre des fonctionnalités d'authentification minimales. Nom d'utilisateur et mot de passe sont envoyés en clair et toute utilisation sécurisée de MQTT exige de mettre en oeuvre SSL/TLS, qui malheureusement n'est pas un protocole léger.
Authentifier des clients avec des certificats client n'est pas un processus des plus simples et MQTT ne permet pas, hormis par des moyens propriétaires hors bande, de déterminer qui est propriétaire d'un sujet et qui peut y publier des informations. Il est donc très facile d'injecter des messages malveillants, volontairement ou non, dans le réseau. En outre, il n'y a aucun moyen pour le récepteur de savoir qui a envoyé le message d'origine, à moins que cette information ne soit contenue dans le message.
La couche de sécurité propriétaire qui doit être ajoutée à MQTT augmente donc l'empreinte logicielle et complique la mise en oeuvre du protocole.
En dépit de ces considérations, de nombreux experts estiment que MQTT jouera un rôle important dans l'Internet des objets, en facilitant des opérations telles que le suivi des stocks, la télématique automobile, la surveillance des ressources et les réseaux du corps médical.
Le protocole s'améliore en permanence et prend désormais en charge WebSockets, un autre protocole qui permet une communication bidirectionnelle en temps réel entre les clients et les brokers.
D'autres protocoles de transfert pour les appareils à ressources limitées sont à l'étude. Comme le protocole pour applications contraintes (CoAP pour Constrained Application Protocol), qui utilise un modèle de communication de type requête/réponse. Ou le protocole de file de messages avancé (AMQP pour Advanced Message Queuing Protocol) qui, comme MQTT, s'appuie sur un modèle publication/abonnement.