Cuando anunciamos la versión R29 de NGINX Plus, abordamos brevemente su nueva compatibilidad nativa con el análisis de mensajes MQTT. En este artículo, profundizaremos en ello y explicaremos cómo se puede configurar NGINX Plus para optimizar las implementaciones de MQTT en entornos empresariales.
¿Qué es MQTT?
MQTT son las siglas de «Message Queuing Telemetry Transport» (transporte de telemetría mediante colas de mensajes). Es un protocolo de mensajería de publicación-suscripción muy popular y ligero, ideal para conectar a través de Internet dispositivos y aplicaciones del Internet de las cosas (IoT) o de comunicación máquina a máquina (M2M). MQTT está diseñado para funcionar de forma eficiente en entornos con poco ancho de banda o bajo consumo energético, por lo que resulta idóneo para aplicaciones con un gran número de clientes remotos. Se utiliza en diversos sectores, como la electrónica de consumo, la automoción, el transporte, la fabricación y la sanidad.
Procesamiento de mensajes MQTT con NGINX Plus
NGINX Plus R29 es compatible con MQTT 3.1.1 y MQTT 5.0. Actúa como proxy entre clientes y brókeres, descargando tareas de los sistemas centrales, facilitando la escalabilidad y reduciendo los costes de computación. En concreto, NGINX Plus analiza y reescribe partes de los mensajes CONNECT de MQTT, lo que permite funciones como:
- Equilibrado de carga de los brokers MQTT
- Persistencia de sesión (reconexión de los clientes al mismo bróker)
- Terminación SSL/TLS
- Autenticación mediante certificado de cliente
Las directivas de procesamiento de mensajes MQTT deben definirse en el contexto stream de un archivo de configuración de NGINX y las proporcionan los módulos ngx_stream_mqtt_preread_module
y ngx_stream_mqtt_filter_module.
El módulo preread procesa los datos MQTT antes de que NGINX realice el proxy interno, lo que permite tomar decisiones de equilibrio de carga y enrutamiento ascendente basadas en los datos analizados del mensaje.
El módulo filter permite reescribir los campos clientid, username y password de los mensajes CONNECT recibidos. La posibilidad de asignar variables y valores complejos a estos campos amplía considerablemente las opciones de configuración, lo que permite a NGINX Plus ocultar información confidencial del dispositivo o insertar datos como el nombre distintivo de un certificado TLS.
Directivas y variables de MQTT
Ahora dispone de varias directivas y variables integradas nuevas para ajustar la configuración de NGINX, optimizar las implementaciones de MQTT y satisfacer sus necesidades específicas.
Directivas y variables integradas del módulo Preread
mqtt_preread– Habilita el análisis de MQTT y extrae los camposclientidyusernamede los mensajes CONNECT enviados por los dispositivos cliente. Estos valores están disponibles mediante variables integradas y permiten distribuir las sesiones mediante hash entre servidores ascendentes con balanceo de carga (véanse los ejemplos a continuación).$mqtt_preread_clientid– Representa el identificador de cliente MQTT enviado por el dispositivo.$mqtt_preread_username– Representa el nombre de usuario enviado por el cliente con fines de autenticación.
Directivas del módulo de filtrado
mqtt– Define si la reescritura de MQTT está habilitada.mqtt_buffers– Anula el número máximo de búferes de procesamiento MQTT que se pueden asignar por conexión y el tamaño de cada búfer. De forma predeterminada, NGINX establece un límite de 100 búferes por conexión, cada uno con un tamaño de 1 KB. Por lo general, esta configuración ofrece un rendimiento óptimo, aunque puede ser necesario ajustarla en situaciones especiales. Por ejemplo, los mensajes MQTT más largos requieren un búfer de mayor tamaño. Los sistemas que procesan un mayor volumen de mensajes MQTT para una conexión determinada en un breve periodo de tiempo pueden beneficiarse de un mayor número de búferes. En la mayoría de los casos, el ajuste de los parámetros de los búferes apenas afecta al rendimiento subyacente del sistema, ya que NGINX crea los búferes a partir de un pool de memoria interno.mqtt_rewrite_buffer_size– Especifica el tamaño del búfer utilizado para crear mensajes MQTT. Esta directiva está obsoleta y dejó de utilizarse a partir de NGINX Plus R30.mqtt_set_connect– Reescribe los parámetros del mensaje CONNECT enviado desde un cliente. Los parámetros admitidos son:clientid,usernameypassword.
Ejemplos de MQTT
Analicemos con más detalle las ventajas de procesar mensajes MQTT con NGINX Plus y las prácticas recomendadas asociadas. Tenga en cuenta que en los siguientes ejemplos utilizamos los puertos 1883 y 8883. El puerto 1883 es el puerto MQTT predeterminado sin protección, mientras que el 8883 es el puerto predeterminado cifrado mediante SSL/TLS.
Equilibrado de carga de brokers MQTT
La naturaleza efímera de los dispositivos MQTT puede hacer que las direcciones IP de los clientes cambien de forma inesperada. Esto puede plantear dificultades a la hora de dirigir las conexiones de los dispositivos al bróker ascendente correcto. El posterior traslado de las conexiones de los dispositivos de un bróker ascendente a otro puede dar lugar a costosas operaciones de sincronización entre brókeres, lo que aumenta la latencia y los costes.
Al analizar el campo clientid de un mensaje MQTT CONNECT, NGINX puede establecer sesiones persistentes con los brókeres de servicios ascendentes. Esto se consigue utilizando el clientid como clave hash para mantener las conexiones con los servicios de bróker del backend.
En este ejemplo, usamos un proxy para los datos de dispositivos MQTT y utilizamos el clientid como token para establecer sesiones persistentes con tres brókeres ascendentes. Usamos el parámetro consistent para que, si falla un servidor ascendente, su parte del tráfico se distribuya uniformemente entre los servidores restantes sin afectar a las sesiones ya establecidas en ellos.
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 también puede analizar el campo de nombre de usuario de un mensaje CONNECT de MQTT. Para obtener más información, consulte la especificación de ngx_stream_mqtt_preread_module specification.
Terminación SSL/TLS
Cifrar las comunicaciones de los dispositivos es fundamental para garantizar la confidencialidad de los datos y protegerlos frente a ataques de intermediario. Sin embargo, el protocolo de enlace, el cifrado y el descifrado TLS pueden suponer una carga considerable para los recursos de un bróker MQTT. Para solucionarlo, NGINX Plus puede descargar al bróker (o clúster de brókeres) de las tareas de cifrado de datos, lo que simplifica las reglas de seguridad y permite que los brókeres se centren en procesar los mensajes de los dispositivos.
En este ejemplo, mostramos cómo se puede utilizar NGINX como proxy del tráfico MQTT cifrado mediante TLS entre los dispositivos y un bróker de backend. La directiva ssl_session_cache define una caché de 5 megabytes, suficiente para almacenar aproximadamente 20 000 sesiones SSL. NGINX intentará conectarse al bróker configurado mediante proxy durante cinco segundos antes de que se agote el tiempo de espera, según lo definido por la directiva 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;
}
} Sustitución del ID de cliente
Por motivos de seguridad, puede optar por no almacenar información que permita identificar al cliente en la base de datos del bróker MQTT. Por ejemplo, un dispositivo puede enviar un número de serie u otros datos confidenciales como parte de un mensaje MQTT CONNECT. Al sustituir el identificador de un dispositivo por otros valores estáticos conocidos recibidos de un cliente, se puede establecer una clave única alternativa para cada dispositivo que intente acceder a los brókeres con proxy de NGINX Plus.
En este ejemplo, extraemos un identificador único del certificado SSL de cliente de un dispositivo y lo utilizamos para ocultar su ID de cliente MQTT. La autenticación mediante certificado de cliente (TLS mutuo) se controla con la directiva ssl_verify_client. Cuando se establece en el parámetro on, NGINX garantiza que los certificados de cliente estén firmados por una autoridad de certificación (CA) de confianza. La lista de certificados de CA de confianza se define mediante la directiva 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;
}
}Certificado de cliente como credencial de autenticación
Un enfoque habitual para autenticar clientes MQTT consiste en utilizar como nombre de usuario los datos almacenados en un certificado de cliente. NGINX Plus puede analizar los certificados de cliente y reescribir el campo de nombre de usuario de MQTT, liberando de esta tarea a los brókeres de backend. En el siguiente ejemplo, extraemos el nombre distinguido del sujeto (Subject DN) del certificado de cliente y lo copiamos en la parte correspondiente al nombre de usuario de un mensaje CONNECT de MQTT.
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;
}
} Para consultar la especificación completa sobre la reescritura de mensajes MQTT CONNECT en NGINX Plus, consulte la especificación de ngx_stream_mqtt_filter_module specification.
Empieza hoy mismo
Los futuros desarrollos de MQTT en NGINX Plus podrían incluir el análisis de otros tipos de mensajes MQTT, así como un análisis más exhaustivo del mensaje CONNECT para habilitar funciones como:
- Mecanismos adicionales de autenticación y control de acceso
- Protección de los brokers mediante la limitación de la tasa de los clientes «parlanchines»
- Telemetría de mensajes y métricas de conexión
Si aún no conoces NGINX Plus, regístrate para disfrutar de una prueba gratuita de 30 días y empezar a utilizar MQTT. También nos encantaría conocer tu opinión sobre las funciones que más te importan. Cuéntanos qué te parece en los comentarios.
Artículos relacionados del blog
Únete a F5 NGINX en AppWorld 2024
Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.
Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.
Exposición de APIs en Kubernetes
La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».
NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.
Presentamos NGINX Plus R22
NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.
Presentamos NGINX Plus R17
NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.