Can't enable https

Hi, all. I'm using Node-Red (v2.2.2npm) in a Docker Container on a Synology NAS and it's set up for the purpose of automations with Home Assistant. I'm trying to enable https and can't get it working; was hoping this was the right place to get some help.

  • I have found the proper settings.js file and I understand how to edit it (I successfully enabled the password protection).
  • I am not clear, however, how to point the settings at the proper certificates.
  • I attempted to follow the guide here: Securing Node-Red with SSL and Username Authentication and it seems to work in that the files get created (node-cert.pem, node-csr.pem, and node-key.pem)
  • I then edited the settings.js to uncomment the required lines (I tried both options 1 and 2 on separate attempts... did not ever uncomment both 1 and 2 simultaneously)

However, when I restart the container, it crashes and restarts in a loop. If I re-comment the lines, it all works fine on http. I'm guessing I'm doing something wrong with the certs, either putting them in the wrong place or missing a step or something, but I can't figure it out. Anyone able to point me in the right direction?

As a new user, I can't upload the log files, but here's a paste of what I think might include the relevant crashes:

nodered-node-red
date,stream,content


2022-04-24 13:47:59,stdout,e[0m

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m     /data/.npm/_logs/2022-04-24T13_47_59_683Z-debug.log

2022-04-24 13:47:59,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m A complete log of this run can be found in:

2022-04-24 13:47:59,stdout,e[0m

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m This is probably not a problem with npm. There is likely additional logging output above.

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Failed at the node-red-docker@2.2.2 start script.

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m 

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Exit status 1

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m node-red-docker@2.2.2 start: `node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"`

2022-04-24 13:47:59,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35merrnoe[0m 1

2022-04-24 13:47:59,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35mcodee[0m ELIFECYCLE

2022-04-24 13:47:59,stdout,}

2022-04-24 13:47:59,stdout,  path: e[32m'privkey.pem'e[39m

2022-04-24 13:47:59,stdout,"  code: e[32m'ENOENT'e[39m,
"
2022-04-24 13:47:59,stdout,"  syscall: e[32m'open'e[39m,
"
2022-04-24 13:47:59,stdout,"  errno: e[33m-2e[39m,
"
2022-04-24 13:47:59,stdout,e[90m    at internal/main/run_main_module.js:17:47e[39m {

2022-04-24 13:47:59,stdout,e[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)e[39m

2022-04-24 13:47:59,stdout,e[90m    at Function.Module._load (internal/modules/cjs/loader.js:790:12)e[39m

2022-04-24 13:47:59,stdout,e[90m    at Module.load (internal/modules/cjs/loader.js:950:32)e[39m

2022-04-24 13:47:59,stdout,e[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)e[39m

2022-04-24 13:47:59,stdout,e[90m    at Module._compile (internal/modules/cjs/loader.js:1085:14)e[39m

2022-04-24 13:47:59,stdout,    at Object.<anonymous> (/usr/src/node-red/node_modules/e[4mnode-rede[24m/red.js:218:20)

2022-04-24 13:47:59,stdout,    at https (/data/settings.js:103:33)

2022-04-24 13:47:59,stdout,e[90m    at Object.readFileSync (fs.js:393:35)e[39m

2022-04-24 13:47:59,stdout,e[90m    at Object.openSync (fs.js:497:3)e[39m

2022-04-24 13:47:59,stdout,"Error: ENOENT: no such file or directory, open 'privkey.pem'
"
2022-04-24 13:47:59,stdout,

2022-04-24 13:47:59,stdout,    ^

2022-04-24 13:47:59,stdout,    throw err;

2022-04-24 13:47:59,stdout,internal/fs/utils.js:332

2022-04-24 13:47:58,stdout,

2022-04-24 13:47:58,stdout,> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"

2022-04-24 13:47:58,stdout,> node-red-docker@2.2.2 start /usr/src/node-red

2022-04-24 13:47:58,stdout,

2022-04-24 13:47:53,stdout,e[0m

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m     /data/.npm/_logs/2022-04-24T13_47_53_684Z-debug.log

2022-04-24 13:47:53,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m A complete log of this run can be found in:

2022-04-24 13:47:53,stdout,e[0m

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m This is probably not a problem with npm. There is likely additional logging output above.

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Failed at the node-red-docker@2.2.2 start script.

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m 

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Exit status 1

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m node-red-docker@2.2.2 start: `node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"`

2022-04-24 13:47:53,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35merrnoe[0m 1

2022-04-24 13:47:53,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35mcodee[0m ELIFECYCLE

2022-04-24 13:47:53,stdout,}

2022-04-24 13:47:53,stdout,  path: e[32m'privkey.pem'e[39m

2022-04-24 13:47:53,stdout,"  code: e[32m'ENOENT'e[39m,
"
2022-04-24 13:47:53,stdout,"  syscall: e[32m'open'e[39m,
"
2022-04-24 13:47:53,stdout,"  errno: e[33m-2e[39m,
"
2022-04-24 13:47:53,stdout,e[90m    at internal/main/run_main_module.js:17:47e[39m {

2022-04-24 13:47:53,stdout,e[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)e[39m

2022-04-24 13:47:53,stdout,e[90m    at Function.Module._load (internal/modules/cjs/loader.js:790:12)e[39m

2022-04-24 13:47:53,stdout,e[90m    at Module.load (internal/modules/cjs/loader.js:950:32)e[39m

2022-04-24 13:47:53,stdout,e[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)e[39m

2022-04-24 13:47:53,stdout,e[90m    at Module._compile (internal/modules/cjs/loader.js:1085:14)e[39m

2022-04-24 13:47:53,stdout,    at Object.<anonymous> (/usr/src/node-red/node_modules/e[4mnode-rede[24m/red.js:218:20)

2022-04-24 13:47:53,stdout,    at https (/data/settings.js:103:33)

2022-04-24 13:47:53,stdout,e[90m    at Object.readFileSync (fs.js:393:35)e[39m

2022-04-24 13:47:53,stdout,e[90m    at Object.openSync (fs.js:497:3)e[39m

2022-04-24 13:47:53,stdout,"Error: ENOENT: no such file or directory, open 'privkey.pem'
"
2022-04-24 13:47:53,stdout,

2022-04-24 13:47:53,stdout,    ^

2022-04-24 13:47:53,stdout,    throw err;

2022-04-24 13:47:53,stdout,internal/fs/utils.js:332

2022-04-24 13:47:52,stdout,

2022-04-24 13:47:52,stdout,> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"

2022-04-24 13:47:52,stdout,> node-red-docker@2.2.2 start /usr/src/node-red

2022-04-24 13:47:52,stdout,

2022-04-24 13:47:48,stdout,e[0m

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m     /data/.npm/_logs/2022-04-24T13_47_48_016Z-debug.log

2022-04-24 13:47:48,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m A complete log of this run can be found in:

2022-04-24 13:47:48,stdout,e[0m

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m This is probably not a problem with npm. There is likely additional logging output above.

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Failed at the node-red-docker@2.2.2 start script.

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m 

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Exit status 1

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m node-red-docker@2.2.2 start: `node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"`

2022-04-24 13:47:48,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35merrnoe[0m 1

2022-04-24 13:47:48,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35mcodee[0m ELIFECYCLE

2022-04-24 13:47:48,stdout,}

2022-04-24 13:47:48,stdout,  path: e[32m'privkey.pem'e[39m

2022-04-24 13:47:48,stdout,"  code: e[32m'ENOENT'e[39m,
"
2022-04-24 13:47:48,stdout,"  syscall: e[32m'open'e[39m,
"
2022-04-24 13:47:48,stdout,"  errno: e[33m-2e[39m,
"
2022-04-24 13:47:48,stdout,e[90m    at internal/main/run_main_module.js:17:47e[39m {

2022-04-24 13:47:48,stdout,e[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)e[39m

2022-04-24 13:47:48,stdout,e[90m    at Function.Module._load (internal/modules/cjs/loader.js:790:12)e[39m

2022-04-24 13:47:48,stdout,e[90m    at Module.load (internal/modules/cjs/loader.js:950:32)e[39m

2022-04-24 13:47:48,stdout,e[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)e[39m

2022-04-24 13:47:48,stdout,e[90m    at Module._compile (internal/modules/cjs/loader.js:1085:14)e[39m

2022-04-24 13:47:48,stdout,    at Object.<anonymous> (/usr/src/node-red/node_modules/e[4mnode-rede[24m/red.js:218:20)

2022-04-24 13:47:48,stdout,    at https (/data/settings.js:103:33)

2022-04-24 13:47:48,stdout,e[90m    at Object.readFileSync (fs.js:393:35)e[39m

2022-04-24 13:47:48,stdout,e[90m    at Object.openSync (fs.js:497:3)e[39m

2022-04-24 13:47:48,stdout,"Error: ENOENT: no such file or directory, open 'privkey.pem'
"
2022-04-24 13:47:48,stdout,

2022-04-24 13:47:48,stdout,    ^

2022-04-24 13:47:48,stdout,    throw err;

2022-04-24 13:47:47,stdout,internal/fs/utils.js:332

2022-04-24 13:47:47,stdout,

2022-04-24 13:47:47,stdout,> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"

2022-04-24 13:47:47,stdout,> node-red-docker@2.2.2 start /usr/src/node-red

2022-04-24 13:47:47,stdout,

2022-04-24 13:47:41,stdout,e[0m

2022-04-24 13:47:41,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m     /data/.npm/_logs/2022-04-24T13_47_40_974Z-debug.log

2022-04-24 13:47:41,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m A complete log of this run can be found in:

2022-04-24 13:47:41,stdout,e[0m

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m This is probably not a problem with npm. There is likely additional logging output above.

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Failed at the node-red-docker@2.2.2 start script.

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m 

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m Exit status 1

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0me[35me[0m node-red-docker@2.2.2 start: `node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"`

2022-04-24 13:47:40,stdout,e[0me[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35merrnoe[0m 1

2022-04-24 13:47:40,stdout,e[37;40mnpme[0m e[0me[31;40mERR!e[0m e[0me[35mcodee[0m ELIFECYCLE

2022-04-24 13:47:40,stdout,}

2022-04-24 13:47:40,stdout,  path: e[32m'privkey.pem'e[39m

2022-04-24 13:47:40,stdout,"  code: e[32m'ENOENT'e[39m,
"
2022-04-24 13:47:40,stdout,"  syscall: e[32m'open'e[39m,
"
2022-04-24 13:47:40,stdout,"  errno: e[33m-2e[39m,
"
2022-04-24 13:47:40,stdout,e[90m    at internal/main/run_main_module.js:17:47e[39m {

2022-04-24 13:47:40,stdout,e[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)e[39m

2022-04-24 13:47:40,stdout,e[90m    at Function.Module._load (internal/modules/cjs/loader.js:790:12)e[39m

2022-04-24 13:47:40,stdout,e[90m    at Module.load (internal/modules/cjs/loader.js:950:32)e[39m

2022-04-24 13:47:40,stdout,e[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)e[39m

2022-04-24 13:47:40,stdout,e[90m    at Module._compile (internal/modules/cjs/loader.js:1085:14)e[39m

2022-04-24 13:47:40,stdout,    at Object.<anonymous> (/usr/src/node-red/node_modules/e[4mnode-rede[24m/red.js:218:20)

2022-04-24 13:47:40,stdout,    at https (/data/settings.js:103:33)

2022-04-24 13:47:40,stdout,e[90m    at Object.readFileSync (fs.js:393:35)e[39m

2022-04-24 13:47:40,stdout,e[90m    at Object.openSync (fs.js:497:3)e[39m

2022-04-24 13:47:40,stdout,"Error: ENOENT: no such file or directory, open 'privkey.pem'
"
2022-04-24 13:47:40,stdout,

2022-04-24 13:47:40,stdout,    ^

2022-04-24 13:47:40,stdout,    throw err;

2022-04-24 13:47:40,stdout,internal/fs/utils.js:332

2022-04-24 13:47:39,stdout,

2022-04-24 13:47:39,stdout,> node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"

2022-04-24 13:47:39,stdout,> node-red-docker@2.2.2 start /usr/src/node-red

2022-04-24 13:47:39,stdout,

2022-04-24 13:47:34,stdout,24 Apr 09:47:34 - [info] Stopped flows

2022-04-24 13:47:34,stdout,24 Apr 09:47:34 - [info] [server:Home Assistant] Closing connection to http://192.168.1.211:8123

2022-04-24 13:47:34,stdout,24 Apr 09:47:34 - [info] Stopping flows

Hi. When posting code and logs, please use the </> option in the editor as it makes things a lot easier to read.

The log is telling you that it can't find your files. The most likely reason is that your Docker container can't reach them. Please read up on Docker so that you know how to give access to an appropriate place.

Explain

  • Where you put the generated files (key/cert) on the NAS
  • How you mounted them into the container
  • Exactly what you put in the settings.js file

Thank you. I'm in the _data folder on the Nas, which is where the settings.js file sits. All 3 generated files are in that same directory.

I don't know if I mounted the files to the container or not... I am trying to read about it, but kind of lost on where to even begin... I assumed that since this folder contains the settings.js that it was already visible to the container/etc.

In the settings.js file itself, I uncommented the https function lines and the require https line and that's all... I didn't type/paste any new code nor change any file names or anything.

IIRC Paths to key/cert should be fully qualified so change them to be /data/privkey.pem

That would make a lot of sense... I renamed:

  • node-cert.pem to cert.pem
    and
  • node-key.pem to privkey.pem

But I'm still having the same issue. I tried a few iterations of referencing the files by name and renaming... none of it worked. I think the files in _data may not be the same as /data... I will continue to look into it, but if you have any other ideas or resources I can check, that would be great. Thanks!

Try accessing the Docker command line and doing a few ls commands to see if you can find the correct path.

It really helps a lot if you actually post the verbatim command you use to launch your container, a verbatim pwd & ls of the directory where "everything resides".

Not sure I follow... I have located the proper settings.js file. I know it's the right one because when I edited to enable password protection, it worked. I also know where the certs are located because I created them in the same folder as that operative settings.js file.

@tve I don't use a command to launch the container. For NodeRed, I just open the Docker GUI on the Synology, go to registry and pull the latest when there's a new one. Then it shows up as an Image, and I can double-click to install it. I have home-assistant and zwave-js launched from cli in ssh terminal, but I haven't figured out how to do so for nodered. I also would like to migrate it all to docker compose, but haven't been able to figure out how to do that yet either.

Show us exactly what you have put in the settings.js file

Ok. Per above, I've tried a few variations, but this is the one I thought would work the closest:

    /** The following property can be used to enable HTTPS
     * This property can be either an object, containing both a (private) key
     * and a (public) certificate, or a function that returns such an object.
     * See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
     * for details of its contents.
     */

    /** Option 1: static object */
    https: {
      key: require("fs").readFileSync('node-key.pem'),
      cert: require("fs").readFileSync('node-cert.pem')
    },

    /** Option 2: function that returns the HTTP configuration object */
    //https: function() {
         // This function should return the options object, or a Promise
         // that resolves to the options object
    //     return {
    //         key: require("fs").readFileSync('privkey.pem'),
    //         cert: require("fs").readFileSync('cert.pem')
    //     }
    // },

    /** If the `https` setting is a function, the following setting can be used
     * to set how often, in hours, the function will be called. That can be used
     * to refresh any certificates.
     */
    httpsRefreshInterval : 12,

    /** The following property can be used to cause insecure HTTP connections to
     * be redirected to HTTPS.
     */
    requireHttps: true,

But you are still not using fully qualified paths for the file names as I asked earlier. It should be:

    https: {
      key: require("fs").readFileSync('/data/node-key.pem'),
      cert: require("fs").readFileSync('/data/node-cert.pem')
    },

Ah. Yes. I tried that also... Is /data/ correct or should it be /_data/ given the name of the actual folder? I'll try it again either way....

Node-RED runs in the container and the path in the container is /data. The path outside the container is irrelevant, that's the point of containers...

@tve, makes sense and appreciate the explanation. Unfortunately, it didn't work. I changed those lines to /data/node-key.pem and /data/node-cert.pem and I'm still getting the crash loops.
I re-commented the " httpsRefreshInterval : 12," line since I wasn't using option 2, but that didn't help either.

2 other thoughts:

  1. should I rename the certs to privkey.pem and cert.pem instead of changing the references to the filenames that already exist?

  2. I had seen somewhere that a line needs to be uncommented setting an "fs" variable. I don't see that line, and I think it's from an earlier version as the lines we're discussing here seem to declare and point at the same time, but am I missing something else that needs to be uncommented?

I think you should start by trying to serve up some small text file over HTTP using the "static file server" option in the settings. See httpStatic in the settings file. You have to set httpAdminRoot too. set httpStatic to /data and httpAdmin to /admin (the former is a filesystem path, the latter a URL path, confusing...). Then place a file foo.txt in /data, i.e., /_data/foo.txt on the host, with some simple text. You should be able to retrieve that using curl or your browser at http://my-synology:1880/foo.txt (using appropriate host and port). See that you can get this to work. You should also be able to retrieve your pem files like this (security issue!!). And the flow editor should then be at http://my-synology:1880/admin or however you set-up the httpAdmin variable. If these things all work then let's move to the next step. My hunch is they won't 'cause either the right dir is not mounted at /data or the settings file isn't working...

edit: do your PEM files have CR-NL line endings by any chance?

Hi @LCMilstein,
You can see an example here.
Bart

I assume in newer versions, these lines should do when uncommented

//         key: require("fs").readFileSync('privkey.pem'),
//         cert: require("fs").readFileSync('cert.pem')

First off, THANK YOU to all who are helping me here.
Second... PROGRESS...
I admit that I don't understand half of what @tve is suggesting re the static file server, but I grokked that we still think this is a permissions issue. I ran ls -nal /volume1/... on the folder where the certs were created and found drwxr-xr-x 3 0 0, so I figured I'd try:

chown -R 1000:1000 /volume1/...

This kinda worked! The container was no longer in a restart loop. HOWEVER, Chrome couldn't get me to Node-Red.

  • If I just put in my local IP and port, Chrome returns a result saying "This page isn’t working"
  • If I precede with https://, then Chrome says, "Your connection is not private" and "NET::ERR_CERT_INVALID"

SO... I'm thinking that I solved the first problem, but I somehow created the wrong type of certs?

  1. Is it ok for these certs to be in 1000:1000 permissions like I did above; and

  2. Does it sound like the issue is now the need to create new certs properly? If so, does anyone have an easy guide they can point me to since the one I had didn't seem to get it done?

Thank you again!