# MQTT - TLS encryption example

**URL:** <https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691>\
**Category:** Share Your Projects\
**Tags:** security\
**Created:** [8 November 2019 21:47 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691 "2019-11-08T21:47:17Z")\
**Posts on this page:** 7\
**Page:** 2

<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:** [12 November 2019 07:08 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/21 "2019-11-12T07:08:12Z")

</div>

Urm, please don't publish your certificate files here thanks. They are specific to you, we don't need them.

Also, as has already been mentioned, the cafile should be the CA ROOT and not your chain. The chain works but isn't correct.

---

<div class="post-metadata">

**Author:** ![skleeschulte](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/skleeschulte/32/20362_2.png) [@skleeschulte](https://discourse.nodered.org/u/skleeschulte)\
**Post date:** [12 November 2019 13:01 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/22 "2019-11-12T13:01:27Z")

</div>

@TotallyInformation The certificates I posted are not my own certificates, but official certificates from Let's Encrypt (as I explain in the answer). Providing this chain as _CA Certificate_ in Node-RED is a way to have Node-RED connect to Mosquitto while having the _Verify server certificate_ option checked. Why do you think this is not correct?

---

<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:** [12 November 2019 14:22 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/23 "2019-11-12T14:22:35Z")

</div>

> [@skleeschulte](#):
>
> The certificates I posted are not my own certificates

We don't really need certificate files in the forum as anyone using LE will have them anyway. It is also easy enough to make a mistake and paste something that should be kept secret.

> [@skleeschulte](#):
>
> Providing this chain as _CA Certificate_ in Node-RED is a way to have Node-RED connect to Mosquitto while having the _Verify server certificate_ option checked

This has already been covered in the other posts. I've also written a cookbook entry containing all the correct information as was also mentioned. You can check out the PR if you like.

> [@skleeschulte](#):
>
> Why do you think this is not correct?

1. Because it isn't the official information given in the Mosquitto documentation.
2. Because you've specified the root certificate chain in a user area of your device which is potentially more open to manipulation than the correct root CA entries that are kept in an area of the OS that isn't as easy to write to. That makes it easier for an attacker to replace the chain with their own to do a successful man-in-the-middle attack.

Small things for many users but the kind of thing that can easily make certificate-based security worthless.

The mantra when working with Public Key Infrastructures is that they are hard to configure securely and really hard to keep secure.

---

<div class="post-metadata">

**Author:** ![skleeschulte](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/skleeschulte/32/20362_2.png) [@skleeschulte](https://discourse.nodered.org/u/skleeschulte)\
**Post date:** [12 November 2019 15:33 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/24 "2019-11-12T15:33:15Z")

</div>

> [@TotallyInformation](#):
>
> Because it isn't the official information given in the Mosquitto documentation.

Which part of my post are you referring to? This is the portion of [the mosquitto.conf man page](https://mosquitto.org/man/mosquitto-conf-5.html) that I think is most relevant here:

> When using certificate based encryption there are three options that affect authentication. The first is require\_certificate, which may be set to true or false. If false, the SSL/TLS component of the client will verify the server but there is no requirement for the client to provide anything for the server: authentication is limited to the MQTT built in username/password.

> [@TotallyInformation](#):
>
> Because you've specified the root certificate chain in a user area of your device which is potentially more open to manipulation than the correct root CA entries that are kept in an area of the OS that isn't as easy to write to. That makes it easier for an attacker to replace the chain with their own to do a successful man-in-the-middle attack.

I don't see any problem here. The very moment someone get's access to what you call user area, he can access all the information that would be protected by a secure MQTT connection anyway.

> [@TotallyInformation](#):
>
> I've also written a cookbook entry containing all the correct information as was also mentioned.

Using an URL beginning with `mqtts://` instead of providing the _CA Certificate_ chain explicitly only works if the Let's Encrypt certificate chain is available on the system running Node-RED. I agree that this should be the preferred way. But if the server certificate cannot be verified using the system's built in trusted certificates, I think it is still better to do it by providing the CA Certificate chain explicitly instead of disabling certificate verification or not using SSL/TLS.

---

<div class="post-metadata">

**Author:** ![skleeschulte](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/skleeschulte/32/20362_2.png) [@skleeschulte](https://discourse.nodered.org/u/skleeschulte)\
**Post date:** [12 November 2019 16:44 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/25 "2019-11-12T16:44:45Z")

</div>

I just made another discovery: When using an URL that begins with `mqtts://` but not selecting _Enable secure (SSL/TLS) connection_, the certificate is not verified at all (neither the CA nor the hostname). To verify the certificate, this option and _Verify server certificate_ have to be selected.

If these options are not selected, `rejectUnauthorized` is set to `false` in the options object passed to [MQTT.js's](https://www.npmjs.com/package/mqtt).

See issue [node-red#2379](https://github.com/node-red/node-red/issues/2379).

---

<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:** [4 December 2019 21:15 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/26 "2019-12-04T21:15:20Z")

</div>

I've just updated the first post above to include locking the broker down to clients who are both TLS enabled and present the correct username/password.  
I've updated the Mosquitto config file and the new section starts at **Enforce Security**.

As always, please comment with improvements/suggestions.

---

<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:** [5 December 2019 10:36 UTC](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691/27 "2019-12-05T10:36:54Z")

</div>

Cool stuff Paul, thanks for that.

One thing that would probably be interesting for people not using a cloud-based client would be to be able to use self-signed certificates for the client - in case that client is on a laptop for example and therefore does not have a recognised domain and so cannot use a Let's Encrypt certificate.

In theory, you should be able to create your own CA file that contains the root trust for a self-signed certificate in addition to the standard Pi root trust.

Of course, it would require you to create a self-signed certificate "properly" which means creating your own root CA certificate as well as the client certificate based off it.

This thread seems to suggest a way to successfully combine the certs in a PEM file:

> <https://unix.stackexchange.com/questions/85404/appending-a-pem-to-another>

* * *

Since all of that is rather complex. I might suggest that people create a 3rd interface that allows user-id/password logins over mqtts for when client certificate authentication isn't feasible.

It shouldn't need to be said, but I will anyway 😀 - **NEVER** add id/password based logins (or indeed any other kind of login) without having _first_ restricted access to a TLS encrypted connection.

By keeping things on separate interfaces (each with its own TCP port), it is possible to restrict access using firewall rules as another level of security. You can also restrict access to specific parts of the topic structure in MQTT and restrict whether or not that interface can update topics or only read them.

Finally, by splitting the interface configurations into their own files, they would be easier to manage I think as well as potentially easier to turn on/off as needed.

[Previous page](https://discourse.nodered.org/t/mqtt-tls-encryption-example/17691.md?page=1)
