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

I'm definitely pro generating the hash, but still think it has to be added to the file manually. I think Nick described the no-to-editing the settings file as the file is a javascript file, and has to properly validate. Since every user can make changes to that file themselves it's hard to properly add something in, especially when doing so from a node. Because a bracket in a wrong place can already mean it stops working, because it's now a syntax error. Same for a missing comma.

The above was written by Nick in a lounge topic on the subject.

Yes absolutely! Nick explained some time ago that some users put custom startup Javascript code in their files, so I'm not going to change or execute that.

Had not much time today, so the readme page is not updated yet.
But I have added a password field on the config screen (in new version on Github).

  1. Enter a password e.g. my_password

  2. Hit the 'arrow' button and then the password hash will be calculated, and also the password strength (which will show a different color depending on Weak, Medium or Strong):

    acme_password

    P.S. The password and the hash won't be saved! So the next time you open the screen, they will be gone (since you don't need them anymore in this node...).
    P.S. You can get different hash values when you generate the hash for the same password multiple times. That is normal ...

  3. You need to copy manually this hash in your settings.js file:

    image

  4. Restart Node-RED

  5. When navigating to Node-RED you will get a login screen. Pass your username (e.g. "admin") and your password (e.g. "my_password"):

    image

  6. Normally you should now be granted access to your Node-RED editor :champagne: :cocktail: :partying_face:

Any thoughts?

P.S. I'm not trying to push people to use port forwarding instead of a VPN, for those who might wonder!

2 Likes

Hello, Bart.
I'm going back to the access from outside your house. Now it's okay, https, certificates it's okay.

But now i have to add a password request on the dashboard too, just like on the publisher.
But it's good from the outside as much as it's annoying when I'm at home.
There to have the Dashboard, I don't want NR to ask me for a password. Would it be possible to have the best of both worlds?
Outside = password
Inside = no password

Is there a setting in NR that would say, if internal network (example 192.168.x.y) does not ask for the password.

I don't want to talk about Trafeak, or Juniper, or Netscaler which is not for a "normal" user.

Thanks for the ideas or solutions

Jean-Luc,
I'm not sure whether Node-RED supports that. Think it might be better to create a new discussion about that, to increase your chances to get a response...

1 Like

Some changes on Github:

  • I have added a new section on the readme page about how to generate a password hash with this node.

  • To renew a certificate you now need to inject a msg.payload="request_certificate" instead of a random message.

  • It is now also possible to inject a msg.payload="get_certificate_info" (as described in this section) to get information about the current certificate:

    image

    This can be used to trigger an alarm, or e.g. to trigger the renewal when your certificate is going to expire in N days from now.
    If somebody create an example flow for these kind of use cases, please share those here!! Thanks

So this node is becoming more a security toolbox (renewing certificates, inspect certificates, generate password hashes) :champagne: :cocktail: :partying_face:
But not sure anymore whether node-red-contrib-acme-client is the best name for this node, since it does more than acme ???

2 Likes

I didn't dare to say it,
but indeed when we talked about HTTPS & Certificates it still spoke to me,
but not the ACME protocol. I didn't know it at all.
This node handles Certificates & Letsencrypt. So a name around that ?
Like node-red-contrib-certificate-ask-renew-Letsencrypt?
Well, maybe it's a little long for a name :thinking:
The idea of tracking the dates of application and revocation is great.
Indeed, with this information, we can send each other an email in a preventive and automatic way.
Mmhhh, you still need to be able to code it :slight_smile: Sending emails is easy, subtracting 2 dates and scheduling the email is another story for me. To be continued...

Bravo and thank you for these 2 Nodes (web-push) I use them now in "production".

Personally, I would recommend to use port forwarding to expose node-RED - I wouldn't use the default port on the Internet. I also recommend that for SSH as well. That's because automated bots check for common ports then try to attack them. Using a non-standard port greatly reduces those attempts.

If you are looking to expose multiple instances, I would recommend the use of a reverse proxy instead. that way, you can assign port-based instances to virtual folders in your web site and you only need to expose port 443 (or choose something more obscure if you like).

Of course, if your purpose is to expose Node-RED to the Internet using a Let's Encrypt certificate, I would strongly recommend using Caddy instead which has LE support built in. Then you don't need to put HTTPS onto Node-RED at all. Simples.

1 Like

Or node-red-contrib-certificate or node-red-contrib-certificate-renewal???

There is now a new version on Github.
The output message now contains a calculated field expiresInDays (which is negative when the certificate already has expired):

image

The following flow uses this field to renew the certificate two days before it expires, and triggers an alarm as soon as the certificate has expired:

[{"id":"70a6d890.f393b8","type":"inject","z":"11289790.c89848","name":"Get certificate info daily at 22:00","topic":"","payload":"get_certificate_info","payloadType":"str","repeat":"","crontab":"00 22 * * *","once":false,"onceDelay":0.1,"x":340,"y":480,"wires":[["92f9265b.fc36d8"]]},{"id":"92f9265b.fc36d8","type":"acme-client","z":"11289790.c89848","name":"Acme client","authority":"letsencrypt","dnsProvider":"duckdns","dnsToken":"your_duckdns_token","dnsUserName":"","dnsEmail":"","dnsApiUser":"","dnsKeyId":"","dnsKey":"","dnsSecret":"","domains":"[\"your_subdomain.duckdns.org\"]","domainsType":"json","certFilePath":"/home/pi/.node-red/cert.pem","keyFilePath":"/home/pi/.node-red/privkey.pem","privateKey":"existing","maintainerEmail":"your_email_address","subscriberEmail":"your_email_address","useTestUrl":false,"x":610,"y":480,"wires":[["d09e255e.fce988","f4ff75c9.781488"],["61a48ed.3a5637"]]},{"id":"d09e255e.fce988","type":"debug","z":"11289790.c89848","name":"Certificate info","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":820,"y":440,"wires":[]},{"id":"f4ff75c9.781488","type":"switch","z":"11289790.c89848","name":"Check expiresInDays","property":"payload.expiresInDays","propertyType":"msg","rules":[{"t":"lt","v":"0","vt":"num"},{"t":"eq","v":"2","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":840,"y":480,"wires":[["d44416f6.d6b008"],["4f263587.3f983c"]],"outputLabels":["Expired!","Two days before"]},{"id":"d44416f6.d6b008","type":"debug","z":"11289790.c89848","name":"Alarm: Certificated is expired !!!","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1110,"y":460,"wires":[]},{"id":"5241e044.c402e","type":"change","z":"11289790.c89848","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"request_certificate","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":520,"wires":[["92f9265b.fc36d8"]]},{"id":"4bde2da9.5ad0f4","type":"link in","z":"11289790.c89848","name":"Renew certificate","links":["4f263587.3f983c"],"x":200,"y":520,"wires":[["5241e044.c402e"]],"l":true},{"id":"4f263587.3f983c","type":"link out","z":"11289790.c89848","name":"Two days before expiration","links":["4bde2da9.5ad0f4"],"x":1100,"y":520,"wires":[],"l":true},{"id":"61a48ed.3a5637","type":"debug","z":"11289790.c89848","name":"Problem detected","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":830,"y":520,"wires":[]}]

I quickly created this flow. Suggestions for improvement are welcome.

I was going to ask the same question as @krambriw
I don't know how you are validating the domain, but for example, one of Certbot's validation options is to spin up a webserver on Port 80, so Port 80 would need to be open to enable validation.
Apart from the Port serving the service, are any other Ports required to be open?

node-red-contrib-ssl would mean much more to me than node-red-contrib-acme-client. Until your post, I've never heard of acme-client, so I certainly would not have searched for it.
Just my opinion :wink:

That is how I did it in my first version of this node. It is called a http01 challenge: you get a little file from Letsencrypt, and you have to make that file avalaible on a specified path on a webserver. It needs to be on port 80 because you can only listen to port 80 as root user. Letsencrypt tries to read the file and compares it with its original file (that they have send to you). When it is ok they know you are the owner of the domain (specified in the certificate request), because they know you can logon as root user.

However now I use the dns01-challenge: you need to send a request to your dns provider (e.g. duckdns) to add an informational TXT record, containing some info you received from Letsencrypt. Letsencrypt calls your domzin and checks whether yor TXT record contains the required info. When it matches, they know you own the domain because you can logon to the dns provider to store the TXT record. So NO (temporary) webserver on port 80 required. You can even use this for internal servers that are not online accessible...

Yes I'm afraid users don't even have a look at this node.
P.S. Is ssl as node name not a bit too wide?

2 Likes

Yes... unless you are willing to pick up the mantle of chief security officer. :slight_smile:

3 Likes

Well it's only a matter of time before someone else creates an obscure contrib node with some weak remote relationship to 'ssl' and names it 'node-red-contrib-ssl' .

I'd rather the 'top level' node name go to something worthy :smiley:
Just my opinion.

1 Like

I tried to change my username to @TotallyInformation, but seems some guy named Julian already has reserved it. So unfortunately I cannot become the chief security officer... My apologies :wink:

Yes that is true. But perhaps something like node-red-contrib-certificate-renewal or node-red-contrib-certificate or something alike is better. But surely the acme-client name is not good for my download statistics ...

P.S. I also regret that I hadn't called my node-red-contrib-xterm node instead node-red-contrib-terminal, because it is very unpopular (and I have spend LOTs of time in it ...)

1 Like

Oops

image

So rename it & mark old one as depreciated, redirecting user to install the new node. (for both acme and xterm)

they deserve to be more popular IMO :+1:

2 Likes

:rofl: :rofl: :rofl:

How about node-red-contrib-lets-encrypt since that is the accurate name :wink:

Certificate would also be too broad surely as someone else might well come up with a more generic process for managing certs.

3 Likes

That was the original name of the repositort. But I renamed because there can be other acme providers...
But can live with it...

Yes was thinking the same last night. It is more z name for a sidebar panel for managing stores and keys and certificates...

ionos.co.uk are the largest hosting company in Europe and host 12 million domains, yet I don't see them in the DNS list.
Are they not compatible with acme?

Will need to add that to my readme page.
The guys from the "root" group (who build this library) have added a tutorial on how to build such a plugin. There is also a "contact" link on the bottom of the page, but that doesn't seem to work. But haven't done it myself yet. Will do that once I'm retired :wink:

Paul, based on what a quick google search showed they’re indeed not compatible as they don’t allow (through api or otherwise I couldn’t find) TXT dns records. So you could do it manually set your A record, take web server down, issue challenge and bring it up again but things like wildcard certs will be hard or impossible. All the while asking customers to instead pay for their certificates that could be set up through LE/ACME instead.

https://github.com/go-acme/lego/issues/727 See this issue

2 Likes