--- title: "Configurar Mosquitto MQTT con TLS y ACL en Ubuntu 24.04" description: "Configura Mosquitto en Ubuntu 24.04 con TLS de Let's Encrypt, usuarios con contraseña, ACL por topic, WebSockets seguros, puentes y métricas $SYS." category: "Automatización del Hogar e IoT" language: es source: https://cubepath.com/es/docs/automatización-del-hogar-e-iot/configuracion-avanzada-de-mosquitto-mqtt updated: 2026-09-25 --- # Configurar Mosquitto MQTT con TLS y ACL en Ubuntu 24.04 Eclipse Mosquitto es un broker MQTT ligero y muy extendido en proyectos IoT y de domótica. Una instalación por defecto sirve para pruebas, pero expuesta a Internet necesita cifrado, autenticación y control de qué puede leer o escribir cada cliente. En este tutorial configurarás Mosquitto en Ubuntu 24.04 con TLS de Let's Encrypt en el puerto 8883, usuarios con contraseña, listas de control de acceso (ACL) por topic, MQTT sobre WebSockets seguros y, opcionalmente, un puente hacia otro broker. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Un dominio o subdominio (en esta guía `your_domain`) con un registro DNS A apuntando a la IP del servidor. - El puerto 80 libre para que Certbot pueda validar el dominio. - UFW activo con SSH permitido. ## Paso 1: Instalar Mosquitto Ubuntu 24.04 incluye Mosquitto 2.0 en sus repositorios. Instala el broker y los clientes de línea de comandos: ```bash sudo apt update sudo apt install mosquitto mosquitto-clients ``` El servicio arranca automáticamente. Comprueba su estado: ```bash systemctl status mosquitto --no-pager ``` ```output ● mosquitto.service - Mosquitto MQTT Broker Loaded: loaded (/usr/lib/systemd/system/mosquitto.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-24 09:40:11 UTC; 8s ago ``` El archivo principal `/etc/mosquitto/mosquitto.conf` ya activa la persistencia en `/var/lib/mosquitto/`, envía el log a `/var/log/mosquitto/mosquitto.log` e incluye todos los archivos `.conf` de `/etc/mosquitto/conf.d/`. No lo modificarás: toda tu configuración irá en `conf.d`. ## Paso 2: Obtener un certificado de Let's Encrypt Con un certificado de una autoridad pública, los clientes validan el broker usando los certificados raíz del sistema y no tienes que distribuir una CA propia. Instala Certbot y abre el puerto 80 para la validación: ```bash sudo apt install certbot sudo ufw allow 80/tcp ``` Solicita el certificado en modo `standalone`, en el que Certbot levanta un servidor web temporal: ```bash sudo certbot certonly --standalone -d your_domain ``` ```output Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem ``` Mosquitto se ejecuta con el usuario `mosquitto`, que no puede leer `/etc/letsencrypt/live`. En lugar de cambiar los permisos de ese directorio, crea un hook de despliegue que copie el certificado a `/etc/mosquitto/certs` y reinicie el broker en cada renovación: ```bash sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto.sh ``` ```bash #!/usr/bin/env bash set -euo pipefail domain="your_domain" # Solo actuar cuando se renueva el certificado del broker if [ "${RENEWED_LINEAGE}" != "/etc/letsencrypt/live/${domain}" ]; then exit 0 fi install -o mosquitto -g mosquitto -m 0644 "${RENEWED_LINEAGE}/fullchain.pem" /etc/mosquitto/certs/fullchain.pem install -o mosquitto -g mosquitto -m 0600 "${RENEWED_LINEAGE}/privkey.pem" /etc/mosquitto/certs/privkey.pem systemctl restart mosquitto ``` Hazlo ejecutable y ejecútalo una vez a mano para copiar el certificado actual: ```bash sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/mosquitto.sh sudo RENEWED_LINEAGE=/etc/letsencrypt/live/your_domain /etc/letsencrypt/renewal-hooks/deploy/mosquitto.sh sudo ls -l /etc/mosquitto/certs/*.pem ``` ```output -rw-r--r-- 1 mosquitto mosquitto 2864 Sep 24 09:45 /etc/mosquitto/certs/fullchain.pem -rw------- 1 mosquitto mosquitto 241 Sep 24 09:45 /etc/mosquitto/certs/privkey.pem ``` ## Paso 3: Crear los usuarios Crea el archivo de contraseñas con el primer usuario, `admin`. La opción `-c` crea el archivo y lo sobrescribiría si ya existiera, así que úsala solo esta vez: ```bash sudo mosquitto_passwd -c /etc/mosquitto/passwd admin ``` Añade el resto de usuarios sin `-c`. En este ejemplo, un sensor y una aplicación de panel que solo lee datos: ```bash sudo mosquitto_passwd /etc/mosquitto/passwd sensor01 sudo mosquitto_passwd /etc/mosquitto/passwd dashboard ``` Cada comando pide la contraseña dos veces. Las contraseñas se guardan con hash, nunca en claro. Ajusta los permisos para que solo root y el grupo `mosquitto` puedan leer el archivo: ```bash sudo chown root:mosquitto /etc/mosquitto/passwd sudo chmod 640 /etc/mosquitto/passwd ``` Para eliminar un usuario más adelante, usa `sudo mosquitto_passwd -D /etc/mosquitto/passwd nombre_usuario` y reinicia Mosquitto. ## Paso 4: Definir las ACL Las ACL limitan a qué topics puede suscribirse o publicar cada usuario. Crea el archivo: ```bash sudo nano /etc/mosquitto/acl ``` ```text # Administrador: acceso total, incluidas las estadísticas del broker user admin topic readwrite # topic read $SYS/# # Panel: solo lee lecturas de sensores user dashboard topic read sensores/# topic write comandos/# # Reglas para todos los usuarios: %u se sustituye por el nombre de usuario. # Cada sensor solo publica en su propia rama y solo lee sus comandos. pattern write sensores/%u/# pattern read comandos/%u/# ``` Reglas a tener en cuenta: - Las líneas `topic` se aplican al último `user` declarado encima. Las líneas `pattern` se aplican a todos los usuarios. - El comodín `#` no incluye los topics que empiezan por `$SYS`, por eso `admin` necesita su propia regla. - Lo que no está permitido explícitamente queda denegado. Ajusta los permisos igual que el archivo de contraseñas: ```bash sudo chown root:mosquitto /etc/mosquitto/acl sudo chmod 640 /etc/mosquitto/acl ``` ## Paso 5: Configurar los listeners Vas a definir tres puntos de escucha: MQTT sin cifrar solo en localhost (para servicios del propio servidor, como Home Assistant o Node-RED), MQTT con TLS en el 8883 y MQTT sobre WebSockets con TLS en el 8084 para clientes web. Crea el archivo: ```bash sudo nano /etc/mosquitto/conf.d/broker.conf ``` ```ini # Autenticación y ACL comunes a todos los listeners per_listener_settings false allow_anonymous false password_file /etc/mosquitto/passwd acl_file /etc/mosquitto/acl # Persistencia y límites autosave_interval 300 max_queued_messages 1000 max_packet_size 262144 # MQTT sin cifrar, solo accesible desde el propio servidor listener 1883 localhost # MQTT sobre TLS listener 8883 certfile /etc/mosquitto/certs/fullchain.pem keyfile /etc/mosquitto/certs/privkey.pem # MQTT sobre WebSockets con TLS listener 8084 protocol websockets certfile /etc/mosquitto/certs/fullchain.pem keyfile /etc/mosquitto/certs/privkey.pem ``` | Opción | Función | |---|---| | `per_listener_settings false` | Aplica la autenticación y las ACL a todos los listeners por igual. | | `allow_anonymous false` | Rechaza clientes sin usuario y contraseña. | | `autosave_interval 300` | Guarda la base de persistencia en disco cada 300 segundos, además de al detener el servicio. | | `max_queued_messages 1000` | Mensajes máximos en cola por cliente desconectado con sesión persistente. | | `max_packet_size 262144` | Rechaza paquetes de más de 256 KB. | Reinicia Mosquitto y comprueba que escucha en los tres puertos: ```bash sudo systemctl restart mosquitto sudo ss -tlnp | grep mosquitto ``` ```output LISTEN 0 100 127.0.0.1:1883 0.0.0.0:* users:(("mosquitto",pid=6120,fd=5)) LISTEN 0 100 0.0.0.0:8883 0.0.0.0:* users:(("mosquitto",pid=6120,fd=7)) LISTEN 0 100 0.0.0.0:8084 0.0.0.0:* users:(("mosquitto",pid=6120,fd=9)) ``` Si el servicio no arranca, el motivo aparece al final del log: ```bash sudo tail -n 20 /var/log/mosquitto/mosquitto.log ``` Abre los puertos cifrados en el firewall. El 1883 queda cerrado al exterior porque solo escucha en localhost: ```bash sudo ufw allow 8883/tcp sudo ufw allow 8084/tcp ``` ## Paso 6: Probar TLS, autenticación y ACL Desde tu equipo (o desde el propio servidor), abre un suscriptor con el usuario `dashboard`. La opción `--capath /etc/ssl/certs` hace que el cliente valide el certificado con las raíces del sistema: ```bash mosquitto_sub -h your_domain -p 8883 --capath /etc/ssl/certs -u dashboard -P 'dashboard_password' -t 'sensores/#' -v ``` En otra terminal, publica una lectura como `sensor01` en su propia rama: ```bash mosquitto_pub -h your_domain -p 8883 --capath /etc/ssl/certs -u sensor01 -P 'sensor01_password' -t sensores/sensor01/temperatura -m 21.5 ``` El suscriptor recibe el mensaje: ```output sensores/sensor01/temperatura 21.5 ``` Ahora comprueba que la ACL funciona: `sensor01` intenta publicar en la rama de otro sensor. ```bash mosquitto_pub -h your_domain -p 8883 --capath /etc/ssl/certs -u sensor01 -P 'sensor01_password' -t sensores/sensor02/temperatura -m 99 ``` El suscriptor no recibe nada: Mosquitto descarta en silencio las publicaciones no autorizadas. Por último, prueba que un cliente sin credenciales es rechazado: ```bash mosquitto_pub -h your_domain -p 8883 --capath /etc/ssl/certs -t prueba -m hola ``` ```output Connection error: Connection Refused: not authorised. Error: The connection was refused. ``` Para el listener de WebSockets, los clientes web (por ejemplo con la librería MQTT.js) se conectan a `wss://your_domain:8084` con los mismos usuarios. ## Paso 7: Crear un puente hacia otro broker (opcional) Un puente (bridge) reenvía topics entre dos brokers. Es habitual en una pasarela local que envía sus lecturas a un broker central. Esta configuración va en el broker **local** que inicia la conexión, no en el central. Crea el archivo: ```bash sudo nano /etc/mosquitto/conf.d/bridge.conf ``` ```ini connection central address central.example.com:8883 bridge_capath /etc/ssl/certs remote_clientid gateway01 remote_username gateway01 remote_password your_bridge_password cleansession false # Envía las lecturas locales al central con el prefijo edificio1/ topic sensores/# out 1 "" edificio1/ # Recibe del central los comandos para esta pasarela topic comandos/# in 1 "" edificio1/ ``` El formato de `topic` es `patrón dirección QoS prefijo-local prefijo-remoto`. Con esta configuración, `sensores/sensor01/temperatura` se publica en el central como `edificio1/sensores/sensor01/temperatura`. En el broker central, el usuario `gateway01` necesita permisos de escritura en `edificio1/sensores/#` y de lectura en `edificio1/comandos/#`. Reinicia y revisa el log: ```bash sudo systemctl restart mosquitto sudo grep -i bridge /var/log/mosquitto/mosquitto.log | tail -n 5 ``` ```output 1727171234: Connecting bridge central (central.example.com:8883) ``` ## Paso 8: Monitorizar el broker con $SYS Mosquitto publica estadísticas en los topics `$SYS/#` cada 10 segundos. Consulta el número de clientes conectados con el usuario `admin` (la opción `-C 1` sale tras recibir un mensaje): ```bash mosquitto_sub -h localhost -p 1883 -u admin -P 'admin_password' -t '$SYS/broker/clients/connected' -C 1 -v ``` ```output $SYS/broker/clients/connected 3 ``` Otros topics útiles: | Topic | Qué indica | |---|---| | `$SYS/broker/version` | Versión del broker. | | `$SYS/broker/messages/received` | Mensajes recibidos desde el arranque. | | `$SYS/broker/load/messages/received/1min` | Media de mensajes recibidos por minuto. | | `$SYS/broker/store/messages/count` | Mensajes retenidos o en cola almacenados. | ## Solución de problemas **`Connection Refused: not authorised` con credenciales correctas**: el usuario no existe en `/etc/mosquitto/passwd` o Mosquitto no puede leer el archivo. Comprueba los permisos (`root:mosquitto`, `640`) y reinicia el servicio tras añadir usuarios. **Error TLS `certificate verify failed`**: el cliente se conecta por IP en lugar de por `your_domain`, o no tiene las raíces de confianza. Usa siempre el nombre del certificado y `--capath /etc/ssl/certs` (o `--cafile` con la ruta del bundle de tu sistema). **Mosquitto no arranca tras editar la configuración**: una opción mal escrita o un archivo de certificado ilegible. El log `/var/log/mosquitto/mosquitto.log` indica la línea exacta del error. **Un cliente publica pero nadie recibe los mensajes**: casi siempre es una ACL. Revisa que la regla cubre el topic exacto y recuerda que las líneas `topic` pertenecen al `user` anterior. ## Conclusión Tu broker Mosquitto acepta solo conexiones cifradas desde el exterior, exige usuario y contraseña, limita los topics de cada cliente mediante ACL, sirve a clientes web por WebSockets seguros y renueva su certificado automáticamente. El listener local sin cifrar queda disponible para servicios del propio servidor. Como siguientes pasos puedes: - Conectar Home Assistant o Node-RED al listener local `127.0.0.1:1883`. - Guardar las lecturas de los sensores en una base de datos de series temporales y visualizarlas en Grafana. - Pasar a autenticación con certificados de cliente (`require_certificate`) para dispositivos que no deben usar contraseña.