Lors de l’annonce de la version R29 de NGINX Plus, nous avons brièvement présenté sa nouvelle prise en charge native de l’analyse des messages MQTT. Dans cet article, nous approfondirons le sujet et verrons comment configurer NGINX Plus afin d’optimiser les déploiements MQTT dans les environnements d’entreprise.
Qu’est-ce que MQTT ?
MQTT signifie « Message Queuing Telemetry Transport ». Il s’agit d’un protocole de messagerie léger et très répandu, basé sur le modèle publication-abonnement. Il est idéal pour connecter sur Internet des appareils et des applications de l’Internet des objets (IoT) ou de communication de machine à machine (M2M). MQTT est conçu pour fonctionner efficacement dans des environnements à faible bande passante ou à faible consommation d’énergie, ce qui en fait un choix idéal pour les applications comptant un grand nombre de clients distants. Il est utilisé dans de nombreux secteurs, notamment l’électronique grand public, l’automobile, les transports, l’industrie manufacturière et la santé.
Traitement des messages MQTT avec NGINX Plus
NGINX Plus R29 prend en charge MQTT 3.1.1 et MQTT 5.0. Il fait office de proxy entre les clients et les courtiers, déchargeant ainsi les systèmes centraux de certaines tâches, facilitant la mise à l’échelle et réduisant les coûts de calcul. Plus précisément, NGINX Plus analyse et réécrit certaines parties des messages MQTT CONNECT, ce qui permet de proposer des fonctionnalités telles que :
- Répartition de charge des brokers MQTT
- Persistance de session (reconnexion des clients au même broker)
- Terminaison SSL/TLS
- Authentification par certificat client
Les directives de traitement des messages MQTT doivent être définies dans le contexte stream d’un fichier de configuration NGINX et sont fournies par les modules ngx_stream_mqtt_preread_module
et ngx_stream_mqtt_filter_module.
Le module preread traite les données MQTT avant leur transmission par le proxy interne de NGINX, ce qui permet de prendre des décisions d’équilibrage de charge et de routage en amont en fonction des données de message analysées.
Le module filter permet de réécrire les champs clientid, username et password dans les messages CONNECT reçus. La possibilité d’attribuer à ces champs des variables et des valeurs complexes élargit considérablement les options de configuration, ce qui permet à NGINX Plus de masquer les informations sensibles des appareils ou d’insérer des données telles que le nom distinctif d’un certificat TLS.
Directives et variables MQTT
Plusieurs nouvelles directives et variables intégrées sont désormais disponibles pour ajuster votre configuration NGINX afin d’optimiser les déploiements MQTT et de répondre à vos besoins spécifiques.
Directives et variables intégrées du module Preread
mqtt_preread– Active l’analyse MQTT et extrait les champsclientidetusernamedes messages CONNECT envoyés par les appareils clients. Ces valeurs sont accessibles via des variables intégrées et permettent de répartir les sessions par hachage entre les serveurs en amont avec équilibrage de charge (voir les exemples ci-dessous).$mqtt_preread_clientid– Représente l’identifiant du client MQTT envoyé par l’appareil.$mqtt_preread_username– Représente le nom d’utilisateur envoyé par le client à des fins d’authentification.
Directives du module de filtrage
mqtt– Indique si la réécriture MQTT est activée.mqtt_buffers– Remplace le nombre maximal de tampons de traitement MQTT pouvant être alloués par connexion, ainsi que la taille de chaque tampon. Par défaut, NGINX impose une limite de 100 tampons par connexion, d’une taille de 1 Ko chacun. Cette configuration offre généralement des performances optimales, mais peut nécessiter des ajustements dans certaines situations particulières. Par exemple, les messages MQTT plus longs nécessitent des tampons de plus grande taille. Les systèmes qui traitent un volume plus important de messages MQTT pour une connexion donnée sur une courte période peuvent tirer parti d’un nombre accru de tampons. Dans la plupart des cas, l’ajustement des paramètres des tampons a peu d’incidence sur les performances globales du système, car NGINX crée les tampons à partir d’un pool de mémoire interne.mqtt_rewrite_buffer_size– Spécifie la taille du tampon utilisé pour construire les messages MQTT. Cette directive est déconseillée et obsolète depuis NGINX Plus R30.mqtt_set_connect– Réécrit les paramètres du message CONNECT envoyé par un client. Les paramètres pris en charge sont notamment :clientid,usernameetpassword.
Exemples MQTT
Examinons plus en détail les avantages du traitement des messages MQTT avec NGINX Plus, ainsi que les bonnes pratiques associées. Notez que nous utilisons les ports 1883 et 8883 dans les exemples ci-dessous. Le port 1883 est le port MQTT non sécurisé par défaut, tandis que le port 8883 est le port chiffré par SSL/TLS par défaut.
Répartition de charge des brokers MQTT
La nature éphémère des appareils MQTT peut entraîner des changements inattendus des adresses IP clientes. Cela peut compliquer l’acheminement des connexions des appareils vers le bon broker en amont. Le déplacement ultérieur des connexions d’un broker en amont vers un autre peut nécessiter des opérations de synchronisation coûteuses entre les brokers, augmentant ainsi la latence et les coûts.
En analysant le champ « clientid » d’un message MQTT CONNECT, NGINX peut établir des sessions persistantes avec les brokers de services en amont. Pour ce faire, il utilise le champ « clientid » comme clé de hachage afin de maintenir les connexions aux services de broker sur le backend.
Dans cet exemple, nous transmettons les données des appareils MQTT via un proxy en utilisant le clientid comme jeton pour établir des sessions persistantes avec trois brokers en amont. Nous utilisons le paramètre consistent afin qu’en cas de défaillance d’un serveur en amont, sa part du trafic soit répartie uniformément entre les serveurs restants, sans affecter les sessions déjà établies sur ces serveurs.
stream { mqtt_preread on;
upstream backend {
zone tcp_mem 64k;
hash $mqtt_preread_clientid consistent;
server 10.0.0.7:1883; # upstream mqtt broker 1
server 10.0.0.8:1883; # upstream mqtt broker 2
server 10.0.0.9:1883; # upstream mqtt broker 3
}
server {
listen 1883;
proxy_pass backend;
proxy_connect_timeout 1s;
}
}NGINX Plus peut également analyser le champ du nom d’utilisateur d’un message MQTT CONNECT. Pour plus de détails, consultez la spécification du module « ngx_stream_mqtt_preread_module ».
Terminaison SSL/TLS
Le chiffrement des communications des appareils est essentiel pour garantir la confidentialité des données et se protéger contre les attaques de l’homme du milieu. Toutefois, la négociation TLS, le chiffrement et le déchiffrement peuvent mobiliser une part importante des ressources d’un broker MQTT. Pour y remédier, NGINX Plus peut décharger le broker (ou le cluster de brokers) du chiffrement des données, ce qui simplifie les règles de sécurité et permet aux brokers de se concentrer sur le traitement des messages des appareils.
Dans cet exemple, nous montrons comment NGINX peut être utilisé comme proxy pour acheminer le trafic MQTT chiffré par TLS des appareils vers un broker backend. La directive « ssl_session_cache » définit un cache de 5 mégaoctets, suffisant pour stocker environ 20 000 sessions SSL. NGINX tentera de joindre le broker faisant l’objet du proxy pendant cinq secondes avant d’expirer, comme défini par la directive « proxy_connect_timeout ».
stream { server {
listen 8883 ssl;
ssl_certificate /etc/nginx/certs/tls-cert.crt;
ssl_certificate_key /etc/nginx/certs/tls-key.key;
ssl_session_cache shared:SSL:5m;
proxy_pass 10.0.0.8:1883;
proxy_connect_timeout 5s;
}
} Substitution de l’identifiant client
Pour des raisons de sécurité, vous pouvez choisir de ne pas stocker d’informations permettant d’identifier les clients dans la base de données du broker MQTT. Par exemple, un appareil peut envoyer un numéro de série ou d’autres données sensibles dans le cadre d’un message MQTT CONNECT. En remplaçant l’identifiant d’un appareil par d’autres valeurs statiques connues reçues d’un client, il est possible d’établir une autre clé unique pour chaque appareil tentant d’accéder à des brokers utilisant NGINX Plus comme proxy.
Dans cet exemple, nous extrayons un identifiant unique du certificat SSL client d’un appareil et l’utilisons pour masquer son identifiant client MQTT. L’authentification par certificat client (TLS mutuel) est contrôlée par la directive ssl_verify_client. Lorsque le paramètre est défini sur on, NGINX vérifie que les certificats clients sont signés par une autorité de certification (CA) de confiance. La liste des certificats d’autorités de certification de confiance est définie par la directive ssl_client_certificate.
stream { mqtt on;
server {
listen 8883 ssl;
ssl_certificate /etc/nginx/certs/tls-cert.crt;
ssl_certificate_key /etc/nginx/certs/tls-key.key;
ssl_client_certificate /etc/nginx/certs/client-ca.crt;
ssl_session_cache shared:SSL:10m;
ssl_verify_client on;
proxy_pass 10.0.0.8:1883;
proxy_connect_timeout 1s;
mqtt_set_connect clientid $ssl_client_serial;
}
}Certificat client comme identifiant d’authentification
Une approche courante pour authentifier les clients MQTT consiste à utiliser comme nom d’utilisateur les données stockées dans un certificat client. NGINX Plus peut analyser les certificats clients et réécrire le champ du nom d’utilisateur MQTT, déchargeant ainsi les courtiers backend de cette tâche. Dans l’exemple suivant, nous extrayons le nom distinctif du sujet (Subject DN) du certificat client et le copions dans la partie réservée au nom d’utilisateur d’un message MQTT CONNECT.
stream { mqtt on;
server {
listen 8883 ssl;
ssl_certificate /etc/nginx/certs/tls-cert.crt;
ssl_certificate_key /etc/nginx/certs/tls-key.key;
ssl_client_certificate /etc/nginx/certs/client-ca.crt;
ssl_session_cache shared:SSL:10m;
ssl_verify_client on;
proxy_pass 10.0.0.8:1883;
proxy_connect_timeout 1s;
mqtt_set_connect username $ssl_client_s_dn;
}
} Pour consulter les spécifications complètes relatives à la réécriture des messages MQTT CONNECT dans NGINX Plus, reportez-vous aux spécifications du module « ngx_stream_mqtt_filter_module ».
Commencez dès aujourd’hui
Les futures évolutions de MQTT dans NGINX Plus pourraient inclure l’analyse d’autres types de messages MQTT, ainsi qu’une analyse plus approfondie du message CONNECT afin de permettre des fonctionnalités telles que :
- Mécanismes supplémentaires d’authentification et de contrôle d’accès
- Protéger les brokers en limitant le débit des clients « bavards »
- Télémétrie des messages et métriques de connexion
Si vous découvrez NGINX Plus, inscrivez-vous pour bénéficier d’un essai gratuit de 30 jours afin de commencer à utiliser MQTT. Nous aimerions également connaître votre avis sur les fonctionnalités qui comptent le plus pour vous. Dites-nous ce que vous en pensez dans les commentaires.
Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.