HTTPS refresh interval returning with an error

Hi everyone,

I have set my httpsRefreshInterval to 12 hours. But whenever it attempts to do the refresh, I get this error.
image

I'm not sure how to address this issue. Here are my current https settings.

https: function() {

       return {

             key: require("fs").readFileSync('/home/pi/.node-red/certs/privkey.pem', 'utf8'),

             cert: require("fs").readFileSync('/home/pi/.node-red/certs/fullchain.pem', 'utf8')

       }

    },
    httpsRefreshInterval : 12,

Hi @WhatDoor,

Sorry for the late reply, but I had overlooked your question.

I don't see at first sight what could cause this error. It is occurs at line 238 in the red.js file:

So what happens when your httpsRefreshInterval timer is executed:

  1. Line 235: The contents of your privkey.pem file are read (via your readFileSync command), to get your private key.
  2. Line 235: Also the contents of your fullchain.pem file are read (via your readFileSync command), to get your corresponding certificate.
  3. We only arrive at line 238 if both file exists and have been read.
  4. Line 238: it is checked whether you have already a server.key. Which means Node-RED checks whether the NodeJs http(s) server has already a private key. If there was previously no key used in your NodeJs http(s) server, then the key from your privekey.pem file should be used anyway.
  5. Line 238: it is also checked whether your current private key (refreshedHttps.key) is equal to the server.key. Which means Node-RED checks whether the key that the NodeJs http(s) server currently uses is equal to the key from your privkey.pem file. Because we only update the private key in the NodeJs http(s) server when that key has changed.

In your case step 5 fails. Which means the server.key is not undefined, but I assume it is not a string (like we expected).

My first thought was that perhaps in a recent NodeJs version, the server.key mechanism has changed an it now returns a function or a promise or ... But when I look at the NodeJs code, I don't immediately see something different (like a wrapper function or something like that) :woozy_face:

Can you give some more information:

  • Your NodeJs version (from your Node-RED startup log)
  • How you created your private key
  • ...

Bart

1 Like

Also, what version of node-RED are you using

What do you get if you format the https section exactly the same as the settings.js template?

     https: function() {
         return {
             key: require("fs").readFileSync('/home/pi/.node-red/certs/privkey.pem'),
             cert: require("fs").readFileSync('/home/pi/.node-red/certs/fullchain.pem')
         }
     },
1 Like

Thanks for responding both. Here are my versions, that I pulled from the top of the nodered log after restarting it.

Node-RED version: v2.0.3
Node.js version: v14.17.2

I generated the certificates with lets encrypt certbot. They seem to be working as I am able to set up https for my webserver.

@Paul-Reed, I've changed the format to follow the example you have given. I'll follow up to see if there is a change.

1 Like

Hey both, looks good now.

I can only assume that the utf8 flag caused the issue. Though its not clear to me why that would be the case.

2 Likes

I 'think' it is becoming clear to me know why it fails in your case.
When I implemented this feature (see pull request), I checked whether the private key was updated in this way:

if ( ... !server.key.equals(refreshedHttps.key) ... )

In Java that would have been fine, but seems now not in Javascript...
Whether the server.key has an 'equal' function, depends on how you read your key file:

  • key: require("fs").readFileSync('...') returns a raw buffer, since you have not specified an encoding (see here). And a NodeJs buffer contains an equals function (see here).
  • key: require("fs").readFileSync('...', 'utf8') returns a string, and in Javascript a string has no 'equals' function :roll_eyes:

Seems my old Java background has caused this issue ...

@knolleary : I assume it is best if we fix this, because keys/certificates in string format should also work correctly... But not sure if you have a preferred way to check the equality of two items? Simply by coding, or by using an npm module, or ...

Please raise an issue so it doesn't get forgotten.

The equality check needs to handle both buffer and string types. There's no need to use an external module to do that.

P.S. I have created a pull-request, on the master branch.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.