RPi-NodeRed
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)
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 :
On les relie entre eux:
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)
On obtiens la confirmation.
On sélectionne, a droite, la fenêtre debug.
Et on clique sur le carré bleu de l'élément "horodatage".
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:
On rentre Admin + mot de passe et on se retrouve connecté.
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 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 :