[ANNOUNCE] node-red-contrib-acme-client : early alpha version

Hi folks,

For my previous node-red-contrib-ui-web-push node, Chrome requires me to have an SSL connection to Node-RED with a trusted certificate.

So I really needed to use LetsEncrypt, to have free trusted certificates. There are a lot of ways to do that... However I wanted to have a way to allow users (with less technical background) to request LetsEncrypt certificates, fully integrated into their familiar Node-RED environment.

But near the end of my developments of node-red-contrib-acme-client, unfortunately suddenly it started becoming complex :frowning_face:
So this this node is NOT READY FOR USAGE, since some fundamental issues need to be solved and simplified somehow. But I'm stuck, so I would really appreciate if some folks with technical background could read through my readme page. It contains a lot of exclamation marks...

The two major issues summarized:

  • For Node-RED installations that are public accessible, a HTTP-01 challenge is being used. To implement that challenge, I need to make a file (which I have received from Letsencrypt) available for Letsencrypt again at port 80 (see last section in my readme page) :

    But I didn't find a way to listen for requests on port 80 from my Javascript code, since I don't have root priveleges. Unless I start Node-RED as root user, but that is again a very bad idea. So currently you have to setup manually a webserver on port 80, or let my node start a temporary webserver (which listens to a port xxxx above 1024) and use e.g. iptables to port forward from 80 to my xxxx port. Most awful workaround of my hobby career. :nauseated_face: :sob:

  • For Node-RED installations that are only private accessible, I should implement a DNS-01 challenge. The good news is that Acme.js (which I use under the cover) should support this, but the bad news is that I have no clue at all how I could integrate this in a solution without manual user interactions. Perhaps not possible?? No idea again, even after some explanation from @TotallyInformation :weary:

So all help is welcome for this node, which would assist users in securing their environment...

!!! THANKS A LOT !!!

Bart

3 Likes

P.S On the readme page there is a basic introduction about the purpose of this node. As you can see there, you only need to add a single node to renew (every x days) the Letsencrypt certificate in your Node-RED keystore:

image

  1. The Inject node triggers (e.g. every x days) the acme client node, which sends a certificate request (for your domain) to Letsencrypt. P.S. the domain is the hostname being used in the url to access your Node-RED application (https://:your_domain_name:1880).
  2. Letsencrypt checks whether you are the real owner of the specified domain.
  3. If everything is fine, Letsencrypt will return the requested certificate.
  4. The acme client node will store the certificate in the specified cert file, and (optionally) the private key in the specified key file. Normally this will be the Node-RED cert and key files, which are specified in the Node-RED settings.js file.

If we could this working together with the pull request for automatic certificate renewal, then users could setup everything within their Node-RED editor (which they are already familiar with).

4 Likes

I have greatest respect for the complexity, but I must say, if this succeeds, this must be a very valuable contribution to all NR users having the need to reach their system in a secure way from outside their network. I also really like the concept "automatic maintenance" (I guess we all do)

3 Likes

:wink: Undoubtedly, my terrible explanations.

The Acme client will only work with DNS-01 when using a compliant DNS provider service. I use Cloudflare for all of my domains now and it is compliant with DNS-01 amongst its many features. If I remember rightly, you simply have to add a TXT record and the Acme client does the rest.

I'm currently using the single script to get wildcard certs for two domains and it runs happily in the background via CRON.

Some people don't like the DNS-01 approach because of the weaknesses of the DNS system over all. I get their point and there would be many DNS services that I wouldn't want to use this way. But Cloudflare have a pretty good record and were early adopters of secure DNS services. So I judge this to be safer in my environment that opening up incoming firewall ports for Let's Encrypt to reach into.

It should be noted though that I'm only using these certs internally to get rid of the annoying browser warnings mainly. I let Cloudflare provide externally facing certificates for my web sites even though I use Netlify for them which also provides me with a cert. The reason is that I get much better usage stats and a number of additional security features via Cloudflare than direct from Netlify.

Not sure how this info might help you with the node though.

Undoubtedly not!!!

Damn there goes my single-node-solution...

Which script do you mean? From Paul perhaps?

Well I am already happy that I have somebody to discuss about this...

I think it was this one:

In fact, I see that this script actually supports DNS mode manually as well as automatically. Nice. Also, the script doesn't require root authority.


Ooh, just noticed that one of the script's notification methods is a webhook. Time to configure that to check in with Node-RED me-thinks. I did the same for my imapfilter scripts that also run via CRON, I get a notification in Node-RED as to how many new/unread emails I've got in my 2 main inboxes.

Thanks for the link. Will need to have a look at that because the readme page says "DOES NOT require root/sudoer access". Not sure how it can listen to port 80 then...

If you check out the docs, it says it does need root if you want to use a stand alone SSL server or "Apache"/"NGINX" mode (they don't recommend that anyway).

If you use an existing web server, the server requires the ability to control ports <1024 but not the script.

There are a number of ways to avoid having to use root-level privaledges for a server.

Probably the best is that you can use systemd which does have root to assign available ports to something that doesn't (If I read that answer correctly). I think this is what standard web servers use as then generally run under their own user/group. I might be wrong though, not an expert in this for sure.

Obviously, if you use the DNS method then you don't need to worry about that at all since you won't be opening up any incoming endpoints. You do want to have a secure DNS setup though.

1 Like