RPi-NodeRed

De knowledge
Aller à la navigation Aller à la recherche

NodeRed est un produit fabuleux. Installons le sur un Raspbery PI. Ici un Raspberry PI 4 de base (4Go)

Installation

On commence par un simple:

sudo apt update
sudo apt install nodejs

Tout se passe bien. Mais ensuite on installe le gestionnaire de packages npm. Ca semple une formalité mais....

sudo apt install npm

à chez moi pris une éternité et installé une centaine de dépendances. Mais ça a terminé et j'ai pu terminé par :

sudo npm install -g --unsafe-perm node-red
added 312 packages in 47s

63 packages are looking for funding
  run `npm fund` for details

Bon, il suffit alors de lancer nodered.

node-red
11 Feb 22:38:13 - [info]

Welcome to Node-RED
===================

11 Feb 22:38:13 - [info] Node-RED version: v4.0.8
11 Feb 22:38:13 - [info] Node.js  version: v18.19.0
11 Feb 22:38:13 - [info] Linux 6.6.51+rpt-rpi-v8 arm64 LE

On peut ouvrir avec un navigateur:

http://XX.YY.ZZ.TT:1880

Si l'adresse IP du serveur est XX.YY.ZZ.PP (1880 est le port par défaut de NodeRed)

Nodered.png

Bon il y a quelques "popups" de présentation. On peut les lires la première fois!

Premier test

On va créer un petit "Hello world" avec nodered!

On "drague & droppe" trois éléments :

Nodered-exemple-001.png

On les relie entre eux:

Nodered-exemple-002.png

On édite l'élément "function 1".

msg.payload+=" Hello World!"
return msg;

Et on clique sur "Déployer" (le bouton rouge en haut à droite)

Deploy-nodered.png

On obtiens la confirmation.

On sélectionne, a droite, la fenêtre debug.

Nodered-debug.png

Et on clique sur le carré bleu de l'élément "horodatage".

Nodereddebug.png

A chaque clic on a une ligne dans les logs de debug... On a vu que dans "function 1" on ajoute "Hello World" au "timestamp" .

Sécurisation

Ajout d'un contrôle d'accès

Il serait tout de même préférable d'ajouter un "login password" non?

Pour cela, on va tout d'abord encoder un mot de passe. Il y a pour cela une commande : node-red admin hash-pw

node-red admin hash-pw
Password: <ici on tape le mot de passe sans echo>
$2y$08$AK6/jMQoUMpbnSxS3TTv3eIxiQfILfTjulpMvYxzomFi.ZZaz1IFu

On arrète le serveur nodered (ctrl + C)

Et on édite le fichier : /home/admin/.node-red/settings.js si admin est l'utilisateur que fait tourner le serveur.

Dans la section "security" on décommente la partie

adminAuth: {
    type: "credentials",
    users: [{
       username: "admin",
       password: "$2y$08$AK6/jMQoUMpbnSxS3TTv3eIxiQfILfTjulpMvYxzomFi.ZZaz1IFu",
       permissions: "*"
    }]
},

On crée un utilisateur nommé "admin" et dont le mot de passe est celui donné à node-red admin hash-pw. Et on relance le serveur (cette fois ci en "détaché")

nohup node-red &

Et on relance la connexion avec le navigateur:

Nodered-login.png

On rentre Admin + mot de passe et on se retrouve connecté.

Remarque
Attention.png Il y a quelque chose à préciser sur le ficheirsettings.js deNode-red.

La première fois que l'on lance node-red en tant qu'utilisateur il vérifie si une version de settings.jsexiste dans le répertoire:/home/$USER/.node-red/settings.jsSi c'est le ca il l'utilise.

SI ce n'est pas le cas il va le créer en utilisant la "matrice" sur: /usr/local/lib/node_modules/node-red/settings.jsDonc, pour une modification qui sera propagée chez tous les utilisateurs il faut modifier le fichier "matrice" sinon un simple vi de celui dans le répertoire privé de l'utilisateur sera suffisant.

Sécuriser en https

Il y a des méthodes pour implémenter https directement dans node-red mais je préfère confier cette tâche à un "reverse proxy" placé entre internet et l'application.

On va donc utiliser un serveur apache pour assurer le rôle de gestion des certificats et du déchiffrage/enchiffrage https tout en renvoyant le trafic vers node-red.

La méthode classique, pour utiliser Apache en reverse proxy (RP) est d'en installer les modules :

sudo a2enmod proxy
sudo a2enmod proxy_http
systemctl restart apache2

Puis de configurer un "virtual-host" afin de le rediriger vers notre instance node-red. Le virtual host https doit ressembler à celà:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        ServerName secure.modomaine.com
        ServerAlias www.secure.mondomaine.com

        ServerAdmin webmaster@mondomaine.com
        DocumentRoot /var/www/html/secured

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error-secure.log
        CustomLog ${APACHE_LOG_DIR}/access-secure.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/secure.pinon-hebert.fr/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/secure.pinon-hebert.fr/privkey.pem
</VirtualHost>
</IfModule>

On ajoute les lignes :

        ProxyPass "/nodered"  "http://XX.YY.ZZ.TT:1880/"
        ProxyPassReverse "/nodered"  "http://XX.YY.ZZ.TT:1880/"

avant le dernier "Include" et, normalement, ça devrait marcher si on entre l'URL https://secure.modomaine.com/node

Et bien on a bien l'impression que ça marche mais.. non on a un e page blanche!

SI on regarde le détail des requêtes on a bien un GET sur /node qui renvoie un 200 OK mais apres, tout ce qui est référencé dans cette page nous "claque en 404".

Par exemple:

equest URL: https://secure.mondomaine.com/vendor/jquery/css/base/jquery-ui.min.css?v=38425ccf4997
Request Method: GET
Status Code: 404 Not Found
Remote Address: XX.YY.ZZ.TT:443
Referrer Policy: strict-origin-when-cross-origin

Le reverse proxy à loupé une réécriture! il manque un /nodered/ entre le domaine et /vendor/...

Comment corriger cela?

Il faut "aider" le RP et réécrire certaines URL (les web sockets si j'ai tout bien compris)!

Le fichier de conf du localhost sera alors:

<IfModule>
<VirtualHost>

.........................


        Define NodeRedURL "/nodered/"

        <Location ${NodeRedURL}>
                RewriteEngine on
                RewriteCond %{HTTP:Upgrade} ^WebSocket$ [NC]
                RewriteCond %{HTTP:Connection} Upgrade$ [NC]
                RewriteRule .*/(.*) "ws://localhost:1880/$1" [P,L]

                ProxyPreserveHost On
                ProxyPass http://localhost:1880/
                ProxyPassReverse http://localhost:1880/
        </Location>
</VirtualHost>
</IfModule>

On relance le serveur apache et on teste

sudo systemctl reload apache2.service

Avec un navigateur on utilise l'URL https://secure.mondomaine.com/nodered/

et tout marche très bien!

Attention.pngAttention cependant à le pas oublier le "/" terminal. https://secure.mondomaine.com/nodered (sans le / à la fin) nous amènera irrémédiablement à un 404.

Ajouter un module

Sur raspberry pi il existe un module qui permet d'utiliser le GPIO (principalement) et accessoirement le clavier et la souris branché sur ses ports USB.

On se déplace dans le repertoire node-red de l'utilisateur qui lance nodered et on installe le module

/home/nodered/.node-red
npm i node-red-node-pi-gpio

SI on relance nodered et qu'on se connecte on voit apparaitre :

Nodered-gpio.png