BLOG | NGINX

Optimisation des déploiements MQTT dans les environnements d'entreprise avec NGINX Plus

NGINX-Partie-de-F5-horiz-black-type-RGB
Miniature de Michael Vernik
Michel Vernik
Publié le 05 juin 2023
Vignette de Prabhat Dixit
Prabhat Dixit
Publié le 05 juin 2023

Lors de l'annonce de la version R29 de NGINX Plus , nous avons brièvement abordé sa nouvelle prise en charge native de l'analyse des messages MQTT . Dans cet article, nous nous appuierons sur cela et discuterons de la manière dont NGINX Plus peut être configuré pour 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 de publication-abonnement léger et très populaire, idéal pour connecter des appareils et des applications de l'Internet des objets (IoT) ou de machine à machine (M2M) via Internet. MQTT est conçu pour fonctionner efficacement dans des environnements à faible bande passante ou à faible consommation, ce qui en fait un choix idéal pour les applications avec un grand nombre de clients distants. Il est utilisé dans de nombreux secteurs, notamment l’électronique grand public, l’automobile, les transports, la fabrication et les soins de santé.

Traitement des messages MQTT NGINX Plus

NGINX Plus R29 prend en charge MQTT 3.1.1 et MQTT 5.0 . Il agit comme un proxy entre les clients et les courtiers, déchargeant les tâches des systèmes principaux, simplifiant l'évolutivité et réduisant les coûts de calcul. Plus précisément, NGINX Plus analyse et réécrit des parties des messages MQTT CONNECT , permettant des fonctionnalités telles que :

  • Équilibrage de charge du courtier MQTT 
  • Persistance de session (reconnexion des clients au même courtier) 
  • Terminaison SSL/TLS 
  • Authentification par certificat client 

Les directives de traitement des messages MQTT doivent être définies dans le contexte de flux d'un fichier de configuration NGINX et sont fournies par le module ngx_stream_mqtt_preread_module
et ngx_stream_mqtt_filter_module .

Le module de prélecture traite les données MQTT avant 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 de filtrage permet de réécrire les champs clientid , username et password dans les messages CONNECT reçus. La possibilité de définir ces champs sur des variables et des valeurs complexes étend considérablement les options de configuration, permettant à NGINX Plus de masquer les informations sensibles de l'appareil ou d'insérer des données comme un nom distinctif de certificat TLS.

Directives et variables MQTT

Plusieurs nouvelles directives et variables intégrées sont désormais disponibles pour optimiser votre configuration NGINX afin d'optimiser les déploiements MQTT et de répondre à vos besoins spécifiques.

Directives de module de prélecture et variables intégrées

  • mqtt_preread – Active l’analyse MQTT, en extrayant les champs clientid et username des messages CONNECT envoyés par les périphériques clients. Ces valeurs sont rendues disponibles via des variables intégrées et aident à hacher les sessions pour équilibrer la charge des serveurs en amont (exemples ci-dessous).
  • $mqtt_preread_clientid – Représente l’identifiant 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 – Définit si la réécriture MQTT est activée.
  • mqtt_buffers – Remplace le nombre maximal de tampons de traitement MQTT qui peuvent être alloués par connexion et la taille de chaque tampon. Par défaut, NGINX imposera une limite de 100 tampons par connexion, chacun d'une longueur de 1 ko. En général, cela est optimal pour les performances, mais peut nécessiter un réglage dans des situations particulières. Par exemple, les messages MQTT plus longs nécessitent une taille de mémoire tampon plus grande. Les systèmes traitant un volume plus important de messages MQTT pour une connexion donnée dans un court laps de temps peuvent bénéficier d'un nombre accru de tampons. Dans la plupart des cas, le réglage des paramètres du tampon a peu d’incidence sur les performances du système sous-jacent, car NGINX construit des tampons à partir d’un pool de mémoire interne.
  • mqtt_rewrite_buffer_size – Spécifie la taille du tampon utilisé pour la construction des messages MQTT. Cette directive est 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 incluent : clientid , username et password .

Exemples MQTT

Explorons plus en détail les avantages du traitement des messages MQTT avec NGINX Plus et les meilleures 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 8883 est le port crypté SSL/TLS par défaut.

Équilibrage de charge du courtier MQTT

La nature éphémère des appareils MQTT peut entraîner des modifications inattendues des adresses IP des clients. Cela peut créer des défis lors du routage des connexions des appareils vers le courtier en amont approprié. Le déplacement ultérieur des connexions des appareils d'un courtier en amont vers un autre peut entraîner des opérations de synchronisation coûteuses entre les courtiers, ajoutant de la latence et des coûts.

En analysant le champ clientid dans un message MQTT CONNECT, NGINX peut établir des sessions persistantes avec les courtiers de services en amont. Ceci est réalisé en utilisant le clientid comme clé de hachage pour maintenir les connexions aux services de courtage sur le backend.

Dans cet exemple, nous proxyons les données du périphérique MQTT en utilisant le clientid comme jeton pour établir des sessions persistantes avec trois courtiers en amont. Nous utilisons le paramètre cohérent afin que si un serveur en amont tombe en panne, sa part du trafic soit répartie uniformément sur les serveurs restants sans affecter les sessions déjà établies sur ces serveurs.

stream {     mqtt_preread on; 
   
    backend en amont {
        zone tcp_mem 64k;
        hachage $mqtt_preread_clientid consistent;
  
        serveur 10.0.0.7:1883; # courtier mqtt en amont 1
        serveur 10.0.0.8:1883; # courtier mqtt en amont 2
        serveur 10.0.0.9:1883; # courtier mqtt en amont 3
    }
  
    serveur {
        écoute 1883;
        proxy_pass backend;
       proxy_connect_timeout 1s;
    }
}

NGINX Plus peut également analyser le champ de nom d'utilisateur d'un message MQTT CONNECT. Pour plus de détails, consultez la spécification ngx_stream_mqtt_preread_module

Résiliation SSL/TLS

Le chiffrement des communications entre appareils est essentiel pour garantir la confidentialité des données et se protéger contre les attaques de type « man-in-the-middle ». Cependant, l'établissement de liaison TLS, le chiffrement et le déchiffrement peuvent représenter une charge de ressources pour un courtier MQTT. Pour résoudre ce problème, NGINX Plus peut décharger le cryptage des données d'un courtier (ou d'un cluster de courtiers), simplifiant ainsi les règles de sécurité et permettant aux courtiers de se concentrer sur le traitement des messages des appareils. 

Dans cet exemple, nous montrons comment NGINX peut être utilisé pour acheminer le trafic MQTT chiffré TLS des appareils vers un courtier backend. La directive ssl_session_cache définit un cache de 5 mégaoctets, ce qui est suffisant pour stocker environ 20 000 sessions SSL. NGINX tentera d'atteindre le courtier proxy pendant cinq secondes avant l'expiration du délai, comme défini par la directive proxy_connect_timeout .

flux {     serveur {
        écoute 8883 ssl ;
        certificat_ssl /etc/nginx/certs/tls-cert.crt ;
        clé_certificat_ssl /etc/nginx/certs/tls-key.key ;
        cache_session_ssl partagé : SSL : 5 m ;
        proxy_pass 10.0.0.8 : 1883 ;
        proxy_connect_timeout 5 s ;
    }
} 

Substitution d'identifiant client

Pour des raisons de sécurité, vous pouvez choisir de ne pas stocker d’informations identifiables par le client dans la base de données du courtier 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, une clé unique alternative peut être établie pour chaque appareil tentant d’atteindre les courtiers proxy NGINX Plus.

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 ce paramètre est défini sur on, NGINX garantit que les certificats clients sont signés par une autorité de certification (CA) de confiance. La liste des certificats d'autorité de certification de confiance est définie par la directive ssl_client_certificate

flux {     mqtt activé ; 
  
    serveur {
        écoute 8883 ssl ;
        certificat_ssl /etc/nginx/certs/tls-cert.crt ;
        clé_certificat_ssl /etc/nginx/certs/tls-key.key ;
        certificat_client_ssl /etc/nginx/certs/client-ca.crt ;
        cache_session_ssl partagé : SSL : 10 m ;
        vérification_client_ssl activée ;
        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 les données stockées dans un certificat client comme nom d’utilisateur. NGINX Plus peut analyser les certificats clients et réécrire le champ du nom d'utilisateur MQTT, déchargeant ainsi cette tâche des courtiers back-end. Dans l’exemple suivant, nous extrayons le nom distinctif du sujet (Subject DN) du certificat client et le copions dans la partie nom d’utilisateur d’un message MQTT CONNECT.

flux {     mqtt activé ; 
   
    serveur {
        écoute 8883 ssl ;
        certificat_ssl /etc/nginx/certs/tls-cert.crt ;
        clé_certificat_ssl /etc/nginx/certs/tls-key.key ;
        certificat_client_ssl /etc/nginx/certs/client-ca.crt ;
        cache_session_ssl partagé : SSL : 10 m ;
        vérification_client_ssl activée ;
        proxy_pass 10.0.0.8 : 1883 ;
       proxy_connect_timeout 1s;
        
        mqtt_set_connect nom d'utilisateur $ssl_client_s_dn;
    }
} 

Pour une spécification complète sur la réécriture des messages NGINX Plus MQTT CONNECT, consultez la spécification ngx_stream_mqtt_filter_module .

Commencez dès aujourd'hui

Les développements futurs de MQTT dans NGINX Plus peuvent inclure l'analyse d'autres types de messages MQTT, ainsi qu'une analyse plus approfondie du message CONNECT pour activer des fonctions telles que :

  • Mécanismes supplémentaires d'authentification et de contrôle d'accès
  • Protéger les courtiers en limitant les tarifs des clients « bavards »
  • Télémétrie des messages et mesures de connexion

Si vous êtes nouveau sur NGINX Plus, inscrivez-vous pour un essai gratuit de 30 jours pour démarrer avec 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.


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."