Seguridad MQTT

Autenticación MQTT con usuario y contraseña explicada

Cómo viajan el usuario y la contraseña en el paquete CONNECT de MQTT, por qué siempre deben ir acompañados de TLS, cómo rechazan los brokers las credenciales incorrectas y cómo gestionar credenciales por dispositivo en un broker MQTT gestionado.

Ilustración de la autenticación MQTT con usuario y contraseña, con un dispositivo enviando credenciales a un broker a través de un túnel TLS
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

La autenticación MQTT con usuario y contraseña es la forma más utilizada para que un cliente demuestre su identidad ante un broker, y también la que con más frecuencia se configura mal. En esta guía verás exactamente cómo viajan las credenciales en el paquete CONNECT, por qué solo están a salvo dentro de TLS, qué códigos de motivo recibes cuando son incorrectas y cómo gestionar un conjunto de credenciales por dispositivo.

Cómo viajan las credenciales en el paquete CONNECT

Toda sesión MQTT comienza con un paquete CONNECT enviado por el cliente. Su cabecera variable contiene los connect flags, dos de los cuales son el User Name Flag y el Password Flag. Cuando están activados, el payload transporta el nombre de usuario como cadena UTF-8 y la contraseña como datos binarios, justo después del client ID y del mensaje Will opcional.

CONNECT
  Protocol name:    MQTT
  Protocol level:   5 (MQTT 5.0) or 4 (MQTT 3.1.1)
  Connect flags:    username=1, password=1, clean start=1
  Keep alive:       60
  Payload:
    Client ID:      sensor-0042
    Username:       YOUR_USERNAME
    Password:       YOUR_PASSWORD   <- bytes en bruto, sin hash

En la capa MQTT no hay hash, desafío ni cifrado. La contraseña se envía tal cual. Cualquiera que pueda leer el flujo TCP en el puerto 1883 puede leer la contraseña con una herramienta de captura de paquetes en cuestión de segundos.

Conviene conocer algunos detalles del protocolo:

  • En MQTT 3.1.1 solo se puede enviar una contraseña si también se envía un nombre de usuario. MQTT 5.0 relajó esta regla para que la contraseña pueda enviarse sola, pero la mayoría de los brokers siguen esperando ambos.
  • El campo de contraseña es binario, así que puede contener bytes arbitrarios, incluidos tokens. Así es como los esquemas basados en tokens, como la autenticación JWT en MQTT, reutilizan el mismo campo.
  • MQTT 5.0 también define la autenticación mejorada mediante una propiedad Authentication Method y paquetes AUTH, para mecanismos de desafío-respuesta. El usuario y la contraseña siguen siendo la base habitual.

Por qué TLS es obligatorio con contraseñas

Como la contraseña cruza la red en texto claro, la autenticación MQTT con usuario y contraseña sin TLS es poco mejor que no tener autenticación en cualquier red no confiable. TLS cifra toda la sesión, incluido el paquete CONNECT, y permite al cliente verificar que está hablando con el broker real y no con un impostor que recopila credenciales.

Puerto Transporte ¿Seguro para credenciales?
1883 MQTT sobre TCP plano No, la contraseña es visible en la red
8883 MQTT sobre TLS Sí, con verificación de certificado
8083 MQTT sobre WebSocket No
8084 MQTT sobre WebSocket seguro (/mqtt) Sí

En ConnectMQ, usa el puerto 8883 para dispositivos y servicios y el 8084 para navegadores siempre que envíes credenciales. El broker presenta un certificado de Let's Encrypt, en el que confían los paquetes de CA estándar de los sistemas operativos de escritorio y servidor. Los clientes embebidos necesitan incluir la CA raíz en el firmware; la guía de configuración de TLS en MQTT cubre ese paso.

Verifica también el certificado. Desactivar la verificación (insecure, setInsecure(), rejectUnauthorized: false) te da cifrado frente a la escucha pasiva, pero ninguna protección frente a un atacante que intercepte la conexión y presente su propio certificado.

Conectarse con usuario y contraseña

Los ejemplos usan los marcadores YOUR_USERNAME, YOUR_PASSWORD y YOUR_CLIENT_ID, que obtienes al crear un broker en el portal. Si todavía no tienes uno, la guía del broker MQTT en la nube repasa las opciones de alojamiento.

Python (paho-mqtt 2.x)

import os
import ssl
import paho.mqtt.client as mqtt

HOST = os.environ.get("MQTT_HOST", "YOUR_BROKER_HOST")
USERNAME = os.environ["MQTT_USERNAME"]   # nunca lo incluyas en el control de versiones
PASSWORD = os.environ["MQTT_PASSWORD"]
CLIENT_ID = os.environ["MQTT_CLIENT_ID"]

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("Rejected:", reason_code)   # p. ej. Bad user name or password
        client.disconnect()
        return
    print("Authenticated")
    client.publish(f"devices/{CLIENT_ID}/status", "online", qos=1, retain=True)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=CLIENT_ID, protocol=mqtt.MQTTv5)
client.username_pw_set(USERNAME, PASSWORD)
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.connect(HOST, 8883, keepalive=60)
client.loop_forever()

Línea de comandos

mosquitto_pub -h YOUR_BROKER_HOST -p 8883 \
  --cafile /etc/ssl/certs/ca-certificates.crt \
  -i YOUR_CLIENT_ID -u YOUR_USERNAME -P "$MQTT_PASSWORD" \
  -t 'devices/YOUR_CLIENT_ID/status' -m online -V mqttv5

Lee la contraseña desde una variable de entorno en lugar de escribirla en la línea de comandos, donde acaba en el historial del shell y en los listados de procesos.

Qué ocurre cuando las credenciales son incorrectas

El broker responde a CONNECT con un CONNACK. El código te indica si el problema está en las credenciales o en la autorización:

Situación CONNACK en MQTT 3.1.1 Código de motivo en MQTT 5.0
Aceptado 0x00 0x00 Success
Client ID rechazado 0x02 Identifier rejected 0x85 Client Identifier not valid
Usuario o contraseña incorrectos 0x04 Bad user name or password 0x86 Bad User Name or Password
Credenciales válidas, sin permiso 0x05 Not authorized 0x87 Not authorized

Los pasos completos de diagnóstico están en MQTT connection refused: not authorized. Hay dos reglas prácticas que se aplican a todos los clientes:

  1. No reintentes inmediatamente en un bucle cerrado. Las credenciales incorrectas no se arreglan solas, y muchos brokers tratan los fallos rápidos como un ataque. ConnectMQ bloquea las direcciones IP tras varios inicios de sesión fallidos, así que una flota mal configurada que bombardee el broker puede acabar bloqueándose a sí misma.
  2. Usa backoff exponencial con jitter y muestra los fallos de autenticación en los logs o en el estado del dispositivo, separados de los errores de red.

Credenciales por dispositivo: por qué y cómo

El atajo con el que empiezan la mayoría de los proyectos es un único usuario y contraseña compartidos y grabados en todos los dispositivos. Funciona el primer día y da problemas a partir de entonces:

  • Un solo dispositivo filtrado expone a toda la flota.
  • No puedes revocar un único dispositivo sin volver a flashearlos todos.
  • Los logs no pueden decirte qué dispositivo se comportó mal.

Las credenciales por dispositivo resuelven los tres problemas. En un broker Mosquitto autoalojado tendrías que mantener un archivo de contraseñas:

# Crea el archivo con el primer usuario y añade los demás sin -c
mosquitto_passwd -c /etc/mosquitto/passwd sensor-0001
mosquitto_passwd /etc/mosquitto/passwd sensor-0002
# mosquitto.conf
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile  /etc/mosquitto/certs/server.key
allow_anonymous false
password_file /etc/mosquitto/passwd

El archivo almacena hashes con sal, no las contraseñas en sí, y el broker debe recargarse tras cada cambio. Operarlo por tu cuenta también implica mantener renovado el certificado TLS y el archivo sincronizado entre instancias.

Credenciales por dispositivo en ConnectMQ

Con ConnectMQ el broker genera las credenciales por ti. Al crear un broker en el portal recibes un nombre de usuario, una contraseña y un client ID, y el client ID queda vinculado a las credenciales emitidas. Esa vinculación importa: una contraseña robada no puede usarse con un client ID arbitrario, y dos dispositivos no pueden compartir en silencio un mismo conjunto de credenciales, porque competirían por la misma identidad vinculada.

Prácticas recomendadas en un broker MQTT gestionado:

  1. Emite un conjunto de credenciales independiente para cada dispositivo o servicio y registra qué dispositivo físico tiene cada client ID.
  2. Guarda la contraseña en un almacenamiento protegido del dispositivo, no en el código fuente. Consulta cómo proteger las credenciales MQTT en los dispositivos.
  3. Conéctate solo en 8883 u 8084 con verificación de certificado.
  4. Planifica los cambios: la guía de rotación de credenciales muestra cómo sustituir credenciales en toda una flota sin tiempo de inactividad.

Los tenants están aislados entre sí, de modo que las credenciales emitidas para tu broker solo dan acceso al tráfico de tu broker. Las cuotas y la protección contra inundaciones se aplican según el plan, lo que limita el daño que puede causar un único cliente comprometido.

Usuario y contraseña frente a otros métodos

Método Ventaja Inconveniente
Usuario y contraseña sobre TLS Sencillo, compatible con todas las bibliotecas cliente Secreto estático; hay que almacenarlo y rotarlo
Certificados de cliente (mTLS) Identidad sólida, sin secreto compartido en la red Ciclo de vida de certificados y PKI que operar
JWT en el campo de contraseña De corta duración, transporta claims Necesita un emisor de tokens y reloj sincronizado en los dispositivos

Para la mayoría de las flotas, contraseñas únicas por dispositivo sobre TLS verificado son una base sólida. La guía de buenas prácticas de seguridad MQTT cubre las capas que se sitúan por encima.

Empieza con ConnectMQ

Olvídate de archivos de contraseñas y renovaciones de certificados. Un broker MQTT gestionado de ConnectMQ te ofrece TLS en 8883 y 8084, credenciales generadas vinculadas a client IDs y bloqueo de IP ante inicios de sesión fallidos repetidos. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito.

Preguntas frecuentes

¿Es segura la autenticación MQTT con usuario y contraseña?

Es lo bastante segura para la mayoría de los despliegues cuando se usa sobre TLS con verificación de certificado y contraseñas únicas por dispositivo. Sobre TCP plano en el puerto 1883, la contraseña es visible para cualquiera que pueda capturar el tráfico.

¿MQTT cifra la contraseña?

No. MQTT envía la contraseña como bytes en bruto dentro de CONNECT. El cifrado procede únicamente de la capa TLS que envuelve la conexión.

¿Puedo conectarme al broker público con usuario y contraseña?

El servidor MQTT público gratuito en broker.connectmq.com acepta conexiones anónimas con cualquier client ID único no vacío y está pensado solo para pruebas y prototipos. Para tráfico privado y autenticado, crea tu propio broker y usa las credenciales generadas.

¿Cuál es la diferencia entre 0x86 y 0x87?

0x86 significa que el usuario o la contraseña eran incorrectos. 0x87 significa que las credenciales se entendieron, pero el cliente no tiene permiso para conectarse o realizar la acción.

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.