MQTT para conectar una web online con un backoffice remoto – ASPL
ACTUALIZACIÓN: ¡El próximo jueves 15 de abril del 2021 no te pierdas el CMS/DXP Day de la serie de eventos virtuales OpenExpo Business Live! Si quieres saber qué herramienta de gestión de contenidos y experiencia de usuario es la más adecuada para la transición digital de tu empresa, qué preguntas tienes que hacerte para elegirla, y por qué hoy en día son fundamentales tanto en entornos B2B como B2C, ¡regístrate gratis!
REGISTRO ↪️ https://cutt.ly/5x2SgRs
——————————————————————————-
1. Resumen
A continuación se presenta una solución basada en MQTT ([1] mqtt.org) para conectar una plataforma web de venta, gestión de producto y relación con el cliente para que use e interaccione con una base de datos remota en uno o varios servidores protegidos (sin conexión directa).
Durante la secunda parte, a partir del punto 5. Usando MQTT para conectar nuestros sistemas, detallamos los pasos necesarios para implementar dicha solución, incluyendo indicaciones técnicas y ejemplos concretos de código necesarios para desplegar la solución [1] MQTT.
Palabras clave: MQTT, Micro servicios, Hacking, Seguridad web, Python, Stashing MQTT
Para una lectura rápida de concepto, recomendamos leer (no más de 2 minutos) los tres primeros puntos, junto con las conclusiones:
- 2. Definición del problema
- 3. Desafios a resolver
- 4. Diseño de la solución: MQTT al rescate
- 11. Conclusiones y revisión de la solución MQTT
2. Definición del problema
Varios de los desafíos a resolver con una plataforma de venta online y que tiene estar «conectada» en tiempo real con un backoffice remoto son:
- Tener la capacidad de integrar los productos contratados, cambios de precios, facturas, etc, con los sistemas de base de datos normalmente localizados en oficinas, separadas del datacenter.
- La seguridad y el control de la información: no parece una buena idea tener información contable, facturas, declaraciones 347 y todo tipo de movimientos en la propia máquina donde ejecuta la web.Un único fallo de seguridad en la programación de la web podría poner en riesgo toda esta información.Sin embargo, necesitamos poder proporcionar toda esta información al cliente debido a los enormes beneficios que esto proporciona: gestión ágil del producto y el acceso inmediato a la información que necesita el cliente.
- Protección frente hacking directo reduciendo la superficie de ataque. Efectivamente, abrir puertos TCP/UDP de aplicaciones de contabilidad, bases de datos, etc, aunque estén limitados por IP, es un riesgo enorme.
Hay que contar con un diseño que espere lo mejor pero que se prepare para lo peor: la web puede ser hackeada y no por eso, el atacante debe tener acceso a puertos autorizados.
3. Desafíos a resolver
Tras varias alternativas estudiadas, llegamos a la conclusión de que necesitábamos una solución que proporcione un [3] bajo acoplamiento entre la web de venta online y el sistema interno de gestión contable (con sus distintos componentes).
En concreto, los requisitos a cumplir son:
- Tener trazados y autorizados los mensajes de modificación y consulta emitidos desde la plataforma web.
- Evitar dar acceso SQL completo. Es decir, si hay un hacking, que esto no implique un acceso completo o generalizado a información de otros usuarios.
- Trazar y almacenar de manera ordenada todas las peticiones de cambio emitidas por la plataforma online en un almacenamiento independiente para poder replicarlas, cotegarlas o comprobarlas.
- Que no sea un problema tener caído el sistema contable: que las compras, altas de usuarios, bajas y peticiones de cambio no se pierdan y se reenvíen y apliquen en orden en cuanto el sistema contable esté en marcha.
- Que no haya conexión directa (puertos abiertos) entre sistema contable y la plataforma de venta online.
- Capacidad de conectar varios sistemas de caracter local en distintas localizaciones (red privada), con la plataforma web online. Cuando hablamos de «sistema contable», en realidad hablamos de varias aplicaciones en distintos servidores.
- Establecer como única fuente de verdad el sistema contable: que la plataforma web online sea una vista.
4. Diseño de la solución: MQTT al rescate
El protocol MQTT ([1] mqtt.org) define un estándar abierto para el intercambio de mensajes entre distintos participantes siguiendo un modelo de [4] PUBLISH-SUBSCRIBE.
En esencia, participantes sin conocimiento mútuo, ni conexión directa, ejecutando plataforma heterogénea, pueden intercambiar mensajes sin tener que obligarse a estar presentes en el momento del intercambio.
Las características que nos proporciona MQTT, junto con algunos añadidos nos resuelven los retos técnicos que tenemos. Veamos cómo.
5. Usando MQTT para conectar nuestros sistemas
Lo primero que necesitaremos es un Broker MQTT. Este es el componente servidor del protocolo MQTT. Es el encargado de autorizar a los participantes, hacer el almacenamiento de los mensajes y de hacer el rutado entre los componentes que publican y los subscriptores.
Existen varias implementaciones disponibles [1] y [2].
[5] http://www.steves-internet-guide.com/mqtt-hosting-brokers-and-servers/
[6] https://github.com/mqtt/mqtt.github.io/wiki/brokers
Nosotros usaremos [7] MyQttHub.com, una plataforma Cloud MQTT con toda la mecánica disponible, administración WEB y API REST.
MyQttHub.com nos proporciona un plan Open sin coste con capacidad para enviar 10.000 mensajes al día, 310.000 mensajes al mes. Sobrada capacidad de manera que tendríamos resuelta esta parte: no habría que preocuparse por mantener un sistema más.
Para ello, nos creamos una cuenta MyQttHub Open directamente desde la misma web, usando el formulario de suscripción: MyQttHub.com. Hay más información sobre el proceso en [3]:
[8] Cómo crear tu cuenta Open MyQttHub.com
Ahora, vayamos integrando paso a paso la solución en nuestro entorno. Comenzaremos con la parte privada de tu red (conectando una sede).
6. Conectando tu plataforma privada local al servidor MQTT
Para poder «exportar» la información que necesitan tus usuarios, necesitas conectar tus sistemas al servidor MQTT. El proceso de configuración inicial es sencillo:
-
- Necesitarás un cliente satélite MQTT que haga de puente (MQTT bridge) entre la plataforma MQTT y tu sistema. Este cliente satélite se encargará de sostener la conexión y de mapear/transformar los mensajes recibidos desde la plataforma MQTT en comandos locales.
2. Estos «comandos locales» encapsularán la parte específica de tu instalación. Ahora veremos esto. Primero, usaremos como cliente satélite MQTT MyQttSatellite. Es gratuito, sin límites ni costes.
Para ello, sigue los pasos descritos el siguiente enlace para descargar instalar y conectar tu equipo:
[9] MyQttSatellite: cliente MQTT para mapear mensajes a comandos
3. Una vez conectado el cliente MQTT satélite tendrás que implementar la lógica para cada mensaje o API MQTT que vaya proporcionando tu solución. Para ello, elegiremos Python, aunque cualquier lenguaje te valdrá. Mira cómo lo hacemos con Python para adaptarlo a tu caso.
4. En concreto, implementaremos soporte para las operaciones «alta de usuario» y «listado de productos». Estas dos operaciones te darán una visión de cómo se implementa una operación de modificación y una operación de consulta.
5. Para la operación de «alta de usuario», crearemos una estructura básica como la que sigue. Usaremos JSON para la codificación de los mensajes aunque puedes usar XML, CSV o incluso formatos binarios como MessagePack sin problemas:
#!/usr/bin/python import sys import json # leemos el mensaje recibido message = open (sys.argv[1]).content # parseamos el mensaje Json newCustomer = json.loads (message) if not newCustomer: print "ERROR: failed to parse new customer mesasge, empty content received" sys.exit (-1) # implementa aquí la parte específica de alta de usuario en tu # base de datos local (consulta SQL, llamada API, etc..) # finalizamos reportando estado OK sys.exit (0)
6. Para implementar soporte para una operación de consulta, tan solo tendrás que extender el ejemplo anterior imprimiendo la salida en un formato conocido para el receptor, junto con una cabecera (X-Publish-Reply-To-Topic). Más detalles sobre esto en:
[10] Cómo generar respuestas MQTT con MyQttSatellite: uso de la cabecera X-Publish-Reply-To-Topic
7.Ahora, con estos comandos definidos, actualiza tu configuración MyQttSatellite para mapear topics a tus comandos dentro de /etc/MyQttSatellite/conf/application.conf . Por ejemplo:
command-mapper = [ "company/customer/new" -> comando_de_alta_de_cliente.py " "company/customer/list/products" -> comando_de_listado_de_productos_de_cliente.py " ]
Con esta parte, ya estarían descritos los pilares que necesitas para gestionar mensajes recibidos desde la plataforma MQTT en tus nodos de red privada.
7. Probando la integración MQTT antes de modificar la parte pública
Ahora, antes de tocar tu plataforma web para comenzar a enviar mensajes MQTT, necesitas probar que todo funciona y es correcto.
Esta es una ventaja que nos proporciona MQTT. Nos permite probar la implementación enviando mensajes con el formato esperado para ver cómo responde el sistema.
Para ello, conecta a tu cuenta MyQttHub.com y usa la función de publicar mensaje que tienes en la parte superior del panel:
[11] Cómo publicar mensajes MQTT desde la interfaz Web MyQtthub.com
Probar la solución de esta manera te permitirá controlar y comprobar cómo funciona el conector cliente MQTT junto con los comandos que vayas implementando.
Una vez estés listo, ya podrías integrar la parte web online para que se subscriba y genere los mensajes necesarios para interactuar con el sistema remoto.
8. Consideraciones de seguridad para tu web al conectar con el servidor MQTT
Llegados este punto solo resta conectar tu plataforma web con la solución MQTT. Antes de realizar ningún cambio, algunas recomendaciones sobre seguridad:
- Al ser un sistema online, hay que considerar que es un entorno hostil y que tiene que estar preparado para recibir ataques o intentos para manipular, hackear o usar el sistema de manera no prevista.
- Dado que el emisor de los mensajes MQTT (tu web) no conoce quién los procesa (en este caso, tu cliente MQTT satélite), y viceversa, hay que extremar las precauciones tomando decisiones de diseño que eviten que el usuario que conecta tu web pueda seleccionar y configurar contenidos del mensaje MQTT.
Efectivamente, la clave para obtener una seguridad adecuada es evitar que sea un cliente javascript MQTT o HTTP (javascript XmlHttpRpc) quien genere los mensajes MQTT en el lado web del navegador del usuario.
Al contrario, las claves para obtener buenos niveles de seguridad son:
- Hacer que el lado server side de tu plataforma web (PHP, .NET, java, etc) sea la que genere los mensajes MQTT.
- No permitir que el cliente decida o indique nada sobre el remite, topic o routing del mensaje MQTT. Para conseguir esto hay que obtener toda la información desde la sesión del usuario (almacenada en el lado servidor).
Con estas consideraciones de seguridad hechas, ya solo resta elegir el formato de integración. Tenemos dos posibilidades:
- Instalar un cliente MQTT para el lenguaje de programación de tu web (PHP, .NET, Go, Node.js, java…etc).
- Usar el API REST [1] proporcionada por MyQttHub.com para conectarnos, publicar y recibir los mensajes:[12] API REST HTTPS de MyQttHub.com
Por facilidad de integración y debido a que hace uso de una tecnología ampliamente disponible, optaremos por integrar con HTTPS y el API REST.
9. Conectando tu web al servidor MQTT
Las partes a completar son:
- Crea un dispositivo MQTT con el que publicar los mensajes. Nunca reúses credenciales usadas por otros dispositivos. Para ello, sigue las indicaciones en:[13] Cómo gestionar dispositivos MQTT con MyQttHub.com
- Da igual si usas interfaz MQTT o HTTP, usa siempre TLS/SSL. De lo contrario estarás enviando información sensible sin cifrar por internet.
- Dado que potencialmente generarás varias conexiones concurrentes a la plataforma, tendrás que activar el Skip Connection Replace. Mira cómo se hace en el siguiente artículo y la motivación:[14] Cómo configurar Skip Connection Replace
- Ahora, elige la sección en el código de tu web donde deseas emitir el mensaje. Si es un alta de cliente tendría que ser hecho al final del alta en la web. Ahí tendrás que realizar una conexión web, y publicar el mensaje.
Para ello, sigue las indicaciones del siguiente artículo que explica cómo realizar esta operación con Python. El ejemplo se puede adaptar fácilmente al lenguaje de programación que uses ya que estamos hablando de hacer consultas HTTPS:
[15] Usando el API REST de MyQttHub.com con python (httplib)
10. Almacenamiento ordenado de mensajes MQTT y soporte de reenvío
Con la solución desplegada, teniendo tu plataforma web conectada a tu gestión interna vía interfaz MQTT, ya puedes pasar a hablar del almacenamiento ordenado de los mensajes intercambiados y del reenvío de mensajes.
Esta característica es fundamental para trazar qué pasó, cuándo y quién solicitó el cambio. También es necesaria para soportar situaciones de fallo durante el proceso de mensajes o la recepción de mensajes pendientes al no estar disponible.
Estas dos características (almacenamiento y reenvío) están fuertemente relacionadas pero se gestionan de manera independiente:
- Reenvío MQTT QoS1 y QoS2: capacidad por la cual un broker/servidor MQTT almacenará y reenviará los mensajes no recibidos durante la desconexión de un participante subscrito a dichos mensajes.
- Stashing MQTT [2]: capacidad por la cual un servidor/broker MQTT almacena los mensajes en orden si encajan con un patrón o topic, con independencia de si han sido entregados o no, para formar un almacenamiento cronológico que permita el reenvío y trazado.
Efectivamente, con el primer soporte (el Reenvío MQTT) ya tenemos cubierto la capacidad de recibir los mensajes de alta y modificación de nuestra base de datos en el caso de que la conectividad en las sedes locales no esté disponible o haya problemas temporales con los servidores localizados en las mismas.
Además, los mensajes que reenvíe la plataforma se recibirán en orden: así aseguramos que los cambios que reciba la base de datos tendrán la misma cronología que cuando se produjeron.
Por otro lado, en el caso del Stashing, cada plataforma o Broker/MQTT lo configura de manera distinta. En el caso de MyQttHub.com sigue los siguientes pasos para crear un Stash y un filtro que ordene el almacenamiento de los mensajes que te interesan:
[2] Stashing MQTT para almacenamiento ordenado de los mensajes
Una vez creado el stashing tendrás todos los mensajes almacenados, en orden y con la capacidad para:
- Reenviar cierto mensaje (por ejemplo, debido a que hubo un problema en su procesado)
- Descargar dichos mensajes para hacer un procesado posterior:[16] Descarga de mensajes MQTT almacenados en un Stash
11. Conclusiones y revisión de la solución MQTT
Hemos presentado un escenario donde necesitábamos resolver el problema de interxión de una plataforma web online junto con un backend de almacenamiento (un sistema de gestión) de manera [3] desacoplada y segura.
La solución presentada, basada en MQTT, nos permite resolver la comunicación entre ambas sin conexión directa.
También nos resuelve el problema de no tener que almacenar información sensible en la web: podemos seguir almacenándola en nuestro sistema de gestión interno (backoffice) y dar «APIs MQTT» para proporcionar acceso «selectivo» a los datos necesarios.
La solución también nos proporciona un almacenamiento de todas las solicitudes de cambio lanzadas desde el portal online. Esto permite trazar en orden qué ocurrió o realizar el reenvío de ciertas operaciones.
La solución basa en MQTT también nos resuelve que los participantes (la web online y el backoffice privado) no tengan que estar presentes en el intercambio: el backoffice puede reconectar más tarde para procesar todos los mensajes que tenga pendiente (y en el orden en el que fueron enviados).
Durante este artículo hemos podido trabajar distintos aspectos del protocolo MQTT, la plataforma Cloud MQTT MyQttHub.com y las distintas características de dispositivos, reenvío y almacenamiento duradero (Stashing).
Referencias
- [1] https://mqtt.org : MQTT estándar abierto para la IoT.
- [2] https://support.asplhosting.com/t/gestionando-y-usando-el-stashing-de-myqtthub-almacenando-mensajes-mqtt-encajando-con-ciertos-filtros : Stashing MQTT, almacenamiento ordenado y duradero.
- [3] https://es.wikipedia.org/wiki/Acoplamiento_(inform%C3%A1tica) : Bajo acoplamiento (término informático)
- [4] https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern : Patrón PUBLISH-SUBSCRIBE para el intercambio de mensajes.
- [5] http://www.steves-internet-guide.com/mqtt-hosting-brokers-and-servers/
- [6] https://github.com/mqtt/mqtt.github.io/wiki/brokers
- [7] MyQttHub.com : Plataforma Cloud MQTT
- [8] https://support.asplhosting.com/t/como-crear-tu-cuenta-myqtthub-com-open
- [9] MyQttSatellite: cliente MQTT para mapear mensajes a comandos
- [10] Cómo generar respuestas MQTT con MyQttSatellite: uso de la cabecera X-Publish-Reply-To-Topic
- [11] Cómo publicar mensajes MQTT desde la interfaz Web MyQtthub.com
- [12] API REST HTTPS de MyQttHub.com
- [13] Cómo gestionar dispositivos MQTT con MyQttHub.com
- [14] Cómo configurar Skip Connection Replace
- [15] Usando el API REST de MyQttHub.com con python (httplib)
- [16] Descarga de mensajes MQTT almacenados en un Stash