[ANNOUNCE] node-red-contrib-letsencrypt : beta version


:warning:
EDIT 20/05/2020: Since there was a lot of confusion about the name, this node has been renamed from node-red-contrib-acme-client to node-red-contrib-letsencrypt. So the links below won't work anymore. The new repository is available here.


Hi folks,

A week ago I announced the alpha version of this node. I was completely stuck, but thanks to @VinistoisR and @TotallyInformation I realized that I should use a dns01 challenge instead of a https01 challenge, both for private and public accessible Node-RED systems. Thanks to their knowledge sharing, I managed to create this beta version. And that works much better!

CAUTION: like Vinistois has explained nicely in another discussion, it is much safer to use a reverse proxy in combination with containers (e.g. Docker). So I have also highlighted that in my readme page! And I have also added that LetsEncrypt certificates can be requested in all kind of places outside of your Node-RED environment. So would like to not discuss those alternatives here!

Instead this node is for all our users that have a simple Node-RED setup (due to lack of time, limited technical knowledge, or whatever reason...). We should assist these users in adding minimal security to their Node-RED system. I hope that this node might be a first aid, since it allows users to request and renew trusted LetsEncrypt certificates simply by injecting a message.

How it works in a nutshell:

  1. Enter all your settings in the config screen (https - DNS provider - LetsEncrypt account):

  2. Inject a message every time you need to renew the certificate (which will be valid for 3 months):

    image

  3. If everything went well, your Node-RED keystore should contain your renewed certificate.

Some remarks:

  • If you want to test this beta version, please make a temporary copy first of your privkey.pem and cert.pem file first. Just to make sure I don't corrupt your system.

  • Currently you will need to restart your Node-RED to activate the renewed certificate. I still need to finish my pull request proposal for automatic certificate renewal.

  • This node supports a number of DNS providers, but I have only tested DuckDns yet!

    image

    It would help a lot if anybody could test some of these other providers ...

  • I have added a introduction about security to my readme page, but now it perhaps has become too long to read. Should I move that part to my wiki pages perhaps?

  • Currently the privatekey.pem and cert.pem file should already exist, otherwise I give an error. But I could also:

    • Create those pem files automatically when they don't exist yet.
    • Only create them whe a checkbox 'create unexisting pem files' is selected, e.g. in case you want to use existing pem files, and you want to get an error if they don't exist yet...
    • Allow extra input messages with topics like "create_new_keypair", "renew_certificate", "create_new_key_file". Or is that perhaps too dangerous and too technical?

    Not sure which way too go...

  • The logging should be updated a bit, because it contains lot of blancs instead of values.

  • I need to add a troubleshooting section, e.g. use https://dnslookup.online/txt.html to check whether the (temporary) TXT record for ACME has been published by your DNS provider on your domain (where LetsEncrypt can search for his DNS validation token). For example:

    image

As usual all "constructive" feedback is more than welcome!!

Have fun with it!
Bart

8 Likes

Fantastic Bart!!

Does this mean that this is the only thing you need to do to get a pretty secure connection from internet to a NR instance running in your network? Besides, I assume, making a port forwarding/virtual server configuration in your router (80 <-tcp-> 1880)?

What if I have several NR running in my network? A port forwarding can normally only be made for one computer per port and if LetsEncrypt requires port 80...

Anyway, very understandable and explanatory write-up on github, explaining very well the details behind. Very well explained also where you can decide to insert the protection. I mean, having it as far out as possible (like with the dns provider or in the router seems to be the best but requires more technical konw-how and configuration work) but for normal home usage this could be good enough I assume

One dns service I miss (maybe because I use it :wink: ) is No-IP. I think they are widely used, not so uncommon. I don't think a token is needed, just a domain name

Great work!!!

Hi Walter,
Yes I think all you need to do is uncomment the https setting in your settings.js file, to instruct Node-RED to use https. And to specify the path of your both pem files (privkey.pem and cert.pem) for Node-RED. I will add functionality to my node to create those files when they don't exist yet (see my question above), but the you need to run my node once (via an input message) before you uncomment the https section in the settings.js file. Otherwise Node-RED won't start beczuse both files are missing... You can also generate both files via opensll command line manually, but then it becomes not user friendly again...

P

Yes but as explained that is being considered as less secure. But lots of people (like myself) will do it like that. But if anybody has concerns, please start a separate discussion!

Yes I only offer the providers that are available in the acme.js library. But you can request it there if you want (they offer that support if I'm not mistaken), so I can add it afterwards to my node. There are also third-party plugins on npm for other providers, but those all seem to be removed due to malicious behaviour!!!

@BartButenaers
Hi Bart
Thanks for the great work
I have tried to install on a number of different pi's and get this error
npm ERR! code ENOENT
npm ERR! syscall spawn git
npm ERR! path git
npm ERR! errno ENOENT
npm ERR! enoent Error while executing:
npm ERR! enoent undefined ls-remote -h -t ssh://git@github.com/bartbutenaers/node-red-contrib-acme-client.git
npm ERR! enoent
npm ERR! enoent
npm ERR! enoent spawn git ENOENT
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

I have then tried to install in a NR instance on Docker and this installs fine but creates all kinds of other issues.
Any advice on why it will not install on the pi?
I have tried to install manually by copying the files and changing permissions, package.json etc but still no luck

in order to install direct from github you need a command line git client installed... sudo apt install git ?

2 Likes

The below worked fine for me, rpi3, buster, NR 1.02

Run the following npm command in your Node-RED user directory (typically ~/.node-red):

npm install bartbutenaers/node-red-contrib-acme-client
1 Like

Hello Bart,

So I tried to install this node.
Here's what I had to do:

  1. create an account on Duckdns
  2. My Pi machine name already existed in Duckdns, so I invented a domain name to reach me from the outside, for example toto.duckdns.org
  3. I have received a token in return.
  4. I had to change the name of my Raspberry to toto with raspi-config
  5. Reboot the Pi and rename the files
    flows_old-name.json into flows_toto.json
    flows_ old-name_cred.json into flows_toto_cred.json
    Node-Red-Start
  6. Modify my router to NAT the external port 80 to port internal 1880
  7. Tested whether from outside NR can be reached via a browser http://toto.duckdns.org
    --> Test Ok
  8. Install the code with the command: npm install bartbutenaers/node-red-contrib-acme-client
  9. Imported the example flow
  10. Enter the infos, deploy, I received this message and also received later an email from acme-js@rootprojects.org to inform me that the account has been created.

image

However I don't have the 2 *.pem files in the /home/pi/.node-red directory. They were not created.
Which is why I can't create a CSR to send to Letencrypt. Here's the log of NR

image
So I missed a step, but I don't know which one. Any ideas? Thanks.

The node configuration:


Yes, both files need to exist.
That is why I had added a question to my original post above (which unfortunately nobody has answered...):

So this is something I still need to do, to avoid that users need to create these files manually via command line (as they had to do in the past, which I find very inconvenient for less technical users).

So if anybody has advise about this, I would like to hear it !!

Sorry,
I had understood and especially misread that this node would create the original certificate application and then take care of renewing it.
This comes from the fact that I don't speak very well english :face_with_hand_over_mouth: and that I'm not paying attention :thinking:.

So I have to use the command lines to generate my certificates and then use your node for the renewal. Right? I already did it on my test VM.

My goal is to be able to do web-push and see if I can actually do without telegram.

I'm indeed a pretty recent user on Linux and NR and I particularly appreciate these nodes that do everything, all alone :+1:t3: and the people who make them !

Yes it should generate also the first certificate but it is a TODO that the files should exist.
But at the moment you should generate both files manually.
Very stupid. Should really need to fix that!

Think I know a solution to do this automatically. Hopefully I have some time this evening to implement it...

1 Like

Hey Jean-Luc (@Jean-Luc),

The new version on Github contains a dropdown to specify how to handle the private key:

image

The default selected option is "use or create private key". This means that:

  • If a private key exists already (in the specified privkey.pem file), then that private key will be used.
  • If no private key exists yet (i.e. the privkey.pem file does not exist yet), then a new private key will be created. And after the certificate arrives, both the privkey.pem and the cert.pem files will be created automatically.

Summarized you can now use this node to do all the following stuff automatically:

  • Create a keypair (public key and private key) automatically.
  • Request a trusted certificate at Letsencrypt.
  • Store the private key in the privkey.pem file (only when a new key is created).
  • Store the certificate in the cert.pem file.

And as soon as I have implemented and tested the (very useful) feedback from Nick and Dave on my pull request, Node-RED should also be able to load the renewed key pair automatically. Then the only thing you need to do manually (afterwards as soon as the files are created), is uncommenting the https property in your settings.js file!

Hopefully less-technical users can now also secure their Node-RED system with SSL :cocktail: :champagne: :partying_face:

Please let me know if it works!
Bart

2 Likes

@BartButenaers
I think this is amazing! Currently and since long, I access my private network via VPN but if I should start testing this, some thoughts came to my mind. Thinking & wondering if it might be important in what order you are configuring things?

  1. Install and configure the node, certificate, keys etc
  2. Restart NR (until a new version is available that reloads the key pairs automatically)
  3. Open up & forward ports in your firewall (this step must be done after 1) and 2), otherwise you may have NR unprotected for a while)

Also, what ports should I open up and forward in my firewall? Is it enough with port 1880?

If I have several NR's running on different computers, I assume I have to open & forward the port for each of them provided I set different ports for each (like 1880, 1881, 1882 etc)?

(what ports are needed

Bart,
what more can I say than BRAVO!
What a job in such a short time. :muscle:
Everything went well.
I was able to create and install the certificate without problems for access to NR encrypted via the outside.
I enclose some screenshots for other users like me who are not in this field.
I will soon be able to test with my production machine the Web-Push with your node which was at the origin of all this.
Great job really.

NR log:
image


NR directory files certificate:
image
NR flow:

Inside Firefox:
image

image
image

2 Likes

@Jean-Luc,
Thanks for your feedback! Now at least I know if it is working for other people or not.

@krambriw,

  1. Add a username and password in your settings.js file.

    I perhaps can add a button to my config screen to generate a password hash (sha256) from a specified password? That way we can avoid that users need to have to use the node-red-admin hash-pw command line...

  2. Configure and trigger this acme-client node.

  3. Restart Node-RED to reload the new key pair ( indeed required until the pull request is completed).

  4. Open up & forward port 1880 in your firewall. This ONLY required if you want to publish your Node-RED system to the internet. It is NOT required to request Letsencrypt certificates!

  5. Uncomment the https setting in your settings.js file

So you don't have to publish any ports to the internet if you don't want people to be able to connect to your system. You can also request certificates for internal servers. But then you need to setup dns forwarding on your router, so that e.g. walter1.duckdns.org is forwarded (on your local network) to the ip address of your first server, and walter2.duckdns.org to your second server and so on. But perhaps others on this forum might be able to explain that better. Because you can also use wildcards ("*") in your certificates, but I didn't have time yet to explore that ...

1 Like

Dear Bart, excellent, so cool!!!

I think your idea with such a button is very good, it removes another thing that will further improve & simplify the setup for users. Maybe also uncomment the https setting at the same time?

As far as external access to the Dashboard is concerned, it would be nice to have 2 authentication factors.
On the other hand, when accessing the Dashboard from the local network, there is no need to identify yourself.
Any idea if this would be possible?
It might be possible to have 2 URLs for the same NR, one accessible by https+login+OTP and the other without anything, direct access.

Then I think you need to have an Acme client on your router, so you only have Letsencrypt certificates when you arrive from the internet.

I use LetsEncrypt certificates also on my local machines, e.g. to test all my nodes from my portable. Because then I also need SSL with trusted certificates. But on the internal network I do DNS forwarding on my router (i.e. the duckdns address to ip address of my raspberry):

Generating the hash sounds good, but having the node edit the settings file doesn't. There's enough topics mentioning something similar to that, and all with strict discouragements in it.

OK, was not aware of that. But isn't the generated password hash also written to settings.js? I think I remember I did exactly that manually earlier. But you mean nothing should be written to the settings by nodes?