Esta práctica es un paso a paso para instalar, configurar y securizar Mosquitto y Node-RED en Raspberry Pi.
Un ejemplo de cómo usar esta instalación en Raspberry Pi una vez finalizada con Raspberry Pi.
Instalar Mosquitto
Comandos para instalar mosquitto:
- wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key – Para usar el nuevo repositorio, primero se debe importar la clave de firma del paquete del repositorio
- sudo apt-key add mosquitto-repo.gpg.key – añade la clave de firma
- cd /etc/apt/sources.list.d/ – Hacer que el repositorio esté disponible para apt
- sudo wget http://repo.mosquitto.org/debian/mosquitto-buster.list – añadir el nuevo repositorio
- sudo apt-get update – Actualizar información de apt
- sudo apt-cache mosquitto – Comprobar paquetes
- sudo apt-get install mosquitto – Instalar
- sudo systemctl enable mosquitto.service – Configurar arranque al inicio
Documentación: https://mosquitto.org/blog/2013/01/mosquitto-debian-repository/
Configurar Mosquitto
NOTA para mosquitto 2.x: https://mosquitto.org/blog/2020/12/version-2-0-0-released/
Mosquitto 2.x ahora es más seguro de forma predeterminada y requiere que los usuarios tomen una decisión activa sobre cómo configurar la seguridad en su broker, en lugar de posiblemente depender del comportamiento anterior muy permisivo, así como eliminar el acceso privilegiado más rápidamente.
Cuando Mosquitto se ejecuta sin un archivo de configuración, o sin configurar ningún listener, ahora se vinculará a las interfaces de loopback 127.0.0.1 y / o :: 1. Esto significa que solo serán posibles las conexiones desde el host local.
La ejecución del broker con un listener definido se vinculará de forma predeterminada a 0.0.0.0 / :: y, por lo tanto, será accesible desde cualquier interfaz.
Todos los listener ahora tienen el valor predeterminado allow_anonymous false a menos que se establezca explícitamente como verdadero en el archivo de configuración. Esto significa que al configurar un listener, el usuario debe configurar un método de control de acceso y autenticación, o establecer allow_anonymous como true.
Documentación: https://mosquitto.org/documentation/migrating-to-2-0/
Para que mosquitto 2.x pueda escuchar en todas las IPs añadir, ejecutar sudo nano /etc/mosquitto/mosquitto.conf y añadir las líneas:
- # Note that this will not allow anonymous access by default.
- listener 1883
Para activar el log de mosquito, ejecutar sudo nano /etc/mosquitto/mosquitto.conf y añadir las líneas:
- # Save all log in file
- log_dest file /var/log/mosquitto/mosquitto.log
- log_type all
- log_timestamp true
Reiniciar mosquitto: sudo systemctl restart mosquitto
NOTA para mosquitto 2.x: hasta no configurar los usuarios, aun no es posible conectarse al Broker fuera del localhost
Autenticación en Mosquitto
Crear fichero de contraseñas con: sudo mosquitto_passwd -c /etc/mosquitto/passwd curso_iot y poner contraseña. Esto crea el usuario curso_iot
Para añadir más usuarios: mosquitto_passwd -b passwordfile curso_iot_2 password Esto crea el usuario curso_iot_2 con la contraseña password
Reiniciar mosquitto: sudo systemctl restart mosquitto
Ahora es posible acceder al broker y probar conexión usando un cliente MQTT como http://mqtt-explorer.com/
Autorización en Mosquitto
Los usuarios creados tienen acceso a todos los topics, para limitar los permisos de acceso hay que configurar las ACLs (Listas de acceso).
Crear fichero aclfile:
- cd /etc/mosquitto
- sudo nano aclfile
Añadir este contenido:
# This only affects clients with username
user curso_iot
topic readwrite #
topic read $SYS/#
user curso_iot_2
topic readwrite curso_iot/#
topic read sololectura/#
# This affects all clients.
pattern write $SYS/broker/connection/%c/state
El usuario curso_iot tiene acceso completo y el usuario curso_iot_2 tiene acceso a los topics curso_iot/# y solo puede leer en los topics sololectura/#
Luego activar el fichero de ACL en la configuración de mosquitto. Ejecutar sudo nano /etc/mosquitto/mosquitto.conf y añadir la línea:
- acl_file /etc/mosquitto/aclfile
Reiniciar mosquitto: sudo systemctl restart mosquitto
Comprobar con los usuarios creados los permisos usando un cliente MQTT como MQTT Explorer.
Más información sobre la configuración: https://mosquitto.org/man/mosquitto-conf-5.html
Comunicación Segura
Generar Certificado Autofirmado
Mosquitto proporciona soporte TLS para conexiones de red cifradas y autenticación.
Es muy fácil crear sus propios certificados SSL y claves de cifrado utilizando herramientas de software libre. Estas claves y certificados son tan seguros como los comerciales.
Utilizaremos openssl para crear nuestra propia autoridad de certificación (CA), claves de servidor y certificados.
Estos pasos nos permitirán una conexión encriptada entre el broker MQTT y el cliente MQTT al igual que la que existe entre un cliente del navegador web y un servidor web. En este caso sólo necesitamos un certificado de servidor de confianza en el Cliente.
El servidor/broker necesita:
- Certificado CA de la CA (autoridad de certificación) que ha firmado el certificado del servidor en el Broker Mosquitto (ca.crt)
- Certificado del servidor certificado por la CA. (srv.crt)
- Clave privada del servidor para el descifrado. (server.key)
Pasos:
- sudo apt-get install openssl – instalar openssl
- Crear un directorio llamado certificados en /home/pi con: mkdir certificados y entrar en el directorio para guardar los certificados y claves
- openssl genrsa -des3 -out ca.key 2048 – Genera una RSA key privada para la CA. Pide contraseña (opción -des3)
- openssl req -new -x509 -days 1826 -key ca.key -out ca.crt – Crear un certificado para la CA utilizando la clave de la CA que creamos en el paso anterior. Poner en CN el nombre o IP del servidor (p.e. raspberrypi.local o 192.168.1.10)
- openssl genrsa -out server.key 2048 – Genera una RSA key privada para el servidor que será utilizada por el broker
- openssl req -new -out server.csr -key server.key – crear una solicitud de certificado .csr. Al rellenar el formulario, el nombre común (CN) es importante y suele ser el nombre de dominio del servidor, el resto se pueden dejar vacíos. Debe utilizar el mismo nombre cuando configure la conexión del cliente. Como somos la CA, no es necesario mandar la solicitud a la CA.
- openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360 – Utilizar la clave de la CA para verificar y firmar el certificado del servidor. Esto crea el archivo server.crt. Pide la contraseña usada para la ca.key
Con estos pasos hemos obtenido los siguientes ficheros:
- ca.crt – Certificado de la CA
- ca.key – Par de claves para la CA. Solo usar para crear un nuevo certificado
- server.crt – Certificado del servidor firmado por la CA
- server.csr – Solicitud de certificado. No es necesario.
- server.key – Par de claves del servidor
- ca.srl – Cada certificado emitido debe contener un número de serie único asignado por la CA. Debe ser único para cada certificado emitido por una determinada CA. OpenSSL guarda los números de serie utilizados en un archivo, por defecto tiene el mismo nombre que el archivo del certificado de la CA con la extensión sustituida por srl. Así que se crea un archivo llamado ca.srlc
NOTA: Tenga en cuenta que los certificados y las claves creadas pueden utilizarse en el broker/servidor de Mosquitto, y también en un servidor web, por lo que en el manual de Mosquitto se utiliza el término servidor y no broker.
Para ver el contenido de un certificado en texto, porque están codificados en base64, usar: openssl x509 -in server.crt -text -noout
Más información:
Configurar Mosquitto con MQTT sobre TLS
Para configurar el broker mosquitto MQTT para usar la seguridad TLS, seguir los pasos:
- Copiar los archivos server.crt y server.key en la carpeta /etc/mosquitto/certs. sudo cp server.crt server.key /etc/mosquitto/certs/
- Copiar el archivo ca.crt en la carpeta /etc/mosquitto/ca_certificates. sudo cp ca.crt /etc/mosquitto/ca_certificates/
Dar permiso a mosquitto para ver el fichero (clave privada) server.key: sudo chown mosquitto:mosquitto server.key (Esto es necesario a partir de la versión 2.0 de Mosquitto)
Configurar fichero configuración mosquitto con sudo nano /etc/mosquitto/mosquitto.conf añadiendo estas líneas en la zona de extra listeners (para mantener acceso simultáneo al puerto 1883 no cifrado y al puerto 8883 cifrado):
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
Reiniciar el servidor: sudo systemctl restart mosquitto
Por último probar la conexión mediante puerto seguro 8883 desde MQTT Explorer y Node-RED, deshabilitando la opción de verificar certificado.
El fichero final de configuración de mosquitto mosquitto.conf queda:
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /run/mosquitto/mosquitto.pid
listener 1883
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
log_timestamp true
include_dir /etc/mosquitto/conf.d
acl_file /etc/mosquitto/aclfile
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
Instalar Node-RED
La instalación recomendada para tener la última version de Node-RED en Raspberry Pi: https://nodered.org/docs/getting-started/raspberrypi
Ejecutar el script (le cuesta unos minutos ejecutarse por completo):
- bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
Iniciar el servicio de Node-RED con: sudo systemctl start nodered.service
Para ejecutar Node-RED como servicio y que se inicie en el boot de Raspberry PI ejecutar:
- sudo systemctl enable nodered.service
Para comprobar que funciona abrir un navegador y enterar en: http://{your_pi_ip-address}:1880
Configurar Node-RED
Para configurar Node-RED ver: https://nodered.org/docs/user-guide/runtime/configuration
El fichero de configuración se encuentra normalmente en $HOME/.node-red/settings.js
Vamos a dejar la configuración por defecto y no vamos cambiar nada, pero es posible añadir las mejoras:
- logging en un lugar externo fuera de la consola
- activar proyectos en Node-RED
- activar almacenamiento persistente de las variables de contexto
Autenticación y Autorización en Node-RED
Por defecto, el editor Node-RED no está protegido: cualquier persona que pueda acceder a su dirección IP puede acceder al editor e implementar cambios.
Para securizar Node-RED a nivel de atenticación y autorización seguir: https://nodered.org/docs/user-guide/runtime/securing-node-red para añadir usuario y password, así como otras configuraciones de seguridad
Instalar node-red-admin (Una herramienta de línea de comandos para administrar remotamente Node-RED):
sudo npm install -g --unsafe-perm node-red-admin
Para habilitar la autenticación basada en usuario y password, descomentar la propiedad adminAuth del fichero de configuración. Editar el fichero settings.js con nano /home/pi/.node-red/settings.js y descomentar estas líneas:
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "$2a$08$zZWtXTja0fB1pzD4OlKj7wCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
permissions: "*"
}]
},
Para calcular la contraseña se usa: node-red-admin hash-pw y una vez cifrada la contraseña pegar en password.
Reiniciar el servicio Node-RED: sudo systemctl restart nodered.service
Entrar en Node-RED de nuevo en http://{your_pi_ip-address}:1880 y comprobar que pide contraseña.
Si se quiere añadir un usuario de solo lectura configurar settings.js como:
adminAuth: {
type: "credentials",
users: [
{
username: "admin",
password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
permissions: "*"
},
{
username: "curso_iot",
password: "$2b$08$wuAqPiKJlVN27eF5qJp.YKo98uy6ZYONW7a/UWYxDTtwKFCdB8F19y",
permissions: "read"
}
]
}
Reiniciar el servicio Node-RED: sudo systemctl restart nodered.service
Comprobar que el usuario de solo lectura no puede hacer deploy.
Autenticación UI (Dashboard y Páginas Dinámicas)
Manual: https://nodered.org/docs/user-guide/runtime/securing-node-red#http-node-security
Para proteger las rutas HTTP expuestas por los nodos y el dashboard se puede usar una autenticación básica.
La propiedad httpNodeAuth en su archivo settings.js se puede usar para definir un nombre de usuario y contraseña únicos que podrán acceder a las rutas.
Editar el fichero settings.js con nano /home/pi/.node-red/settings.js y descomentar estas líneas y poner el usuario deseado:
- httpNodeAuth: {user:»usuario«,pass:»$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.»},
La propiedad pass, usa el mismo formato que adminAuth utilizando el algoritmo bcrypt y la contraseña se puede generar con el comando node-red-admin hash-pw. Para calcular la contraseña se usa: node-red-admin hash-pw y una vez cifrada la contraseña pegar en password.
Reiniciar el servicio Node-RED: sudo systemctl restart nodered.service
Entrar en Node-RED de nuevo en http://{your_pi_ip-address}:1880/ui y comprobar que pide contraseña.
Comunicaciones Cifradas TLS Node-RED
Node-RED proporciona soporte TLS para conexiones de red cifradas y autenticación.
No es necesario generar el certificado autofirmado del servidor, porque ya lo hemos hecho para mosquitto y se usa el mismo.
Editar el fichero settings.js con nano /home/pi/.node-red/settings.js y descomentar estas líneas y poner los datos de los certificados:
var fs=require("fs")
https: {
key: fs.readFileSync('/home/pi/certificados/server.key'),
cert: fs.readFileSync('/home/pi/certificados/server.crt')
},
requireHttps: true,
Reiniciar el servicio Node-RED: sudo systemctl restart nodered.service
Entrar en Node-RED de nuevo en https://{your_pi_ip-address}:1880 y comprobar que no funciona http://{your_pi_ip-address}:1880
La web aparecerá como no segura en el navegador, pero se puede añadir el fichero ca.crt como certificado raíz confiable en el ordenador y ya aparecerá como una web segura.