Node-Red Con Certificado SSL Firmado por LetsEncrypt

Esta vez vamos a crear un certificado SSL/TSL Firmado y certificado.
Para nuestro servidor node-red.
Asi podremos ver nuestro servidor con el Candadito Verde y sin tener que aceptar el mensaje de pagina no segura.

En una imagen. Esto es lo que queremos.
node-red con certificado ssl




Indice:

1) Requisitos
2) Comprobaciones
3) Instalar certbot
4) Obtener Certificado SSL para nuestro dominio
5) Configurar node-red para funcionar con certificados ssl
6) Comprobacion
7) Redirigir el puerto https(443) al puerto de node red(1880)
8) Hacer la configuracion permanente
9) Asegurando-node-red
- 9.1) Generar un password)
- 9.2) Configurar usuario y passord en settings.js)
- 9.3) Cambiar la url de administracion
Notas
Referencias




1) Requisitos.

Supongo que ya tienes un servidor configurado con node-red. Y quieres asegurarlo con un certificado firmado. (para que no salga el aviso de pagina insegura en los navegadores).
Si no puedes ver instalar node-red en vps debian8

Nota1: no todos los Nat Vps soportan la redireccion dle puerto 443 (https).
Si es el caso tendras que usar otro puerto.

Nota2: Si tienes node-red detras de un proxy inverso estilo nginx.
Los certificados se los deberias añadir al proxy y no a node-red

Nota3: He supuesto un servidor minimalista. Con los recursos muy limitados.
Para este articulo he usado un Mini-Vps con tan solo 128Mb de RAM.




2) Comprobaciones.

Suponemos que tenemos node-red arrancado y funcionando.
Luego la URL http://localhost:1880 deberia funcionar en el navegador.




3) Instalar certbot.

Mas Info aqui: Instalacion y Puesta a punto de un Servidor Debian8 7.1 Instalar CertBot

(Para debian 8 copiar y pegar codigo)

echo 'deb http://archive.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/backports.list

apt-get -o Acquire::Check-Valid-Until=false update
apt-get install python-certbot -t jessie-backports -y



4) Obtener Certificado ssl para nuestro dominio.

Si no estas seguro puedes lanzar una prueba. (no intrusiva)
con certbot -v certonly --standalone --dry-run

Lanzar el asistente certbot en modo automatico con el siguiente comando.

certbot certonly --standalone 

Asi seria la Salida del comando. (en rojo lo rellenado por nosotros.)

root@ne:~# certbot certonly --standalone 
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):Pon_Tu_Correo_aqui@jejo.es
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):tu_dominio_aqui.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for tu_dominio_aqui.com
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/tu_dominio_aqui.com/fullchain.pem. Your cert will
   expire on 2019-12-27. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to tu_correo@jejo.es.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Los certificados se quedan en: /etc/letsencrypt/live/tu_dominio.com

Copio los certificados a la carpeta del usuario en el que corre node-red.
(modifica texto en rojo por tu dominio y tu usuario.)

cp /etc/letsencrypt/live/tu_dominio.com/cert.pem /home/node/cert.pem
cp /etc/letsencrypt/live/tu_dominio.com/privkey.pem /home/node/priv.pem



5) Configurar node-red para funcionar con certificados ssl

Dos formas:

1) Desde el usuario que corre node red edito el archivo de configuracion de node-red.

nano .node-red/settings.js 

2) Puedes poner la ruta completa al archivo de configuracion. (modifica texto en rojo (node) por tu usuario.)

nano /home/node/.node-red/settings.js 

Haz Los siguientes Cambios:

1) Descomenta //var fs = require("fs"); ( linea 14 aproximadamente )

Deberia quedar asi:

// The `https` setting requires the `fs` module. Uncomment the following
// to make it available:
var fs = require("fs");

2) Descomenta y configura las variables con la ruta a los certificados. ( linea 150 aproximadamente )
(modifica texto en rojo (node) por tu usuario.)

    // The following property can be used to enable HTTPS
    // See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
    //
    //https: {
    //    key: fs.readFileSync('privatekey.pem'),
    //    cert: fs.readFileSync('certificate.pem')
    //},
    
    https: {
        key: fs.readFileSync('/home/node/priv.pem'),
        cert: fs.readFileSync('/home/node/cert.pem')
    },

6) Comprobacion

Si paro y arranco node-red. (copiar y pegar codigo)

killall node-red
(node-red --max-old-space-size=96 &)&

Asi seria la Salida del comando. (en rojo lo rellenado por nosotros.)

node@jejo.es:~$ killall node-red
node@jejo.es:~$ (node-red --max-old-space-size=96 &)&

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

29 Sep 14:25:21 - [info] Node-RED version: v0.20.8
29 Sep 14:25:21 - [info] Node.js  version: v11.10.1
29 Sep 14:25:21 - [info] Linux 3.10.0-957.12.2.vz7.86.2 x64 LE
29 Sep 14:25:22 - [info] Loading palette nodes
29 Sep 14:25:22 - [info] Settings file  : /home/jejo/.node-red/settings.js
29 Sep 14:25:22 - [info] Context store  : 'default' [module=memory]
29 Sep 14:25:22 - [info] User directory : /home/node/.node-red
29 Sep 14:25:22 - [warn] Projects disabled : editorTheme.projects.enabled=false
29 Sep 14:25:22 - [info] Flows file     : /home/node/.node-red/flows_sg.jejo.es.json
29 Sep 14:25:22 - [info] Server now running at https://127.0.0.1:1880/nodeadmin/
29 Sep 14:25:22 - [warn] 

Como se puede ver ya tengo https

Tambien lo podriamos probar el certificado ssl con el siguiente comando.
curl -ksv https://127.0.0.1:1880/ |head -1




7) Redirigir el puerto https(443) al puerto de node-red(1880).

Ya que tenemos node-red con un certificado https firmado y validado.
Lo ideal seria que pudiramos acceder con una url tipo: https://tu_dominio.com
Para esto solo tenemos que hacer que node sea accesible desde el puerto 443.
Podriamos ejecutar node-red como administrador y configurarlo para que escuche en el puerto 443.
Pero eso seria bastante inseguro y un verdadero peligro para nuestro servidor.

En su lugar prefiero redirigir el puerto 443 al puerto 1880.

Para ello tenemos varias opciones:

  • Ejecutar socat desde administrador y dejar el puerto redirigido:
    (socat TCP-LISTEN:443,fork,reuseaddr TCP:127.0.0.1:1880 &)&
  • Usar una regla iptables:
    iptables -t nat -A PREROUTING -i venet0 -p tcp --dport 443 -j REDIRECT --to-port 1880 -m comment --comment 'node-red'

Nota Si quieres que node red funcione como http y como https. tambien tendras que añadir este comando.
(socat TCP-LISTEN:80,fork,reuseaddr ssl:127.0.0.1:1880,verify=0 &)&




8) Hacer la configuracion permanente.

Se podria configurar todo como servicio.
Aunque en mi caso he preferido añadir las siguientes lineas a /etc/rc.local
Asi se cargara todo en cada reinicio.

# Configuracion permanente Node-red
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 1880 -m comment --comment 'node-red'
(socat TCP-LISTEN:80,fork,reuseaddr ssl:127.0.0.1:1880,verify=0 &)&
su node -c "cd /home/node ; (node-red  --max-old-space-size=96 &)&"

Explicacion: - Iptables redirige el puerto https(443) al puerto de node-red (1880).
- socat (opcional) es para que node-red se pueda seguir viendo por http
- su node -c Lanza node-red desde el usuario node




Despues de arrancar mi maquina queda asi de sencilla:

em50l@node:~$ pstree -Ua 
systemd -z 
  ├─node-red 
  ├─rsyslogd -n
  ├─socat TCP-LISTEN:80,fork,reuseaddr ssl:127.0.0.1:1880,verify=0
  ├─sshd -D
  ├─systemd-journal
  ├─systemd-network
  ├─systemd-resolve
  └─systemd-udevd



9) Asegurando node-red

La interfaz de administracion de Node-red viene sin usuario y contraseña.
Antes de exponerlo a internet es necesario asegurar la interfaz de administracion
Mas info aqui: https://nodered.org/docs/user-guide/runtime/securing-node-red

Como minimo Vamos a crear un password para la interfaz de administracion.
y vamos a cambiar la url de acceso a la misma.




9.1) Generar un password.

1) Con una Herramienta online https://www.bcryptgenerator.com/

2) Desde Linea de comandos

Instalamos la libreria bcryptjs npm i bcryptjs
Generamos una contraseña con el siguiente comando.
node -e "console.log(require('bcryptjs').hashSync(process.argv[1],8))" tu-contrasenya

Asi seria la Salida del comando. (en rojo lo rellenado por nosotros.)

node@jejo.es:~$ killall node-red
node@jejo.es:~$ (node-red --max-old-space-size=96 &)&

node@jejo.es:~$ npm i bcryptjs
+ bcryptjs@2.4.3
added 1 package from 6 contributors and audited 1 package in 1.325s

jejo@ne:~$ node -e "console.log(require('bcryptjs').hashSync(process.argv[1],8))" tu-contrasenya
$2a$08$VkweDSnRzNootBL4sKAXp.v6hr87eMX2NcvmyDqhL37DD1OI4ATRi
jejo@ne:~$ node -e "console.log(require('bcryptjs').hashSync(process.argv[1],8))" tu-contrasenya
$2a$08$B3wSA/TpJpRZBVGGQMHVK.63EJK5jxhZcrhTaKEV73FhQwOslaV66
jejo@ne:~$ node -e "console.log(require('bcryptjs').hashSync(process.argv[1],8))" tu-contrasenya
$2a$08$GwF.KXzOEVjGaiXtd62OsuaZrvpW1XpAGNFGxnFJDHFT19WaUDdMu

Observa que la misma contraseña nunca se cifra de la misma forma.




9.2) Configurar usuario y passord en settings.js

Edita nano .node-red/settings.js y sobre la linea 120 cambia las lineas comentadas por las siguientes. (en rojo lo rellenado por nosotros.)
username: el usuario que quieras.
password: el password generado en el punto anterior.

    // To password protect the Node-RED editor and admin API, the following
    // property can be used. See http://nodered.org/docs/security.html for details.
    adminAuth: {
        type: "credentials",
        users: [{
            username: "tu_usuario_admin",
            password: "$2a$08$GwF.KXzOEVjGaiXtd62OsuaZrvpW1XpAGNFGxnFJDHFT19WaUDdMu",
            permissions: "*"
        }]
    },



9.3) cambiar la url de administracion.

Edita nano .node-red/settings.js y sobre la linea 90 cambia las lineas comentadas por las siguientes.

httpAdminRoot: '/kadmin',

Asi la url de administracion sera:
https://localhost:1880/kadmin/ desde tu maquina.
o
https://tu_dominio.com/kadmin/ desde el exterior.

node-red-admin

Notas

Referencias

https://letsencrypt.org/es/ https://itnext.io/node-express-letsencrypt-generate-a-free-ssl-certificate-and-run-an-https-server-in-5-minutes-a730fbe528ca?gi=e6bb40bf899a https://github.com/node-red/cookbook.nodered.org/wiki/How-to-safely-expose-Node-RED-to-the-Internet https://www.todotech20.com/como-usar-nginx-como-un-proxy-inverso/

A estudiar.
https://diyfuturism.com/index.php/2018/01/31/setting-up-lets-encrypt-with-node-red-home-assistant/ https://www.busindre.com/comandos_openssl_utiles_para_certificados http://www.dest-unreach.org/socat/doc/socat-openssl.txt http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html