Resumen
Esta solución conecta de forma segura un dispositivo Shelly IP a RabbitMQ mediante el complemento MQTT usando TLS mutuo (mTLS), sin contraseñas y con autenticación mutua basada en certificados. Un único script de Bash instala y configura RabbitMQ, genera una CA privada y certificados de servidor y cliente, y después muestra una tabla con los valores de configuración. Cuando termina, el único paso manual en Shelly es cargar ca.crt, client.crt, y client.key, copia esos valores en la configuración de MQTT y guárdala. Admite la selección de la serie de RabbitMQ (--rmq-series 3.13|4.0|4.1, 4.1 de forma predeterminada) desde los repositorios Ubuntu noble de Team RabbitMQ y fuerza TLS 1.2 únicamente. En 4.x, el MQTT client_id se aplica desde el certificado SAN (URI) mientras que la autenticación nombre de usuario sigue proviniendo del certificado CN; en la versión 3.13, SAN->client_id la vinculación no está disponible. Puedes controlar el host de conexión (y el CN/SAN del certificado del servidor) mediante --connect-dns / --connect-ip. El script exporta los certificados de los dispositivos a /etc/mqtt-cert y, de forma predeterminada, también emite un certificado de monitorización () en /etc/mqtt-cert-monitor con archivos tarball en /tmp/.
Resultado: MQTT cifrado y autenticado mediante certificados, con acceso a temas basado en el principio de mínimo privilegio.
Enlace al script aquí.
Importante: este script es solo para desarrollo/pruebas, un ejemplo de lo que es posible hacer. Úsalo con cuidado y no lo implementes tal cual en producción.
Arquitectura
[Shelly device] | | MQTT sobre TLS (mTLS) - puerto 8883 v [receptor MQTT de RabbitMQ] ---> [intercambio amq.topic] ---> [queues/subscriptions] | | | ‘-- ACL de temas limitadas a tu prefijo MQTT | ‘-- Interfaz de administración (HTTPS, 15671) -
Transporte: Shelly se comunica con RabbitMQ por el puerto 8883 (MQTTS). TLS es obligatorio; los clientes deben presentar un certificado válido (mTLS) y se fuerza únicamente TLS 1.2.
-
Identidad: el CN del certificado del dispositivo se asigna a un usuario de RabbitMQ (sin nombre de usuario ni contraseña en Shelly).
-
Vinculación del ID de cliente: se aplica desde el SAN del certificado (URI) en RabbitMQ 4.x. El nombre de usuario sigue proviniendo del CN; la versión 3.13 no admite
SAN→client_id. -
Autorización: las ACL de temas están restringidas al prefijo MQTT elegido (además de solo lectura en shellies/command por compatibilidad).
-
Multiarrendamiento: MQTT no transporta vhosts, por lo que las conexiones se enrutan a un vhost dedicado (por ejemplo, /shelly) mediante mqtt.vhost.
-
Gestión: interfaz HTTPS en 15671.
-
Puertos sin cifrar: Desactivados de forma predeterminada. Puedes mantener temporalmente 1883/15672 con --keep-plaintext durante la migración.
Referencia rápida
| Inquietud | Decisión |
|---|---|
| Puerto (datos) | 8883 / TCP (MQTTS con mTLS) |
| Puerto (administración) | 15671 / TCP (interfaz de usuario de gestión HTTPS) |
| Identidad | Certificado CN -> usuario de RabbitMQ |
| ID de cliente | Proporcionado por el usuario en Shelly; en RabbitMQ 4.x se aplica a partir del SAN del certificado (URI). En 3.13, |
| Vhost | /shelly (se establece mediante mqtt.vhost) |
| Temas | Restringido a tu prefijo MQTT (tanto en formato con barra como con punto), además de acceso de solo lectura a |
| Secretos en el dispositivo | Solo la clave del cliente (sin contraseñas) |
| Texto sin cifrar | Desactivado de forma predeterminada; activación opcional con --keep-plaintext |
| Versión de TLS | Solo TLS 1.2 |
Requisitos previos
-
Entorno probado (en el momento de redactar):
Ubuntu 24.04 LTS (amd64),RabbitMQ 4.1(instalado mediante este script), firmware de Shelly1.7.1. -
Instalación: desde los repositorios de Team RabbitMQ fijados para Ubuntu noble.
-
Acceso: Shell en el host con privilegios de sudo; se necesita internet saliente para los repositorios apt.
-
Direccionamiento:
IP/DNSestable del broker (el script puede detectarla automáticamente, pero es mejor fijarla). -
Sincronización horaria: NTP habilitado (la validez del certificado depende de que la hora sea correcta).
-
Opcional:
mosquitto-clientspara realizar rápidamente pruebas de extremo a extremo.
Qué hace el script
-
Instalar RabbitMQ (3.13 / 4.0 / 4.1) y el Erlang correspondiente en Ubuntu 24.04
Utiliza los repositorios apt de Team RabbitMQ (la ruta recomendada actualmente) para obtener versiones modernas de Erlang/RabbitMQ. https://www.rabbitmq.com/docs/install-debian
-
Configurar mediante rabbitmq.conf (no rabbitmq-env.conf)
La configuración en tiempo de ejecución (listeners, TLS y complementos) se encuentra en
rabbitmq.conf;rabbitmq-env.confsolo se utiliza para las variables de entorno. https://www.rabbitmq.com/docs/configure -
Habilitar los complementos de MQTT y gestión
Activa la compatibilidad nativa con MQTT y la gestión/interfaz de usuario HTTPS, y habilita
rabbitmq_auth_mechanism_ssl. https://www.rabbitmq.com/docs/mqtt-
Habilitar
detailed_queues_endpointindicador de función (detalle exclusivo de la interfaz de usuario para las colas).
-
-
Exige TLS mutuo (mTLS) para MQTT
Establece
ssl_options.verify = verify_peeryssl_options.fail_if_no_peer_cert = truepor lo que los clientes deben presentar un certificado válido; fuerza únicamente TLS 1.2. https://www.rabbitmq.com/docs/mqtt#tls -
Inicio de sesión con certificado sin contraseña (CN → usuario)
Habilita
mqtt.ssl_cert_login = trueyssl_cert_login_from = common_nameEl usuario asignado debe existir en RabbitMQ (no se necesita contraseña). https://www.rabbitmq.com/docs/mqtt#tls-certificate-authentication -
Vincula el client_id de MQTT al SAN (URI) del certificado
En RabbitMQ 4.1, establece
mqtt.ssl_cert_client_id_from = subject_alternative_name por lo que el CONNECT client_id debe coincidir con el SAN del certificado (evita la suplantación de identidad). https://www.rabbitmq.com/docs/mqtt#usage-of-client_id-extraction-from-client-certificates-for-authentication
Esto vincula client_id al certificado SAN (URI). Nombre de usuario siga procediendo de CN; si quieres que el nombre de usuario de SAN en su lugar, cambiarías a ssl_cert_login_from=subject_alternative_name y ssl_cert_login_san_type=uri en la configuración.
-
Emitir dos certificados de cliente (mismo CN, SAN distintos)
-
dispositivo:
SAN=URI: -
monitor:
SAN=URI:-mon -
Perfiles de certificados: CA RSA-4096; servidor/cliente RSA-2048; validez de las hojas ≈ 825 días
-
Te permite suscribirte con el certificado de monitorización sin desconectar el dispositivo (ID de cliente distintos).
-
Bloquear los escuchas y puertos
-
MQTTS:
8883 -
Gestión (HTTPS):
15671 -
Sin cifrado 1883/15672 desactivado de forma predeterminada; opcional durante la migración con --keep-plaintext. https://www.rabbitmq.com/docs/networking
-
-
Crear tenencia y permisos
-
Dirige las sesiones MQTT a
/shelly(mediante mqtt.vhost). https://www.rabbitmq.com/docs/vhosts -
Aplica permisos de temas para que publicar/suscribirse se limite a tu prefijo MQTT (además de shellies/command de solo lectura). https://www.rabbitmq.com/docs/man/rabbitmqctl.8#Access_control
-
Elimina el usuario predeterminado guest.
-
Si
set_topic_permissionsno está disponible en tu RabbitMQ, el script avisa y mantiene un acceso más amplio a los temas hasta que actualices.
-
-
Salida que utilizas en Shelly
Escribe una carpeta de exportación con
ca.crt,client.crt,client.keye imprime una tabla con los valores exactos que debes copiar en la configuración de Shelly MQTT.
Implementación
-
Ejecutar el script
./shelly-rmq-mqtt/setup-mqtt-mtls.sh \ --admin-user admin \ --admin-pass 'Sh3lly-i0T!' \ -C 'Shelly-Group' \ --client-id 'test-device' \ --vhost /shelly \ --mqtt-prefix 1pm-mini Precedencia del host de conexión (y CN del certificado): --connect-dns > --connect-ip > --ip (detección automática si no se especifica ninguno). Este valor elegido se convierte en el CN del certificado del servidor y es al que deben conectarse los clientes.
Indicadores útiles (según sea necesario)
Identidad / destino de conexión (al que se conectan los clientes; determina el CN/SAN del certificado) --connect-dns # preferido: los clientes se conectan a este nombre --connect-ip # los clientes se conectan a esta IP (si no hay DNS) Identidad del host (esta máquina) -i | --ip | --server-ip # IP principal detectada por sustitución (usada en el resumen y SAN) MQTT / tenencia / temas -V | --vhost # valor predeterminado /shelly --mqtt-prefix # ámbito de ACL del tema Certificados / resultados --tls-dir # valor predeterminado /etc/rabbitmq-tls --export-dir # valor predeterminado /etc/mqtt-cert --monitor-export-dir # valor predeterminado /etc/mqtt-cert-monitor --no-monitor-cert # omitir -mon bundle --monitor-client-id # valor predeterminado -mon --force-regen # rotar CA/servidor/cliente incluso si ya existen Versionado de RabbitMQ --rmq-series 3.13|4.0|4.1 # valor predeterminado 4.1 Autenticación / usuarios --admin-user # administrador predeterminado -p | --admin-pass # se genera automáticamente de forma predeterminada si se omite -C | --client-cn # Shelly-Group predeterminado --client-id # valor predeterminado = Redes (compatibilidad temporal) --keep-plaintext # mantener abiertos 1883/15672 durante la migración Registro / diagnósticos -l | --log-level debug|info|warn|error -d | --debug # transmitir logs; sin indicador de progreso --debug-tls | --tls-debug # imprimir diagnósticos del certificado (o DEBUG_TLS=1)
El script se ejecutará, recorrerá cada paso y mostrará un indicador de éxito y un error si se produce.
Cuando termine, consulta la tabla de resumen en la parte inferior:
-
IP/puertos del broker
-
ID de cliente y prefijo MQTT
-
Rutas a
ca.crt,client.crt,client.key(carpeta de exportación) -
Opciones de configuración de Shelly
-
URL de administración:
https://(o:15671 https://si CN es una IP):15671 -
Usuario y contraseña de administrador (la contraseña se genera automáticamente, a menos que pases
--admin-pass) -
Ruta del archivo de log:
/tmp/rabbitmq-mqtt-setup.log
-
Subir certificados a Shelly
-
Abre Interfaz web de Shelly → Configuración → Configuración de TLS.
-
Sube los tres archivos de la carpeta de exportación del script:
-
Certificado de CA: ca.crt
-
Certificado del cliente: client.crt
-
Clave privada del cliente: client.key
-
-
Sube cada archivo individualmente: selecciona el archivo, haz clic en Subir y espera la ventana emergente que confirme que se ha realizado correctamente. Repite el proceso con los tres.
-
-
Configurar Shelly MQTT
-
Abre Interfaz web de Shelly → Configuración → MQTT.
-
Configura los valores del script:
-
Habilitar: Seleccionado TLS del usuario: Seleccionado Usar certificado de cliente: Habilitado Habilitar «Control MQTT»: Habilitado Habilitar RPC sobre MQTT: Habilitado Notificaciones de estado de RPC sobre MQTT: Habilitado Actualización de estado genérica sobre MQTT: Habilitado Servidor: Valor del script ID de cliente: Valor del script Prefijo MQTT: Valor del script Nombre de usuario / Contraseña: Dejar en blanco -
Haz clic en Guardar configuración y reinicia el dispositivo
Una vez finalizada la configuración, el dispositivo debería verse así:
-
Después de que Shelly se reinicie, ejecuta el comando de supervisión que muestra el resumen del script. Se genera automáticamente a partir de los valores que proporcionaste y utiliza el certificado de supervisión (con un client_id distinto), por lo que no desconectará el dispositivo. Deberías ver mensajes fluyendo de Shelly a RabbitMQ.
Deberías ver que Shelly se conecta y publica.
También puedes confirmar que la conexión se realizó correctamente en la interfaz web de Shelly: el icono de MQTT de la esquina superior derecha muestra dos flechas cuando está conectado. Si ves las flechas, el dispositivo está vinculado activamente a RabbitMQ mediante MQTT/TLS.
También puedes ver un indicador en la interfaz web de RabbitMQ, en Conexiones
El script también muestra un resumen de depuración de certificados que te ayuda a ver qué certificados se generaron para minimizar los problemas que puedan surgir. Ten en cuenta que debes utilizar la Indicador --debug-tls.
Solución de problemas
-
Sincronización horaria: asegúrate de que los relojes del bróker y de Shelly sean correctos (NTP). Una hora desfasada interrumpe TLS.
-
Se han cargado tres archivos:
ca.crt,client.crt,client.key(cada uno por separado, con una ventana emergente de confirmación). -
Client ID frente a SAN: en RabbitMQ 4.1, el Client ID debe coincidir con el SAN (URI) del certificado. Si difieren, se rechaza la conexión.
-
En RabbitMQ 3.13, no se admite vincular
client_iddesde SAN; solo se utilizaCN->username.
-
-
El usuario del CN existe: el CN del certificado debe coincidir con un usuario existente de RabbitMQ (no se necesita contraseña con mTLS).
-
Puertos: usa 8883 (MQTTS). 1883/15672 están desactivados, a menos que hayas ejecutado el script con --keep-plaintext.
-
Firewall: si UFW está activo, el script abre 8883 y 15671; de lo contrario, no cambia las reglas del firewall.
-
Prefijo: los temas deben estar bajo tu prefijo de MQTT o las ACL de RabbitMQ los bloquearán.
-
Coincidencia entre clave y certificado: Si las conexiones fallan, ejecuta con
--debug-tlsy comprueba la línea “key <-> cert match” tanto para el servidor como para el cliente.

