Trasciende la pila con el protocolo de red adecuado

El auge de los dispositivos en red en los últimos años ha sido una especie de arma de doble filo. Si bien, por un lado, es realmente bueno tener un método sencillo y directo para hablar con los dispositivos, esto también conlleva muchas complicaciones, principalmente relacionadas con la confiabilidad y la seguridad.

Con WiFi, la integración de nuevos dispositivos en la red es mucho más difícil que con Ethernet o CAN, y la seguridad (por ejemplo, WPA y TLS) ya no es opcional, ya que el acceso físico a la red ya no puede estar restringido. Agregue a esto los problemas confiables debido a la interferencia de las redes WiFi cercanas de la competencia y otras fuentes de ruido electromagnético, y las cosas se complican mucho incluso antes de considerar qué protocolo de comunicación de nivel superior usar.

En este artículo, analizaremos la implementación de un sistema basado en red de este tipo, la protección de una red WiFi a través de TLS y el uso de MQTT en combinación con un proxy. Ilustraré esto con experiencias y lecciones aprendidas mientras trabajaba en este proyecto de Construcción y Control (BMaC), que discutí en un artículo anterior.

Ingrese MQTT en su sistema

Message Queue Server Telemetry Transport (MQTT) es un pequeño protocolo binario desarrollado por Andy Stanford-Clark de IBM y Arlen Nipper de Cirrus Link en 1999. Su versión 3.1 fue enviada en 2013 por IBM a OASIS para su estandarización. Otra versión de MQTT es MQTT-SN, que está diseñada para anchos de banda más pequeños, no para redes TCP, como Zigbee, UDP y Bluetooth.

Debido a su tamaño compacto y arquitectura simple cliente-servidor, es muy adecuado para conectar más y más pequeñas redes de sensores, especialmente en situaciones con alta latencia y bajo ancho de banda. Utiliza un modelo de publicación por suscripción en el que los clientes pueden suscribirse a temas sobre los que otros pueden publicar mensajes. Estos mensajes pueden ser persistentes, garantizar la entrega y (a partir de la versión 5) pueden caducar automáticamente si no se pueden entregar.

La ventaja obvia de MQTT es que admite todo, desde clientes de Internet de banda ancha siempre hasta nodos de sensores remotos de baja potencia que solo se despiertan semanalmente, marcan en un enlace satelital y envían algunas lecturas de sensores mientras actualizan sus configuraciones de calibración. de datos que reciben al mismo tiempo de algún otro cliente.

El uso de MQTT (con el broker Mosquitto MQTT) en el proyecto BMaC fue inicialmente más que una coincidencia, usándolo principalmente porque un cliente MQTT ya estaba integrado en el marco que usamos en los microcontroladores. Ninguno de nosotros ha pensado realmente en los pros o los contras de MQTT sobre ninguna alternativa. Ahora, años después, es fácil ver por qué MQTT fue la elección correcta. Si bien lo operamos a través de una red interna basada en TCP, obtuvimos el aspecto de entrega garantizada de TCP junto con su control de suma de verificación incorporado, y el protocolo MQTT en sí no pone límites a la carga útil que puede transportar, ya sea de texto. basado. o binario.

No existe una competencia real para MQTT. AMQP también es bastante popular, pero está dirigido a sistemas de escritorio y servidores en configuración empresarial, y no se reduce realmente a microcontroladores de 8 bits con RAM limitada. Además, AMQP también define un esquema de codificación para la carga útil, mientras que MQTT deja a uno libre para usar cualquier esquema de codificación o serial que desee usar.

Con BMaC podríamos desarrollar nuestro propio formato de carga útil que se enviaría desde y hacia los nodos basados ​​en ESP8266. Esto dio como resultado un formato binario compacto que usa solo unos pocos bytes, lo que fue suficiente para configurar nodos sobre MQTT y también para ajustar la configuración del ventilador y el relé.

Asegurar el sistema

La mejor forma de proteger un sistema es mediante una práctica de seguridad profunda. Esto significa que todas las partes explotables deben asegurarse de alguna manera. Suponiendo un sistema como el de BMaC, esto significa que el hardware físico está completamente dentro de un edificio de oficinas que tiene su propio sistema de seguridad instalado.

Este sistema de seguridad puede ser una simple llave mecánica o algún sistema basado en etiquetas NFC. Las áreas sensibles, como las salas de servidores, requieren sus propias claves de acceso o permisos asociados con las etiquetas NFC. Esto prácticamente elimina cualquier riesgo de que personas no autorizadas accedan al hardware, y mucho menos de realizar actos maliciosos.

Las redes inalámbricas para un sistema de este tipo están, por supuesto, protegidas por WPA2 o similar, lo que significa que sin la contraseña o el certificado correctos, no se puede conectar a la red inalámbrica. Por tanto, todo el tráfico de la red se cifrará. Esto cambia la amenaza más probable para aquellos que de alguna manera obtuvieron acceso a la red, ya sea a través de medios legales, o porque el SSID WiFi y la contraseña estaban en una foto que apareció en el blog de una empresa pública (historia real).

En este punto tenemos un buen nivel de seguridad, pero el ingrediente que falta es asegurar el tráfico entre los nodos y los servidores backend, lo que significa cifrado TLS (muy común) o Criptografía de curva elíptica (ECC), que sería la parte superior. opción porque es más rápido, requiere mucha menos RAM y tiene certificados mucho más pequeños. Desafortunadamente, ECC ha tomado el asiento trasero de TLS, en gran parte porque está bloqueado por patente durante mucho más tiempo.

Esto hizo que TLS fuera el tipo más fácil de integrar en el proyecto BMaC, ya que agregar ECC significaría dejar la biblioteca axTLS en el marco que usamos para los nodos ESP8266 e integrar una biblioteca alternativa que admita ECC y que también coincida con la RAM limitada proporcionada. con este microcontrolador.

La parte donde las cosas explotan

Rápidamente aprendimos que el protocolo de enlace predeterminado en el cifrado TLS para conexiones TCP causa problemas masivos para ESP8266 y MCU similares, que tienden a tener menos de 30 kB de SRAM disponibles cuando se produce este enlace.

La configuración predeterminada de TLS dicta, a saber, que los tamaños máximos de búfer TX / RX se asignan cuando se intenta una conexión segura, siendo 16 kB cada uno o un total de 32 kB. Con un firmware insignificante, esto da como resultado que la MCU se quede sin memoria y la MCU se restaure. Afortunadamente, esta configuración se puede cambiar en el lado del servidor, como se indica en este artículo sobre TLS. Esto permitiría al servidor establecer el tamaño del búfer TLS en algo que se ajuste a la SRAM de la MCU.

Desafortunadamente para BMaC, el servidor del broker Mosquitto MQTT no tenía esto como una configuración personalizada, requiriendo que lo cambiemos en el código fuente y compilemos el servidor. Eso pareció demasiado.

En su lugar, optamos por agregar otro punto final TLS al sistema, utilizando HAProxy como intermedio. Configuramos una interfaz con solo acceso TLS, que simplemente dirige algunos datos descifrados a Mosquitto a través de la interfaz de bucle de reparación local, y establecemos la propiedad tune.ssl.maxrecord en 2 kB, para 4 kB de espacio de búfer en el ESP8266. Después de habilitar los certificados de servidor y cliente en el firmware de nodo HAProxy y BMaC, respectivamente, teníamos un enlace cifrado TLS en ejecución, asegurándonos de que ni siquiera nuestros colegas pudieran oler lo que estábamos haciendo.

Poniendo todo junto

Cuando terminamos de cablear el primer controlador para el sistema de aire acondicionado en la oficina, el proyecto BMaC consistía en una red inalámbrica de sensores de movimiento, temperatura, CO2, presión de aire y presión de café, junto con una serie de relés y controladores de ventiladores, todos conectados. mediante un servidor central trasero y enlaces MQTT seguros.

Después de instalar la red, con MQTT asegurado con certificados del lado del cliente para garantizar que solo los clientes genuinos de BMaC MQTT pudieran conectarse, fue muy bueno poder concentrarse en transmitir los comandos y datos entre los nodos y el backend. El único problema que realmente me molestó fue la falta de un cliente MQTT de escritorio que me permitiera monitorear MQTT, descubrir temas activos y ser directamente compatible con cargas útiles binarias en lugar de asumir que solo se usaría MQTT para cargas útiles de texto. .

Esto me llevó a desarrollar un cliente de escritorio basado en C ++ / Qt MQTT llamado MQTTCute. Es el cliente que me gustaría tener desde el principio cuando instalé todo el sistema, tratando de tener una idea de lo que se envía en los problemas de MQTT. Dado que terminamos usando un protocolo binario para BMaC, tener una función hexadecimal incorporada en el cliente de escritorio habría sido invaluable.

De todos modos, si tuviéramos que hacer todo de nuevo, con los conocimientos adquiridos, casi seguiríamos eligiendo la misma ruta. Seguramente intentaríamos usar ECC en lugar de TLS, sin embargo, solo para ahorrarnos la carga de usar un punto final y un proxy TLS adicionales.

También encontramos que algunas bibliotecas MQTT asumían cargas útiles basadas en texto y usarían funciones de C como strlen () y kin. Muchos de ellos recibieron más tarde solicitudes de extracción de los suyos, de modo que esas bibliotecas ahora pueden aceptar felizmente todo tipo de datos binarios que uno quiera enviar a través de MQTT, incluidas las imágenes.

El elefante en el cuarto

Cuando se trata de MQTT y sistemas de intermediarios de clientes similares, siempre existe el argumento de que no se puede confiar en ellos porque tienen un único punto de falla en la forma del intermediario de MQTT. Este es ciertamente un punto válido, pero tampoco tan válido como se podría suponer.

Los corredores de MQTT tienden a ejecutarse en hardware de servidor confiable, en el caso de BMaC como el caso de una máquina virtual Linux en un clúster de almacenamiento. Para que el corredor desapareciera repentinamente de la red, se necesitaría una falla tan catastrófica que paralizaría la red de la empresa junto con ella.

Se podría crear un segundo corredor MQTT en una dirección secundaria, pero eso sería mucho trabajo sin una buena causa. En nuestro propio proceso de desarrollo de BMaC durante todo el año, tuvimos cero fallas del corredor Mosquitto y más problemas con los puntos de acceso WiFi (antiguos).

  • Kevin Kessler dice:

    Se lo recomiendo a cualquiera que busque proteger el tráfico MQTT con ESP32 u 8266, busque claves precompartidas. Son más simples de implementar y probablemente lo suficientemente buenos para lo que hacemos. Si no genera un certificado específicamente para cada dispositivo con alguna información válida (como la dirección IP del host MQTT y los clientes), realmente no obtiene seguridad adicional con los certificados PKI. Si usa la misma seguridad de cliente en todas partes, solo tiene un montón de material clave en cada dispositivo que podría descargarse y reutilizarse en un dispositivo defectuoso, que básicamente se obtiene con una clave previamente compartida.

  • Tom Brusehaver dice:

    Node-red es una excelente herramienta de depuración para el tráfico MQTT. Con las herramientas instrumentales, puede tener una interfaz de usuario en su teléfono o escritorio sin código adicional.

    Escribí mis resultados en http://enginemonitor.blogspot.com

  • dcfusor2015 dice:

    Usted llama seguridad amplia, seguridad profunda. No son muy iguales. Cubrir cada pieza es amplio, tener un respaldo en cada cosa es profundidad, como tener una alarma antirrobo que atraiga a la policía, pero también tener una caja fuerte para frenar a los villanos hasta que la policía pueda llegar allí, eso es profundidad (superficial, pero general). Solo cubrir una superficie de ataque con una capa de profundidad no es profundidad en absoluto, y es muy engañoso para aquellos que no conocen esta seguridad.

    • Elliot Williams dice:

      Creo que ella piensa que WPA es una capa de cifrado, TLS es otra capa.

  • Fosselius dice:

    En mi experiencia, MQTT es bueno y malo. está bien hacer un truco rápido o una prueba de concepto, pero cuando realmente desea optimizar la batería / datos / seguridad, probablemente desee ejecutar su propio protocolo. Al final, es tu candidatura la que decide.

    What’s Wrong with MQTT?

    • Montrough dice:

      Gracias por el artículo, amablemente que no está enojado y el estado mqtt es inútil, solo llama la atención sobre sus defectos. Y estoy de acuerdo con él.

      Una cosa que me gustaría señalar es una seguridad menos considerable para los dispositivos de gama baja, si los datos no son secretos, pero se requiere confianza, considere la posibilidad de firmar los datos. Sé que hay un chip barato que puede manejar eso. Tengo algunos, pero aún no los he contactado (tweet redondo).

    • Elliot Williams dice:

      Soy uno de los descritos en el artículo por tener hojas MQTT. O al menos una almohada MQTT.

      Las personas que están acostumbradas a adoptar protocolos por completo se quejan de que MQTT carece de cosas como cargas útiles estandarizadas y mecanismos de descubrimiento. Y eso es cierto, aquí hay detalles que usted dejó para implementar. Si un sensor informa en grados Celsius y otro en Fahrenheit, eso le preocupa.

      La T es MQTT significa “transporte”, y realmente se trata de llevar los datos de aquí para allá. El artículo vinculado parece pensar que necesita hacer mucho más.

      Te permites diseñar tu propio protocolo, interpretar los datos e ingresar tanta seguridad como necesites. ¿Eso es bueno o malo? Probablemente ambos, como dices.

    • rubypanther dice:

      Vi muchas publicaciones como esa mientras evaluaba MQTT, pero en última instancia, esas son las razones por las que lo elegí.

      Yo mismo me ocuparé de la interoperabilidad, en la capa de aplicación. Tendrá que variar de alguna manera, desde un pequeño sistema ARM hasta un cliente de escritorio.

      Lo que obtengo de MQTT es que puedo dirigir los datos de forma transparente. Tal vez sea punto a punto primero, pero luego quiero que los datos fluyan. No necesariamente tengo que cambiar de cliente para que eso suceda.

      Generalmente, utilizo Protocol Buffers (nanopb) para describir los datos. Para muchos casos de uso, algo como AVRO podría ser mejor para esa capa porque es autodescriptivo.

      Cuando la alternativa es rodar todo, no parece justo quejarse de que la herramienta no lo hace todo. Realiza algunas de las partes que no quiero realizar varias veces.

  • Pete dice:

    Comparar TLS con ECC es como comparar manzanas con …. semillas de manzana, supongo. ECC es uno de los cifrados asimétricos disponibles dentro de TLS. ¿Quizás está pensando en NaCl o en una de las bibliotecas de cifrado más pequeñas y más enfocadas que TLS? Quizás sea mejor utilizar uno de los conjuntos de cifrado de bajos recursos hechos específicamente para programas integrados; o como [Kevin Kessler] sugiere, PSK.

  • seathermarqx0 dice:

    “Trascender” MQTT sería abandonar el protocolo. El gran tobogán no tiene sentido. Si realmente desea seguridad u optimización, probablemente desee crear la suya propia utilizando algo como ZeroMQ como procesador de mensajes.

    http://zeromq.org/

    O puede que ya haya establecido un protocolo como DDS (apropiado).

  • bosque eterno dice:

    Busqué durante un tiempo un protocolo que fuera adecuado para mi aplicación y, al final, decidí crear el mío propio. Necesitaba una seguridad bastante buena (como en “Ningún criptógrafo profesional tiene tiempo para hacer trampa en esto, pero los guionistas deben permanecer fuera”), llamadas de procedimiento remotas y mensajería confiable. También necesitaba compatibilidad con ESP8266 / 32 desde el IDE y quería multidifusión.

    Pero lo más importante es que quería que todo se hiciera como si estuviera desconectado. El concepto de conexión rota no debe exponerse al usuario cuando se pretende que funcione con una mala conexión WiFi. Si no se puede acceder a un dispositivo, las llamadas RPC fallarán, pero si el dispositivo regresa, el protocolo debe volver a conectarse.

    Fue uno de los proyectos más interesantes que hice. NaCl fue la opción obvia para la seguridad, y UDP fue obvio para el transporte, pero diseñar API que disfruté y operar todo de manera confiable tomó mucho tiempo.

  • neroZZ dice:

    Si está utilizando MQTT, puede consultar http://mqtt-explorer.com, es un excelente cliente MQTT.
    – Le da un comienzo fácil cuando es nuevo en MQTT
    – le brinda una excelente descripción general de todos los temas
    – le muestra su arquitectura existente y heredada (cosas que se olvidó por completo)

    Buen artículo

  • nerozz dice:

    Si está utilizando MQTT, es posible que desee consultar https://mqtt-explorer.com, es un excelente cliente MQTT.
    – Le da un comienzo fácil cuando es nuevo en MQTT
    – le brinda una excelente descripción general de todos los temas
    – le muestra su arquitectura existente y heredada (cosas que se olvidó por completo)

    Gran artículo y realmente me encantan las características binarias de MQTTCute

  • Julian Silden Langlo dice:

    Me pregunto cuánto costará un conmutador Omron con capacidades mqtt. (Inspirado en https://la-tecnologia.com/2019/04/03/giving-an-industrial-push-button-usb-elegantly/) Facilitaría conocer el estado de todos los interruptores de su fábrica.

Joel Carrasco
Joel Carrasco

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *