Seguridad MQTT

Pruebas de penetración MQTT: una metodología práctica para tus propios brokers

Un enfoque estructurado y defensivo de las pruebas de penetración MQTT: cómo delimitar el alcance de una prueba de tu propio broker, qué revisar en cada capa y cómo convertir los hallazgos en trabajo de bastionado.

Diagrama del flujo de pruebas de penetración MQTT con delimitación del alcance, reconocimiento y comprobaciones de autenticación y TLS contra un broker propio de la empresa
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

Las pruebas de penetración MQTT son una forma estructurada de encontrar debilidades en tu propio broker y en tus clientes antes de que lo haga otro. Esta guía te ofrece una metodología repetible, desde la delimitación del alcance y el reconocimiento hasta las comprobaciones de autenticación, autorización, TLS y límites de recursos, y termina con una lista de bastionado que puedes entregar al equipo. Todo lo que se describe aquí está pensado para sistemas que te pertenecen o para los que tienes permiso por escrito para probar.

Primero, las reglas de enfrentamiento

Probar un broker que no es tuyo constituye un acceso no autorizado en la mayoría de las jurisdicciones, aunque "ya estuviera abierto". Antes de enviar un solo paquete:

  • Obtén autorización por escrito del propietario del sistema, indicando hosts, puertos, fechas y técnicas permitidas.
  • Define qué queda fuera del alcance, por ejemplo dispositivos de producción que accionan equipos físicos, brokers de terceros y brokers públicos de pruebas.
  • Prefiere una copia de preproducción. Un broker con la misma configuración pero sin equipos reales te permite probar el acceso de escritura sin riesgo.
  • Acuerda condiciones de parada. Si una prueba provoca inestabilidad, detente e informa.

En un broker MQTT gestionado también se aplica la política de uso aceptable del proveedor. Prueba la configuración de tu propio tenant y el comportamiento de tus clientes, no la infraestructura compartida del proveedor, y nunca lances campañas de carga o fuzzing contra un clúster compartido o un servidor MQTT público gratuito como broker.connectmq.com. Sus límites por cliente existen para que siga siendo utilizable por todos.

La metodología de un vistazo

Fase Objetivo Evidencias típicas
1. Alcance Saber qué puedes probar Alcance firmado, lista de activos
2. Reconocimiento Mapear listeners, versiones y endpoints Lista de puertos, detalles de TLS, banner del broker
3. Autenticación Verificar que solo se conectan identidades válidas Resultados de intentos anónimos, con credenciales erróneas y reutilizadas
4. Autorización Verificar que cada identidad está limitada a sus topics Matriz de publicación/suscripción por rol
5. Seguridad del transporte Confirmar el cifrado y la validación de certificados Versiones de TLS, lista de cifrados, comportamiento de verificación del cliente
6. Robustez Comprobar límites y gestión de entradas malformadas (preproducción) Respuestas ante límites, estabilidad del broker
7. Revisión de clientes Revisar cómo gestionan los secretos dispositivos y apps Hallazgos en firmware y configuración
8. Informe Convertir los hallazgos en correcciones Lista de remediación priorizada

Fase 2: reconocimiento de tu broker

Empieza por enumerar todas las formas en que un cliente puede llegar al broker. Los equipos suelen proteger cuidadosamente el 8883 y olvidar un listener WebSocket o un antiguo listener sin cifrar.

# Enumera los puertos relacionados con MQTT en tu propio host
nmap -Pn -p 1883,8883,8083,8084,9001 your-broker.example.com

# Inspecciona el endpoint TLS
openssl s_client -connect your-broker.example.com:8883 -servername your-broker.example.com </dev/null

Anota para cada listener: el protocolo (TCP, TLS, WS, WSS), si es accesible desde internet, el sujeto y la caducidad del certificado y qué versiones de MQTT acepta. Si el broker expone topics $SYS, comprueba qué revelan a un cliente autenticado normal. Las cadenas de versión y el número de clientes son útiles para un atacante y rara vez los necesitan los dispositivos.

Fase 3: pruebas de autenticación

Las pruebas de autenticación responden a una pregunta: ¿puede conectarse alguien que no debería? Ejecuta cada prueba con un identificador que facilite encontrar el intento en los logs.

  1. Conexión anónima. Conéctate sin nombre de usuario. Resultado esperado: rechazo con un motivo "not authorised".
  2. Contraseña incorrecta. Resultado esperado: rechazo. Repítelo unas cuantas veces y confirma que los fallos repetidos se detectan o se limitan.
  3. Credenciales válidas, client ID incorrecto. Si tu broker vincula los client IDs a las credenciales, una discrepancia debe rechazarse.
  4. Client ID duplicado. Conéctate dos veces con el mismo ID y observa la toma de control de la sesión. Asegúrate de que tus dispositivos lo gestionan y de que un atacante que solo conozca un client ID no pueda apropiarse de una sesión.
  5. Credenciales revocadas. Revoca una identidad de prueba y confirma que ya no puede conectarse ni reconectarse.

Un pequeño script de Python hace que estas comprobaciones sean repetibles:

import time
import paho.mqtt.client as mqtt

HOST, PORT = "your-broker.example.com", 8883

CASES = [
    ("anonymous", None, None, "pt-anon-01"),
    ("wrong-password", "YOUR_USERNAME", "not-the-password", "YOUR_CLIENT_ID"),
    ("valid", "YOUR_USERNAME", "YOUR_PASSWORD", "YOUR_CLIENT_ID"),
    ("valid-wrong-id", "YOUR_USERNAME", "YOUR_PASSWORD", "pt-other-id"),
]

def try_connect(name, user, pwd, cid):
    result = {}
    client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=cid,
                         protocol=mqtt.MQTTv5)
    client.tls_set()  # verifica el certificado del servidor con las CA del sistema
    if user:
        client.username_pw_set(user, pwd)

    def on_connect(c, userdata, flags, reason_code, properties):
        result["rc"] = str(reason_code)
        c.disconnect()

    client.on_connect = on_connect
    try:
        client.connect(HOST, PORT, keepalive=10)
        client.loop_start()
        time.sleep(5)  # espera el CONNACK
        client.loop_stop()
    except Exception as exc:
        result["rc"] = f"exception: {exc}"
    print(f"{name:16} -> {result.get('rc', 'no response')}")

for case in CASES:
    try_connect(*case)

Solo el caso valid debería devolver Success. Todos los demás deberían rechazarse con un código de motivo claro.

Fase 4: pruebas de autorización

La autenticación demuestra quién es un cliente; la autorización decide qué puede hacer. Construye una matriz de roles (sensor, gateway, dashboard, servicio de administración) frente a patrones de topics y prueba cada celda con una conexión real.

Rol Publicar site/+/telemetry Suscribirse a # Publicar site/+/cmd Suscribirse a $SYS/#
Sensor Permitido (solo su topic) Denegado Denegado Denegado
Dashboard Denegado Denegado (solo comodín acotado) Denegado Denegado
Servicio de control Denegado Denegado Permitido Denegado

Fíjate en cómo se manifiestan las denegaciones. En MQTT 5, una suscripción rechazada devuelve un código de motivo en el SUBACK, como 0x87 (not authorised), y una publicación QoS 1 rechazada devuelve un PUBACK con un código de motivo. En MQTT 3.1.1, una publicación denegada suele descartarse en silencio, así que debes verificar con un segundo suscriptor privilegiado que el mensaje nunca llegó. En brokers autoalojados, la guía de ACL en MQTT explica cómo expresar estas reglas. Cuando el broker no ofrece reglas por topic, el control equivalente son brokers o tenants separados por zona de confianza.

Fase 5: pruebas de seguridad del transporte

Comprueba ambos lados de TLS:

  • Lado del servidor: solo versiones modernas del protocolo (TLS 1.2 y 1.3), un certificado de una CA de confianza que coincida con el nombre de host y ningún listener sin cifrar accesible desde internet.
  • Lado del cliente: los dispositivos deben rechazar un certificado incorrecto. Apunta un dispositivo de prueba a un host de preproducción con un certificado autofirmado o que no coincida y confirma que la conexión falla. Un cliente que se conecta de todos modos está, en la práctica, sin cifrar frente a un atacante activo.

El artículo de configuración de TLS en MQTT cubre los ajustes correctos del cliente, y analizar el tráfico MQTT con Wireshark es una buena forma de demostrar que los payloads ya no son visibles en la red.

Fase 6: robustez y límites (solo en preproducción)

Las pruebas de robustez comprueban cómo se comportan el broker y tus clientes ante entradas excesivas o malformadas. Ejecútalas solo en un broker de preproducción que controles, nunca en infraestructura compartida o de producción.

  • Payloads sobredimensionados: publica un mensaje mayor que el máximo configurado. Espera un rechazo, no un fallo.
  • Límites de tasa: publica más rápido de lo que permite tu política y confirma que el broker limita o desconecta. En los planes de ConnectMQ, superar una cuota se señala con el código de motivo 0x97 (quota exceeded) de MQTT 5, que tus clientes deben gestionar correctamente.
  • Inundaciones de conexiones: abre muchas conexiones desde un mismo origen y comprueba que los límites se aplican por cliente o por IP.
  • Fuzzing del protocolo: las herramientas que mutan paquetes MQTT pueden revelar errores de análisis. Mantenlas en un broker de pruebas aislado e informa de los fallos al fabricante del broker.

Para contextualizar el diseño de estos límites, consulta limitación de tasa y protección DoS en MQTT.

Fase 7: revisión de clientes y dispositivos

Muchos hallazgos reales están en el dispositivo y no en el broker:

  • Credenciales incrustadas en el firmware o subidas a un repositorio.
  • Una misma contraseña compartida por todos los dispositivos de una flota.
  • Topics de depuración que publican configuración o secretos.
  • Topics de comandos que ejecutan payloads sin validarlos.
  • Verificación TLS desactivada "para que funcione".

Trata cada dispositivo como si un atacante pudiera extraerlo e inspeccionarlo. Cada uno debe tener credenciales únicas que puedan revocarse de forma individual.

Lista de bastionado a partir de tus hallazgos

Convierte los hallazgos en resultados que el equipo pueda verificar:

  1. Todos los listeners exigen autenticación; el acceso anónimo solo existe donde es intencionado y está documentado.
  2. Solo los listeners TLS son accesibles desde internet, con un certificado válido.
  3. Cada dispositivo y servicio tiene credenciales únicas y revocables.
  4. Cada identidad solo puede publicar y suscribirse a los topics que necesita.
  5. Los clientes rechazan certificados no válidos.
  6. Hay límites configurados de tamaño de mensaje, tasa y conexiones, y los clientes gestionan los rechazos.
  7. Los inicios de sesión fallidos repetidos se limitan o bloquean.
  8. El software del broker se actualiza de forma programada.
  9. Los topics retenidos y de depuración no contienen secretos.
  10. Hay nuevas pruebas programadas tras cada cambio importante.

Varios elementos de esta lista los gestiona la plataforma cuando usas un broker MQTT gestionado. En ConnectMQ, los brokers privados exigen credenciales generadas, los client IDs están vinculados a esas credenciales, TLS usa un certificado de Let's Encrypt, los tenants están aislados y la protección contra inundaciones y el bloqueo de IP tras inicios de sesión fallidos repetidos vienen integrados. Así, tus pruebas pueden centrarse en el comportamiento de los clientes y en el diseño de topics. El artículo de buenas prácticas de seguridad MQTT es un buen complemento para los elementos del lado del cliente.

Prueba contra un broker que controles

La forma más segura de practicar esta metodología es con un broker propio. Crea un broker privado de ConnectMQ en el plan Serverless gratuito en app.connectmq.com (sin tarjeta de crédito), ejecuta las comprobaciones de autenticación y TLS con tus propias credenciales y deja las pruebas de carga y fuzzing para un broker local de preproducción. Para experimentos rápidos y no sensibles, puedes seguir usando el servidor MQTT público gratuito, dentro de sus límites y solo con datos de prueba.

Preguntas frecuentes

¿Puedo hacer pruebas de penetración a un broker MQTT público?

No sin el permiso explícito del operador. Los brokers públicos de pruebas son servicios compartidos, y las pruebas de carga o fuzzing los degradan para todos. Prueba tus propios brokers o una copia local de preproducción.

¿Qué herramientas se usan habitualmente en las pruebas de seguridad MQTT?

Escáneres de red para descubrir listeners, openssl s_client para las comprobaciones de TLS, mosquitto_pub y mosquitto_sub para pruebas rápidas y clientes programados como paho-mqtt para matrices repetibles de autenticación y autorización.

¿Con qué frecuencia deberíamos volver a probar nuestra instalación MQTT?

Tras cada cambio significativo en listeners, credenciales, estructura de topics o firmware, y de forma periódica en el resto de casos. Automatizar las comprobaciones de autenticación y autorización abarata las pruebas frecuentes.

¿Cuál es el hallazgo más habitual?

Las credenciales compartidas o incrustadas en los dispositivos y la verificación TLS desactivada en los clientes son hallazgos frecuentes, junto con listeners que aceptan conexiones anónimas.

Artículos relacionados

Cómo rotar credenciales MQTT sin tiempo de inactividad

Una estrategia de doble credencial paso a paso para rotar usuarios y contraseñas MQTT en toda una flota: prepara la nueva credencial, cambia con respaldo, verifica y solo entonces revoca la antigua.

8 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.