Archivo de la etiqueta: Seguridad Node-RED

Práctica 4: Instalar, Configurar y Securizar Mosquitto y Node-RED en Raspberry Pi

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): 

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.

Configurar y Securizar Node-RED

Configurar Node-RED

Para configurar Node-RED seguir: https://nodered.org/docs/user-guide/runtime/configuration

El fichero de configuración se encuentra normalmente en $HOME/.node-red/settings.js

El fichero de configuración por defecto es settings.js y está situado en /usr/lib/node-modules/node-red/ y puede encontrarse en https://github.com/node-red/node-red/blob/master/packages/node_modules/node-red/settings.js

Settings file: https://nodered.org/docs/user-guide/runtime/settings-file

Si no está seguro de qué archivo de configuración está usando Node-RED, debe verificar la salida del registro cuando se inicie Node-RED. Registrará la ruta completa al archivo:

  • 22 Jun 12:34:56 – [info] Settings file  : /Users/nol/.node-red/settings.js

El fichero por defecto viene con muchas opciones comentadas, para habilitarla, simplemente quitar el comentario “//”.

Al añadir una nueva opción asegurarse de añadir una coma al principio y final para separar del resto de opciones.

El fichero de flujos se encuentra por defecto en $HOME/.node-red/flows_<hostname>.json

Por defecto el directorio donde se guardan los nodos es $HOME/.node-red/nodes_modules

Existe una API de Node-RED que permite administrar remotamente en runtime: https://nodered.org/docs/api/admin/

Logging Node-RED

Ver https://nodered.org/docs/user-guide/runtime/logging

Node-RED utiliza un logger que escribe su salida en la consola. También admite el uso de módulos de logging personalizados para permitir que la salida se envíe a otra parte.

Esto se puede configurar mediante el fichero de configuración: https://nodered.org/docs/user-guide/runtime/settings-file

Securizar Node-RED (Autorización y Autenticación)

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

El editor y la API de administración admiten dos tipos de autenticación:

  • autenticación basada en credenciales de nombre de usuario / contraseña
  • autenticación contra cualquier proveedor de OAuth / OpenID como Twitter o GitHub

Para habilitar la autenticación basada en usuario y password, descomentar la propiedad adminAuth del fichero de configuración:

adminAuth: {
    type: "credentials",
    users: [
        {
            username: "admin",
            password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
            permissions: "*"
        },
        {
            username: "george",
            password: "$2b$08$wuAqPiKJlVN27eF5qJp.RuQYuy6ZYONW7a/UWYxDTtwKFCdB8F19y",
            permissions: "read"
        }
    ]
}

La propiedad de los usuarios es una matriz de objetos de usuario. Esto le permite definir múltiples usuarios, cada uno de los cuales puede tener diferentes permisos.

El nivel de permisos se puede configurar a nivel de los métodos de la API de administración: https://nodered.org/docs/api/admin/methods/

Las contraseñas se codifican de forma segura utilizando el algoritmo bcrypt

Para calcular la contraseña se usa: node-red-admin hash-pw

La herramienta le pedirá la contraseña que desea usar y luego imprimirá el hash que se puede copiar en el archivo de configuración.

Hay servicios web que permiten calcular el hash: https://passwordhashing.com/BCrypt

Command line administration: https://nodered.org/docs/node-red-admin 

Más información:

Autenticación HTTP Node-Red

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.

  • httpNodeAuth: {user:”user”,pass:”$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.”},

La propiedad pass, usa el mismo formato que adminAuth utilizando el algoritmo bcrypt

Manual: https://nodered.org/docs/user-guide/runtime/securing-node-red#http-node-security

Securizar node red dashboard: https://github.com/node-red/node-red-dashboard/blob/master/README.md#securing-the-dashboard

Más información:

SSL en Node-Red

Para usar https con Node-RED seguir estos tutoriales:

Lo configuro el https en  $HOME/.node-red/settings.js

Líneas a descomentar/configurar:

var fs=require("fs")

https: {

key: fs.readFileSync('/user/myuser/privatekey.pem'),

cert: fs.readFileSync('/user/myuser/certificate.pem')

},

requireHttps: true,

Aplicar cambios de la nueva configuración con: node-red -s settings.js

Y restart node:

  • node-red-stop
  • node-red-start

Pero si tienes systemctl: systemctl start nodered.service

Como exponer un Node-Red de forma segura en Internet: https://github.com/node-red/cookbook.nodered.org/wiki/How-to-safely-expose-Node-RED-to-the-Internet

Certificados Autofirmados

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 servidor y el cliente 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 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

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:

Información completa en: https://aprendiendoarduino.wordpress.com/2021/02/28/practica-4-instalar-configurar-y-securizar-mosquitto-y-node-red-en-raspberry-pi/