# Node-RED SSL using Letsencrypt & Certbot

**URL:** <https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606>\
**Category:** Share Your Projects\
**Tags:** security\
**Created:** [6 November 2019 20:22 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606 "2019-11-06T20:22:22Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![recursivecodes](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/recursivecodes/32/13422_2.png) [@recursivecodes](https://discourse.nodered.org/u/recursivecodes)\
**Post date:** [15 November 2019 14:21 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/21 "2019-11-15T14:21:43Z")

</div>

I missed this post before - Nice work @Paul-Reed!

---

<div class="post-metadata">

**Author:** ![mattia\_pi](https://avatars.discourse-cdn.com/v4/letter/m/e9a140/32.png) [@mattia\_pi](https://discourse.nodered.org/u/mattia_pi)\
**Post date:** [15 December 2019 21:58 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/22 "2019-12-15T21:58:07Z")

</div>

@Paul-Reed Thank you for this post! it is great what have you done here. By the way I ask here for some helps. The explained configuration with apache goes straight but now I cannot access my node-red anymore. I'm getting this error in the browser.

```auto
# Proxy Error

The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request

Reason: **Error reading from remote server**

Apache/2.4.38 (Raspbian) Server at 192.168.0.38 Port 80

```

For sure is a config apache server problem. Anyone can explain what is wrong ?

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [15 December 2019 22:10 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/23 "2019-12-15T22:10:38Z")

</div>

> [@Paul-Reed](#):
>
> ....no other webserver (such as apache) has been installed. If you do intend to also run another webserver as well as node-RED, then the Certbot installation is slightly different and not covered here

Sorry I've not installed apache, so can't really help further with apache related errors.  
Hopefully other members will be more familiar with apache, and be better placed to assist.  
This guide was really intended for non-apache users for that reason.

---

<div class="post-metadata">

**Author:** ![ioanpenu](https://avatars.discourse-cdn.com/v4/letter/i/4af34b/32.png) [@ioanpenu](https://discourse.nodered.org/u/ioanpenu)\
**Post date:** [16 February 2020 10:29 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/24 "2020-02-16T10:29:42Z")

</div>

Hi guys,

I would need a bit a help from you. I am having a Raspberry with node-red which is accessible through VPS. RPi starts automatically at boot a ssh reverse tunnel to a VPS and then I can reach RPi through VPS. Port 80 of the VPS is forwarded to port 1880 on RPi. On VPS I'm having a domain configured, so I can access node-red on RPi when I'm opening a page to [http://domain.com](http://domain.com).  
My question would be - if I would like to use SSL, where should I install the certificates, on VPS or on RPi? What else should I configure? Have anyone from you implemented this? Thank you very much in advance.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [16 February 2020 12:38 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/25 "2020-02-16T12:38:41Z")

</div>

> [@ioanpenu](#):
>
> I would need a bit a help from you

Are you using Certbot & Letsencrypt?

---

<div class="post-metadata">

**Author:** ![ioanpenu](https://avatars.discourse-cdn.com/v4/letter/i/4af34b/32.png) [@ioanpenu](https://discourse.nodered.org/u/ioanpenu)\
**Post date:** [16 February 2020 13:28 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/26 "2020-02-16T13:28:26Z")

</div>

Yes, I would like to use Certbot and Letsencrypt, but don't know whether I have to install it on RPi or VPS side.  
What I did so far: installed Certbot on RPi and requested a certificate with command "certbot certonly --standalone", but this fails with error:  
Domain: [mydomain.com](http://mydomain.com)  
Type: unauthorized  
I assume this is because of the fact that [mydomain.com](http://mydomain.com) is set on VPS and not on RPi.  
Then I've installed certbot on VPS and requested a certificate with mydomain. This worked, I've got a certificate and key but don't know if this is right. If yes, don't know what to do next.  
Thank you very much.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [16 February 2020 15:08 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/27 "2020-02-16T15:08:09Z")

</div>

Hi Ioan,

I have _ **no** _ knowledge about certbot, but I'm about to announce a new LetsEncrypt node for Node-RED. So I have been playing with the acme protocol already, which hopefully can get you a bit started ...

- When you _ **request a new certificate** _ for a domain ([mydomain.com](http://mydomain.com)), the guys from Letsencrypt have to be sure that you are the owner of [domain.com](http://domain.com). Otherwise everybody could request a certificate, which means it wouldn't be secure anymore ...

- Once you have received your Letsencrypt certificate, that certificate should be used by your webserver when you connect to Node-RED:

Good luck!  
Bart

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [16 February 2020 20:53 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/28 "2020-02-16T20:53:45Z")

</div>

Hi Bart, the process you outline isn't the only one. You can also validate via DNS _if_ your DNS provider supports the appropriate protocol (which Cloudflare and others do).

That is a much better process for home users as it means that you don't have to expose your home network to the Internet just to get certbot to work.

Some details here:

> **[How to create secure certificates](https://it.knightnet.org.uk/kb/nr-qa/https-valid-certificates/)**
>
> Generate certificates for Node-RED that are trusted by all modern browsers. This will let you access Node-RED (and other services) over an encrypted HTTPS link.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [16 February 2020 21:29 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/29 "2020-02-16T21:29:33Z")

</div>

...as described in [https://letsencrypt.org/docs/challenge-types/](https://letsencrypt.org/docs/challenge-types/) it can be more difficult to implement as it's necessary to create a TXT record, and place it under the domain name.  
There are also security concerns in the event of the web server being hacked.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [16 February 2020 21:38 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/30 "2020-02-16T21:38:32Z")

</div>

> [@TotallyInformation](#):
>
> Hi Bart, the process you outline isn't the only one. You can also validate via DNS _if_ your DNS provider supports the appropriate protocol (which Cloudflare and others do).

Hi Julian,  
Indeed I only have been discussing the "http-01" challenge. But suppose the RPI (running Node-RED and Certbot) isn't connected to the internet. How does certbot gets its certificates then?  
On this [link](https://blog.heckel.io/2018/08/05/issuing-lets-encrypt-certificates-for-65000-internal-servers/) I found this sequence diagram:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/3/536aa98b94c5343c95e7869150c6bf76fff18177.jpeg)

E.g. not clear to me what the control server would look like. Could you please explain (in dummy language) what a home setup could look like to request Letsencrypt certificates for RPI's that are not exposed to the internet. Because it would be very nice if each internal device could have Letsencrypt certificates ...

Thanks !!!!!

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [16 February 2020 22:14 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/31 "2020-02-16T22:14:09Z")

</div>

> [@Paul-Reed](#):
>
> There are also security concerns in the event of the web server being hacked.

Useful points of Note Paul. For me not a problem, the Cloudflare DNS is entirely separate to any web servers and separate to any other ISPs and has its own 2-factor auth. In addition, the updates run from a Pi that doesn't present at all to the Internet - indeed, that was the whole point of using the DNS method for me. If you have an Internet facing web server, then the http method will be simpler but is much more complex if not. Creating a TXT entry on a good DNS service like Cloudflare is trivial.

> [@BartButenaers](#):
>
> But suppose the RPI (running Node-RED and Certbot) isn't connected to the internet.

Well, it _has_ to be connected to the Internet somehow or you can't interact with Let's Encrypt at all can you? 🙂

With the http method, you have to expose a web server to the internet. With the DNS method, you don't. So for me, I've registered a spare domain and used the DNS method but the server that consumes the domain names is never reachable _from_ the Internet. My router provides internal DNS routing which allows the certs to work.

To update the certs, a script runs that connects to Let's Encrypt from the registered domain - so LE see's the script's connection as coming from the registered domain and checks the DNS (Cloudflare) for the TXT record (rather than having to check a web server for it).

Hope that makes sense?

> [@BartButenaers](#):
>
> it would be very nice if each internal device could have Letsencrypt certificates ...

Well, I cheat - I registered a wild-card, multi-domain cert 🙂 Then I sync the cert files if I need to. The important thing is to ensure that the private key file is kept completely secure.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [16 February 2020 22:27 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/32 "2020-02-16T22:27:23Z")

</div>

> [@TotallyInformation](#):
>
> With the DNS method, you don't.

I will need to digest that next week 😉  
The RPI is not connected to the internet, then I don't understand how it's certificates can be updated... Or do you mean that your router requests the certificate from Letsencrypt, and passes them somehow to the RPI. Or does the RPI never get the certificate, and you keep the private keys/public keys somewhere else?  
If you have some time, a quickly drawn sketch on a small piece of toilet paper perhaps would be sufficient to demystify this mechanism 🙄  
Appreciate your feedback!

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [16 February 2020 22:45 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/33 "2020-02-16T22:45:03Z")

</div>

I think it's this comment which is causing the confusion;

> [@TotallyInformation](#):
>
> you don't have to expose your home network to the Internet

I suspect that Julian was describing;

> you don't have to expose your home network to the Internet **by spinning up a webserver on Port 80**

In all cases, an internet connection is necessary otherwise, as Julian has said;

> [@TotallyInformation](#):
>
> Well, it _has_ to be connected to the Internet somehow or you can't interact with Let's Encrypt at all

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [16 February 2020 22:50 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/34 "2020-02-16T22:50:31Z")

</div>

> [@BartButenaers](#):
>
> The RPI is not connected to the internet

The Pi can reach **OUT** to the internet but nothing can reach **IN**. So the script runs, contacts the LE servers to request an updated cert. LE checks DNS, approves the request and the updated cert comes in via the same connection. At no point can anything from the Internet connect to the Pi. Everything is driven from the Pi connecting to the LE server.

In other words, everything is PULLed by the Pi from the LE servers, never PUSHed from the Internet. This is much safer & requires no messing with your router, firewall or web server.

---

<div class="post-metadata">

**Author:** ![Roaders](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/roaders/32/11282_2.png) [@Roaders](https://discourse.nodered.org/u/Roaders)\
**Post date:** [23 May 2020 14:10 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/35 "2020-05-23T14:10:55Z")

</div>

Great post. Many thanks.

Out of interest why do you copy the certificates to a different folder rather than just using them where they are generated?

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [23 May 2020 14:39 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/36 "2020-05-23T14:39:56Z")

</div>

> [@Roaders](#):
>
> Out of interest why do you copy the certificates to a different folder rather than just using them where they are generated?

Node-RED normally runs as a 'user', and Letsencrypt creates the certificates in `etc/letsencrypt/live/` with root ownership, and therefore without changing the ownership of the certificates to `pi`, node\_RED would not be able to read them.

So... rather than start altering files that sit within the Letsencrypt directory, I prefer to copy the certificates to the node-RED user directory and then use chown to make them readable (it's all done by the script).  
That then keeps the two services independent, and for me has the advantage that when I back-up node-RED, it also backs up the node-RED certificates in the NR user dir. If I ever needed to quickly restore the backup, I could be back online, complete with https in minutes without having to worry about Letsencrypt/Certbot.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [3 June 2020 08:29 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/37 "2020-06-03T08:29:03Z")

</div>

Split this topic on 3 June 2020 08:29 UTC

4 posts were split to a new topic: [OpenSSL Certificate not working](https://discourse.nodered.org/t/openssl-certificate-not-working/27701)

---

<div class="post-metadata">

**Author:** ![catonia](https://avatars.discourse-cdn.com/v4/letter/c/b5e925/32.png) [@catonia](https://discourse.nodered.org/u/catonia)\
**Post date:** [7 December 2020 17:45 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/38 "2020-12-07T17:45:38Z")

</div>

Hi Paul,  
thanks for sharing this usefull post!  
Anyway I have a question for anyone who can clarify me the following.  
I'm missing if (and when) the "renewal\_success" script will be run in order to copy the new generated certificates.  
In my understanding there was, in an earlier version, a cron job to do that. Now according to latest instructions the cron job is no longer needed (certbot setup by itself) thus I can't figure out who will call that script and when.  
Thanks in advance.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 December 2020 20:41 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/39 "2020-12-07T20:41:53Z")

</div>

I can't remember where all this started now. I can only give you my working setup and it has been rock-solid since I set it up in 2018.

I use the `acme.sh` shell script that runs on a CRON script **as a user** not root:

```auto
28 0 * * * "/home/home/.acme.sh"/acme.sh --cron --home "/home/home/.acme.sh" > /dev/null

```

I actually have 2 domains that I fetch certificates for, each cert having wildcard sub-domains specified so that I can use the certs for multiple uses (my needs aren't for too much security, if I were using this for internet facing services, I'd probably have separate certs for each service).

All of the resulting files are owned by the user that runs the CRON, not by root. That also isn't as secure and if I needed that security, I would run as root but then at the end of each run, have a script that changes ownership of the public key to allow it to be copied. But then you also have to allow the user running Node-RED and any other services to have read access to the private key or make copies of that as well. Can be done either way.

Because I'm running as the same user as NR and because I don't need lots of security, I simply point NR at the folder containing the certs/keys.

If you are copying things around, best to have separate certs for each use.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [7 December 2020 20:52 UTC](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606/40 "2020-12-07T20:52:09Z")

</div>

> [@catonia](#):
>
> I'm missing if (and when) the "renewal\_success" script will be run in order to copy the new generated certificates.

If you look at the first post in this thread, you'll see this section;

> [@Paul-Reed](#):
>
> Create a script called **renewal\_success** in `/etc/letsencrypt/renewal-hooks/deploy/`

There we create a script which certbot will automatically run, IF new certificates have been created (as it's in the `renewal-hooks` directory). That script will copy across the certs to your node-RED directory.

> [@catonia](#):
>
> In my understanding there was, in an earlier version, a cron job to do that. Now according to latest instructions the cron job is no longer needed

Correct when installed on a Pi, as the Certbot installation will create it's own time schedule as part of the installation.

[Previous page](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606.md?page=1)

[Next page](https://discourse.nodered.org/t/node-red-ssl-using-letsencrypt-certbot/17606.md?page=3)
