Instalar broker MQTT con autenticación en Raspberry Pi
MQTT (Message Queue Telemetry Transport) es un protocolo estándar de mensajería entre dispositivos del Internet of Things (IoT). El software que sirve como nexo de unión a todos los dispositivos que utilizan este protocolo se denomina broker. Vamos a instalar mosquitto, uno de los brokers más conocidos, y a configurar la autenticación por usuario y contraseña.
MQTT funciona siguiendo un modelo de publicación-subscripción. Los dispositivos se suscriben a uno o varios topics o temas, que consisten en una ruta jerárquica separada por la barra inclinada, y recibirán todos los mensajes publicados sobre ese topic. Podemos tener por ejemplo un tema raíz que se llama hogar y dentro de él podemos tener temas que representen las estancias, como hogar/dormitorio, hogar/cocina u hogar/salon. Podríamos detallar todos los niveles que queramos: hogar/salon/temperatura o hogar/salon/lampara_techo. Cualquier dispositivo puede publicar un mensaje en uno de esos topics y automáticamente todos los que estén suscritos a ese topic lo recibirán.
Para hacer todo esto posible es necesario un software que actúe como servidor, denominado broker. Vamos a proceder a la instalación y configuración de mosquitto, el servidor MQTT más conocido, en una Raspberry Pi. Podemos instalar mosquitto a través del gestor de paquetes de nuestra distribución Linux o utilizar un contenedor. Nos centraremos en el primer sistema.
Mosquitto está disponible en los repositorios oficiales de la Raspberry Pi. Para instalarlo ejecutamos lo siguiente:
sudo apt-get install -y mosquitto
Para configurar el servicio de manera que se exija autenticación para la publicación y la suscripción, tenemos en primer lugar de asegurarnos de que el servicio está parado:
sudo systemctl stop mosquitto
Creamos un archivo de credenciales al que añadimos un usuario. En este caso añadimos el usuario zigbee
con el siguiente comando que nos pedirá la contraseña de forma interactiva dos veces:
sudo mosquitto_passwd -c /etc/mosquitto/users zigbee
Podemos añadir más usuarios al archivo, o cambiar la contraseña a un usuario existente, eliminando el parámetro -c
:
sudo mosquitto_passwd /etc/mosquitto/users zigbee
Si queremos eliminar un usuario del archivo, utilizaremos el parámetro -D
:
sudo mosquitto_passwd -D /etc/mosquitto/users usuario_a_eliminar
Una vez agregados los usuarios que necesitemos, eliminamos permisos de lectura sobre el archivo de credenciales para los usuarios en general:
sudo chgrp mosquitto /etc/mosquitto/users
sudo chmod o-r /etc/mosquitto/users
Para activar la autenticación en el servicio en base a este archivo de credenciales podemos editar el archivo /etc/mosquitto/mosquitto.conf
o crear un archivo nuevo en el directorio /etc/mosquitto/conf.d/
. En ambos casos debemos incluir la instrucción password_file
y la ruta del archivo de credenciales. La siguiente instrucción utiliza la segunda opción:
echo -e "password_file /etc/mosquitto/users\nlistener 1883\nallow_anonymous false" | sudo tee /etc/mosquitto/conf.d/auth.conf
Ahora pasamos a activar el servicio para que arranque al inicio del sistema:
sudo systemctl enable mosquitto.service
Y lo arrancamos con la configuración aplicada:
sudo systemctl start mosquitto.service
Comprobamos que el servicio está activo:
sudo systemctl status mosquitto
mosquitto.service - Mosquitto MQTT Broker
Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-01-20 13:23:54 CET; 5s ago
Docs: man:mosquitto.conf(5)
man:mosquitto(8)
Para comprobar que está funcionando correctamente, desde la propia Raspberry Pi podemos instalarnos la herramienta cliente:
sudo apt-get install -y mosquitto-clients
Utilizamos el comando mosquitto_sub
para suscribirnos a un topic, en este caso rpi/test
, sin autenticar. Si hemos configurado correctamente el servicio, esta operación debe dar un error de autorización:
mosquitto_sub -d -h localhost -p 1883 -t "rpi/test"
Client (null) sending CONNECT
Client (null) received CONNACK (5)
Connection error: Connection Refused: not authorised.
Client (null) sending DISCONNECT
Ahora probamos de nuevo el comando de suscripción, incluyendo el usuario (parámetro -u
) y la contraseña (parámetro -P
):
mosquitto_sub -d -h localhost -p 1883 -u zigbee -P contraseña -t "rpi/test"
Publicamos un valor en ese topic utilizando el comando mosquitto_pub
:
mosquitto_pub -d -h localhost -p 1883 -t "rpi/test" -u zigbee -P contraseña -m "Buenos días"
y comprobamos que es recibido en el otro lado:
Client (null) received PUBLISH (d0, q0, r0, m0, 'rpi/test', ... (10 bytes))
Buenos días
Ahora podemos repetir la prueba desde otro equipo distinto de la Rpi. El comando será el mismo, pero en el parámetro -h
indicaremos la dirección IP de la RPi en lugar de localhost (en el ejemplo la dirección de la RPi es 192.168.1.10).
mosquitto_sub -d -h 192.168.1.0 -p 1883 -u zigbee -P contraseña -t "rpi/test"
Si en la RPi está activado el firewall, habrá que permitir el puerto 1883/tcp, que es el que utiliza MQTT, por defecto o desactivar el firewall para poder conectar.
A continuación publicaremos un mensaje en el topic rpi/test
, también desde otro equipo:
mosquitto_pub -d -h 192.168.1.10 -p 1883 -t "rpi/test" -u zigbee -P contraseña -m "Saludos"
en la sesión de suscripción recibimos:
Client null sending PINGREQ
Client null received PINGRESP
Client null received PUBLISH (d0, q0, r0, m0, 'rpi/test', ... (7 bytes))
Saludos
Ya tenemos disponible nuestro broker, que será la base para interconectar muchos disposititos IoT. Esto puede ser de utilidad para controlar o recibir información de dispositivos IoT Wifi basados en el chip ESP8266 o ESP32 con el firmware Espurna o Tasmota. También para gestionar dispositivos Zigbee a través de zigbee2mqtt. En otros tutoriales veremos cómo trabajar con algunos de ellos.