Configuración Avanzada del Broker MQTT Mosquitto

Mosquitto es el broker MQTT de referencia en entornos IoT, capaz de gestionar miles de conexiones simultáneas con un consumo de recursos mínimo. Una configuración básica es suficiente para prototipos, pero en producción necesitas TLS para cifrado, autenticación por usuario o certificado, listas de control de acceso (ACL) y puentes para conectar múltiples brokers. Esta guía cubre todas estas características avanzadas de Mosquitto en Linux, junto con soporte WebSocket, persistencia y monitoreo.

Requisitos Previos

  • Ubuntu 20.04/22.04 o CentOS/Rocky 8/9
  • Acceso root o usuario con sudo
  • OpenSSL instalado para la generación de certificados
  • Puertos 1883 (MQTT), 8883 (MQTT/TLS) y 9001 (WebSocket) disponibles
# Verificar que los puertos no están en uso
ss -tlnp | grep -E '1883|8883|9001'

# Verificar la versión de OpenSSL
openssl version

Instalación de Mosquitto

Ubuntu/Debian

# Actualizar el sistema e instalar Mosquitto
sudo apt-get update
sudo apt-get install -y mosquitto mosquitto-clients

# Habilitar e iniciar el servicio
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

# Verificar que está activo
sudo systemctl status mosquitto
mosquitto -v

CentOS/Rocky Linux

# Instalar el repositorio EPEL
sudo dnf install -y epel-release

# Instalar Mosquitto
sudo dnf install -y mosquitto

# Habilitar e iniciar el servicio
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

La configuración principal está en /etc/mosquitto/mosquitto.conf y los archivos adicionales en /etc/mosquitto/conf.d/.

Configuración de TLS/SSL

El cifrado TLS es imprescindible en producción para proteger los datos de los dispositivos IoT en tránsito.

Generar los certificados

# Crear el directorio para los certificados
sudo mkdir -p /etc/mosquitto/certs
cd /tmp

# Paso 1: Crear la CA (Autoridad Certificadora) propia
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt \
  -subj "/C=ES/ST=Madrid/O=MiEmpresa/CN=MQTT-CA"

# Paso 2: Crear la clave y el certificado del servidor
openssl genrsa -out servidor.key 2048
openssl req -new -key servidor.key -out servidor.csr \
  -subj "/C=ES/ST=Madrid/O=MiEmpresa/CN=mqtt.tudominio.com"

# Firmar el certificado del servidor con la CA
openssl x509 -req -days 730 -in servidor.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out servidor.crt

# Copiar los certificados al directorio de Mosquitto
sudo cp ca.crt servidor.crt servidor.key /etc/mosquitto/certs/
sudo chown mosquitto:mosquitto /etc/mosquitto/certs/*
sudo chmod 640 /etc/mosquitto/certs/*

Configurar Mosquitto con TLS

# Crear el archivo de configuración TLS
sudo tee /etc/mosquitto/conf.d/tls.conf << 'EOF'
# Listener MQTT sin TLS (solo para conexiones locales)
listener 1883 localhost

# Listener MQTT con TLS para conexiones externas
listener 8883
certfile /etc/mosquitto/certs/servidor.crt
keyfile /etc/mosquitto/certs/servidor.key
cafile /etc/mosquitto/certs/ca.crt

# Requerir certificado de cliente (opcional, para autenticación mutua)
# require_certificate true
# use_identity_as_username true

# Versiones TLS permitidas (deshabilitar versiones inseguras)
tls_version tlsv1.2 tlsv1.3
EOF

# Reiniciar Mosquitto para aplicar los cambios
sudo systemctl restart mosquitto

# Probar la conexión TLS
mosquitto_pub -h localhost -p 8883 \
  --cafile /etc/mosquitto/certs/ca.crt \
  -t "prueba/tls" -m "Mensaje cifrado"

Autenticación de Usuarios

Autenticación por contraseña

# Crear el archivo de contraseñas y añadir el primer usuario
sudo mosquitto_passwd -c /etc/mosquitto/passwd admin

# Añadir usuarios adicionales (sin la bandera -c para no sobreescribir)
sudo mosquitto_passwd /etc/mosquitto/passwd sensor01
sudo mosquitto_passwd /etc/mosquitto/passwd aplicacion

# Cambiar la contraseña de un usuario existente
sudo mosquitto_passwd /etc/mosquitto/passwd admin

# Eliminar un usuario
sudo mosquitto_passwd -D /etc/mosquitto/passwd usuario-viejo

# Configurar Mosquitto para usar autenticación por contraseña
sudo tee /etc/mosquitto/conf.d/auth.conf << 'EOF'
# Deshabilitar acceso anónimo
allow_anonymous false

# Archivo de contraseñas
password_file /etc/mosquitto/passwd
EOF

sudo systemctl restart mosquitto

Plugin de autenticación con base de datos

# Instalar el plugin mosquitto-auth-plug para autenticación avanzada
sudo apt-get install -y libmosquitto-dev libssl-dev

# Alternativa: usar mosquitto-go-auth (más moderno)
# Descargar el plugin precompilado
wget https://github.com/iegomez/mosquitto-go-auth/releases/download/2.0.0/go-auth.so

sudo cp go-auth.so /etc/mosquitto/

# Configurar autenticación contra MySQL/PostgreSQL
sudo tee /etc/mosquitto/conf.d/auth-db.conf << 'EOF'
auth_plugin /etc/mosquitto/go-auth.so
auth_opt_log_level debug
auth_opt_backend mysql

# Conexión a la base de datos
auth_opt_mysql_host localhost
auth_opt_mysql_port 3306
auth_opt_mysql_dbname mqtt_auth
auth_opt_mysql_user mosquitto
auth_opt_mysql_password TuPasswordSeguro

# Consultas SQL para autenticación
auth_opt_mysql_userquery SELECT password_hash FROM usuarios WHERE username = ? AND activo = 1 LIMIT 1
auth_opt_mysql_superquery SELECT COUNT(*) FROM usuarios WHERE username = ? AND es_admin = 1
auth_opt_mysql_aclquery SELECT topic FROM permisos WHERE username = ? AND rw >= ?
EOF

Listas de Control de Acceso (ACL)

Las ACL definen qué topics puede publicar o suscribirse cada usuario:

# Crear el archivo ACL
sudo tee /etc/mosquitto/acl << 'EOF'
# Sintaxis:
# topic [read|write|readwrite] <patron-topic>
# user <nombre-usuario>
# topic [read|write|readwrite] <patron-topic>

# Reglas globales (para todos los usuarios)
# Permitir leer el topic de estado del sistema a todos
topic read sistema/estado

# Reglas para el usuario 'admin'
user admin
topic readwrite #

# Reglas para sensores (solo pueden publicar en su propio topic)
user sensor01
topic write sensores/sala/+
topic read configuracion/sensor01

user sensor02
topic write sensores/cocina/+
topic read configuracion/sensor02

# Reglas para la aplicación de visualización
user aplicacion
topic read sensores/#
topic read alertas/#
topic write comandos/+

# Patrón con comodín: el usuario solo puede acceder a topics con su nombre
# (requiere plugin compatible con variables de usuario)
# topic read usuarios/%u/#
EOF

# Configurar Mosquitto para usar el archivo ACL
sudo tee -a /etc/mosquitto/conf.d/auth.conf << 'EOF'

# Archivo de listas de control de acceso
acl_file /etc/mosquitto/acl
EOF

sudo chmod 640 /etc/mosquitto/acl
sudo chown mosquitto:mosquitto /etc/mosquitto/acl
sudo systemctl restart mosquitto

Soporte WebSocket

WebSocket permite que las aplicaciones web se conecten directamente al broker MQTT desde el navegador:

# Añadir configuración de WebSocket
sudo tee /etc/mosquitto/conf.d/websocket.conf << 'EOF'
# Listener WebSocket sin TLS (para desarrollo)
listener 9001
protocol websockets

# Listener WebSocket con TLS (para producción)
listener 9443
protocol websockets
certfile /etc/mosquitto/certs/servidor.crt
keyfile /etc/mosquitto/certs/servidor.key
cafile /etc/mosquitto/certs/ca.crt
EOF

sudo systemctl restart mosquitto

# Verificar que los puertos WebSocket están activos
ss -tlnp | grep -E '9001|9443'

Ejemplo de conexión desde JavaScript con la librería MQTT.js:

// Conexión WebSocket desde el navegador
const mqtt = require('mqtt');

const cliente = mqtt.connect('wss://mqtt.tudominio.com:9443', {
    username: 'aplicacion',
    password: 'tu-password',
    // Certificado CA para validar el servidor
    ca: fs.readFileSync('ca.crt')
});

cliente.on('connect', () => {
    console.log('Conectado al broker MQTT');
    cliente.subscribe('sensores/#');
});

cliente.on('message', (topic, mensaje) => {
    console.log(`${topic}: ${mensaje.toString()}`);
});

Puentes entre Brokers

Los puentes (bridges) sincronizan topics entre dos brokers Mosquitto, útil para arquitecturas distribuidas o para reenviar datos de brokers locales a la nube:

# Configurar un puente entre el broker local y un broker central en la nube
sudo tee /etc/mosquitto/conf.d/bridge.conf << 'EOF'
# Definición del puente hacia el broker central
connection puente-central
# Dirección del broker remoto
address mqtt.central.tudominio.com:8883

# Credenciales para el broker remoto
remote_username puente-local
remote_password TuPasswordDelPuente

# Certificados TLS para la conexión del puente
bridge_cafile /etc/mosquitto/certs/ca.crt
bridge_certfile /etc/mosquitto/certs/servidor.crt
bridge_keyfile /etc/mosquitto/certs/servidor.key

# Topics a sincronizar
# Formato: topic <patron> [direction] [qos] [prefijo-local] [prefijo-remoto]

# Enviar lecturas de sensores al broker central (dirección: out)
topic sensores/# out 1 "" sede-madrid/

# Recibir comandos del broker central (dirección: in)
topic comandos/# in 1 sede-madrid/ ""

# Sincronización bidireccional del estado
topic estado/# both 1 "" sede-madrid/

# Mantener el puente activo aunque no haya mensajes
keepalive_interval 60
start_type automatic
restart_timeout 30
EOF

sudo systemctl restart mosquitto

# Verificar el estado del puente en los logs
sudo journalctl -u mosquitto -f --no-pager | grep -i bridge

Persistencia y Retención de Mensajes

# Configurar la persistencia para sobrevivir reinicios
sudo tee /etc/mosquitto/conf.d/persistencia.conf << 'EOF'
# Habilitar la persistencia de sesiones y mensajes
persistence true
persistence_location /var/lib/mosquitto/

# Guardar datos cada 60 segundos y tras cada 1000 mensajes
autosave_interval 60
autosave_on_changes false

# Registro de actividad
log_dest file /var/log/mosquitto/mosquitto.log
log_type error warning notice information
log_timestamp true

# Límites de conexión y mensajes
max_connections 10000
max_queued_messages 1000
message_size_limit 10240
EOF

# Crear el directorio de datos con los permisos correctos
sudo mkdir -p /var/lib/mosquitto
sudo chown mosquitto:mosquitto /var/lib/mosquitto

sudo systemctl restart mosquitto

Monitoreo y Métricas

Mosquitto publica estadísticas propias en el topic $SYS:

# Suscribirse a todas las estadísticas del sistema
mosquitto_sub -h localhost -u admin -P tu-password \
  -t '$SYS/#' -v

# Topics de métricas más útiles
mosquitto_sub -h localhost -u admin -P tu-password \
  -t '$SYS/broker/clients/connected' \
  -t '$SYS/broker/messages/received' \
  -t '$SYS/broker/messages/sent' \
  -t '$SYS/broker/publish/messages/received' \
  -v

# Exportar métricas a Prometheus con mqtt-exporter
docker run -d \
  --name mqtt-exporter \
  -p 9641:9641 \
  -e MQTT_ADDRESS=tu-broker:1883 \
  -e MQTT_USERNAME=admin \
  -e MQTT_PASSWORD=tu-password \
  kpetrem/mqtt-exporter

Solución de Problemas

Error "Connection refused" al conectar:

# Verificar que Mosquitto está escuchando en el puerto correcto
ss -tlnp | grep 1883

# Ver los logs de Mosquitto
sudo journalctl -u mosquitto --no-pager -n 50

# Verificar la configuración sin reiniciar
sudo mosquitto -c /etc/mosquitto/mosquitto.conf -v

Error de autenticación (código 5):

# Verificar que el usuario existe en el archivo de contraseñas
sudo cat /etc/mosquitto/passwd

# Probar la conexión con credenciales explícitas
mosquitto_pub -h localhost -u admin -P password -t "prueba" -m "test" -d

# Ver si allow_anonymous está configurado correctamente
grep allow_anonymous /etc/mosquitto/conf.d/*.conf

El puente no se conecta:

# Ver los logs del puente
sudo journalctl -u mosquitto | grep -i "bridge\|connection"

# Probar la conectividad al broker remoto
mosquitto_pub -h mqtt.central.tudominio.com -p 8883 \
  --cafile /etc/mosquitto/certs/ca.crt \
  -u puente-local -P password \
  -t "prueba" -m "test"

Clientes desconectados frecuentemente:

# Aumentar el límite de keepalive y revisar la configuración de red
# En el archivo de configuración principal:
echo "keepalive_interval 120" | sudo tee -a /etc/mosquitto/conf.d/red.conf

# Verificar los límites del sistema operativo
ulimit -n
# Si es bajo, aumentarlo en /etc/security/limits.conf
echo "mosquitto soft nofile 65536" | sudo tee -a /etc/security/limits.conf

Conclusión

Una configuración avanzada de Mosquitto transforma el broker en una infraestructura MQTT robusta y segura, capaz de soportar despliegues IoT en producción con miles de dispositivos conectados. La combinación de TLS, autenticación granular, ACL y puentes entre brokers proporciona tanto la seguridad como la flexibilidad necesaria para arquitecturas distribuidas. Con WebSocket habilitado y métricas expuestas a Prometheus, puedes monitorear el estado del broker en tiempo real e integrarlo con tus dashboards existentes de Grafana.