Bei der Ankündigung von R29 von NGINX Plus, haben wir kurz die neue native Unterstützung für das Parsen von MQTT-Nachrichten vorgestellt. In diesem Beitrag knüpfen wir daran an und erläutern, wie NGINX Plus konfiguriert werden kann, um MQTT-Bereitstellungen in Unternehmensumgebungen zu optimieren.
Was ist MQTT?
MQTT steht für Message Queuing Telemetry Transport. Es ist ein sehr beliebtes, schlankes Publish-Subscribe-Nachrichtenprotokoll, das sich ideal eignet, um Geräte und Anwendungen aus dem Internet der Dinge (IoT) oder für die Maschine-zu-Maschine-Kommunikation (M2M) über das Internet zu verbinden. MQTT ist für den effizienten Betrieb in Umgebungen mit geringer Bandbreite oder niedrigem Energieverbrauch ausgelegt und daher die ideale Wahl für Anwendungen mit einer großen Anzahl von Remote-Clients. Es kommt in zahlreichen Branchen zum Einsatz, darunter Unterhaltungselektronik, Automobilindustrie, Transportwesen, Fertigung und Gesundheitswesen.
NGINX Plus MQTT-Nachrichtenverarbeitung
NGINX Plus R29 unterstützt MQTT 3.1.1 und MQTT 5.0. Es fungiert als Proxy zwischen Clients und Brokern, entlastet Kernsysteme, vereinfacht die Skalierung und senkt die Rechenkosten. Insbesondere analysiert und überschreibt NGINX Plus Teile von MQTT-CONNECT-Nachrichten und ermöglicht so Funktionen wie:
- Lastverteilung für MQTT-Broker
- Sitzungspersistenz (erneute Verbindung von Clients mit demselben Broker)
- SSL/TLS-Terminierung
- Client-Zertifikatsauthentifizierung
Direktiven zur Verarbeitung von MQTT-Nachrichten müssen im stream-Kontext einer NGINX-Konfigurationsdatei definiert werden und werden durch die Module ngx_stream_mqtt_preread_module
und ngx_stream_mqtt_filter_module bereitgestellt.
Das preread-Modul verarbeitet MQTT-Daten vor der internen Proxy-Verarbeitung durch NGINX, sodass Entscheidungen über die Lastverteilung und das Upstream-Routing auf Grundlage der analysierten Nachrichtendaten getroffen werden können.
Das filter-Modul ermöglicht das Umschreiben der Felder clientid, username und password in empfangenen CONNECT-Nachrichten. Da diese Felder auf Variablen und komplexe Werte gesetzt werden können, erweitern sich die Konfigurationsmöglichkeiten erheblich. So kann NGINX Plus vertrauliche Geräteinformationen maskieren oder Daten wie den Distinguished Name eines TLS-Zertifikats einfügen.
MQTT-Direktiven und -Variablen
Für die Feinabstimmung Ihrer NGINX-Konfiguration stehen jetzt mehrere neue Direktiven und eingebettete Variablen zur Verfügung, mit denen Sie MQTT-Bereitstellungen optimieren und an Ihre spezifischen Anforderungen anpassen können.
Direktiven und eingebettete Variablen des Preread-Moduls
mqtt_preread– Aktiviert das MQTT-Parsing und extrahiert die Felderclientidundusernameaus CONNECT-Nachrichten, die von Clientgeräten gesendet werden. Diese Werte werden über eingebettete Variablen bereitgestellt und ermöglichen es, Sitzungen per Hash auf Upstream-Server mit Lastverteilung zu verteilen (Beispiele siehe unten).$mqtt_preread_clientid– Stellt die vom Gerät gesendete MQTT-Client-ID dar.$mqtt_preread_username– Steht für den Benutzernamen, den der Client zu Authentifizierungszwecken sendet.
Direktiven des Filtermoduls
mqtt– Legt fest, ob das Umschreiben von MQTT aktiviert ist.mqtt_buffers– Überschreibt die maximale Anzahl der MQTT-Verarbeitungspuffer, die pro Verbindung zugewiesen werden können, sowie die Größe der einzelnen Puffer. Standardmäßig legt NGINX ein Limit von 100 Puffern pro Verbindung mit einer Größe von jeweils 1 KB fest. Dies ist in der Regel optimal für die Leistung, kann jedoch in besonderen Situationen eine Anpassung erfordern. Beispielsweise ist für längere MQTT-Nachrichten ein größerer Puffer erforderlich. Bei Systemen, die innerhalb kurzer Zeit eine größere Menge an MQTT-Nachrichten für eine bestimmte Verbindung verarbeiten, kann eine höhere Anzahl von Puffern von Vorteil sein. In den meisten Fällen hat die Anpassung der Pufferparameter nur geringe Auswirkungen auf die zugrunde liegende Systemleistung, da NGINX die Puffer aus einem internen Speicherpool erstellt.mqtt_rewrite_buffer_size– Gibt die Größe des Puffers an, der zum Erstellen von MQTT-Nachrichten verwendet wird. Diese Direktive ist veraltet und wird seit NGINX Plus R30 nicht mehr verwendet.mqtt_set_connect– Schreibt Parameter der von einem Client gesendeten CONNECT-Nachricht um. Zu den unterstützten Parametern gehören:clientid,usernameundpassword.
MQTT-Beispiele
Sehen wir uns die Vorteile der Verarbeitung von MQTT-Nachrichten mit NGINX Plus und die damit verbundenen Best Practices genauer an. Beachten Sie, dass wir in den folgenden Beispielen die Ports 1883 und 8883 verwenden. Port 1883 ist der ungesicherte Standardport für MQTT, während Port 8883 standardmäßig mit SSL/TLS verschlüsselt ist.
Lastverteilung für MQTT-Broker
Aufgrund der kurzlebigen Verbindungen von MQTT-Geräten können sich Client-IP-Adressen unerwartet ändern. Dies kann die Weiterleitung von Geräteverbindungen an den richtigen Upstream-Broker erschweren. Werden Geräteverbindungen daraufhin von einem Upstream-Broker zu einem anderen verschoben, kann dies aufwendige Synchronisierungsvorgänge zwischen den Brokern auslösen und so die Latenz und die Kosten erhöhen.
Durch das Parsen des Feldes „clientid“ in einer MQTT-CONNECT-Nachricht kann NGINX persistente Sitzungen mit vorgelagerten Service-Brokern einrichten. Dazu wird die „clientid“ als Hash-Schlüssel verwendet, um Verbindungen zu Broker-Diensten im Backend aufrechtzuerhalten.
In diesem Beispiel leiten wir MQTT-Gerätedaten über einen Proxy weiter und verwenden die clientid als Token, um persistente Sitzungen mit drei Upstream-Brokern einzurichten. Wir verwenden den Parameter „consistent“, damit bei Ausfall eines Upstream-Servers dessen Anteil am Datenverkehr gleichmäßig auf die verbleibenden Server verteilt wird, ohne die bereits auf diesen Servern eingerichteten Sitzungen zu beeinträchtigen.
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 kann auch das Feld für den Benutzernamen einer MQTT-CONNECT-Nachricht analysieren. Weitere Informationen finden Sie in der Spezifikation des Moduls „ngx_stream_mqtt_preread_module“.
SSL/TLS-Terminierung
Die Verschlüsselung der Gerätekommunikation ist entscheidend, um die Vertraulichkeit der Daten zu gewährleisten und Man-in-the-Middle-Angriffe abzuwehren. TLS-Handshakes sowie die Ver- und Entschlüsselung können jedoch die Ressourcen eines MQTT-Brokers stark beanspruchen. Um dieses Problem zu lösen, kann NGINX Plus die Datenverschlüsselung von einem Broker (oder einem Broker-Cluster) übernehmen. Dadurch werden Sicherheitsregeln vereinfacht und die Broker können sich auf die Verarbeitung von Gerätenachrichten konzentrieren.
In diesem Beispiel zeigen wir, wie NGINX verwendet werden kann, um TLS-verschlüsselten MQTT-Datenverkehr von Geräten an einen Backend-Broker weiterzuleiten. Die Direktive „ssl_session_cache“ definiert einen 5 Megabyte großen Cache, der für etwa 20.000 SSL-Sitzungen ausreicht. NGINX versucht fünf Sekunden lang, den per Proxy angebundenen Broker zu erreichen, bevor eine Zeitüberschreitung eintritt, wie durch die Direktive „proxy_connect_timeout“ festgelegt.
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;
}
} Client-ID-Ersetzung
Aus Sicherheitsgründen können Sie darauf verzichten, Informationen, anhand derer ein Client identifiziert werden kann, in der Datenbank des MQTT-Brokers zu speichern. Beispielsweise kann ein Gerät im Rahmen einer MQTT-CONNECT-Nachricht eine Seriennummer oder andere sensible Daten senden. Indem die Kennung eines Geräts durch andere bekannte statische Werte ersetzt wird, die von einem Client empfangen wurden, lässt sich für jedes Gerät, das versucht, über NGINX Plus auf die per Proxy angebundenen Broker zuzugreifen, ein alternativer eindeutiger Schlüssel festlegen.
In diesem Beispiel extrahieren wir eine eindeutige Kennung aus dem Client-SSL-Zertifikat eines Geräts und verwenden sie, um dessen MQTT-Client-ID zu maskieren. Die Clientzertifikatsauthentifizierung (gegenseitiges TLS) wird mit der Direktive „ssl_verify_client“ gesteuert. Wenn sie auf den Parameter „on“ gesetzt ist, stellt NGINX sicher, dass die Clientzertifikate von einer vertrauenswürdigen Zertifizierungsstelle (CA) signiert wurden. Die Liste der vertrauenswürdigen CA-Zertifikate wird durch die Direktive „ssl_client_certificate“ festgelegt.
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;
}
}Clientzertifikat als Authentifizierungsnachweis
Ein gängiger Ansatz zur Authentifizierung von MQTT-Clients besteht darin, in einem Clientzertifikat gespeicherte Daten als Benutzernamen zu verwenden. NGINX Plus kann Clientzertifikate analysieren und das MQTT-Benutzernamenfeld umschreiben, sodass diese Aufgabe nicht von den Backend-Brokern übernommen werden muss. Im folgenden Beispiel extrahieren wir den Distinguished Name des Zertifikatsinhabers (Subject DN) aus dem Clientzertifikat und kopieren ihn in den Benutzernamenteil einer MQTT-CONNECT-Nachricht.
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;
}
} Eine vollständige Spezifikation zum Umschreiben von MQTT-CONNECT-Nachrichten mit NGINX Plus finden Sie in der Spezifikation des Moduls „ngx_stream_mqtt_filter_module“.
Starten Sie noch heute
Zukünftige Weiterentwicklungen von MQTT in NGINX Plus könnten das Parsen weiterer MQTT-Nachrichtentypen sowie eine tiefergehende Analyse der CONNECT-Nachricht umfassen, um Funktionen wie die folgenden zu ermöglichen:
- Zusätzliche Authentifizierungs- und Zugriffskontrollmechanismen
- Schutz von Brokern durch Ratenbegrenzung für „kommunikationsintensive“ Clients
- Nachrichtentelemetrie und Verbindungsmetriken
Wenn Sie NGINX Plus noch nicht kennen, melden Sie sich für eine kostenlose 30-tägige Testversion an, um mit MQTT loszulegen. Wir würden uns außerdem über Ihr Feedback dazu freuen, welche Funktionen Ihnen am wichtigsten sind. Teilen Sie uns Ihre Meinung in den Kommentaren mit.
Ähnliche Blogbeiträge
Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.
Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.
Ankündigung von NGINX Plus R16
NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.
5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.