-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New entry: Connect to an MQTT broker with TLS encryption #67
base: master
Are you sure you want to change the base?
Changes from all commits
277b37a
2b3bfcb
cc36a4e
868ea84
b8a04f1
62695b3
071e65c
24aa202
25f5c5d
e73019e
7db38b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
--- | ||
layout: default | ||
title: Connect to an MQTT broker with TLS encryption | ||
slug: | ||
- label: mqtt | ||
url: /#mqtt | ||
- secure connect | ||
--- | ||
|
||
### Problem | ||
|
||
You want to have an encrypted connection to your Mosquitto MQTT broker. | ||
|
||
### Solution | ||
|
||
Create a valid set of certificates and keys for the broker to use. | ||
|
||
Change the configuration of the broker to start a TLS encrypted port (`mqtts`) using the above. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe "... to accept encrypted connections..." instead of "...to start a TLS encrypted port..."? |
||
|
||
Alter the <code class="node">MQTT Config</code> node, changing the "Server" name to start with `mqtts://`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding mqtts:// to the server name is redundant when ticking the "Enable secure connection" checkbox... Maybe just "Configure the MQTT broker node to establish a secure connection."? |
||
|
||
#### Example | ||
|
||
**Valid Certificate Creation** | ||
|
||
THe easiest approach for this is to use [Let's Encrypt](https://letsencrypt.org/getting-started/). This is beyond the scope of this article but there are plenty of examples and tutorials available on the Internet. For this to work successfully, you also need to be able to use a registered domain name on your internal network because you cannot use Let's Encrypt with IP addresses or non-public domain names. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would argue that it depends very much on the server's configuration whether Let's Encrypt is easy to use. It might be considerably easier to generate self-signed certificates than using Let's Encrypt. Leave out "...on your internal network..."? THe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The internal network part is important. LE doesn't validate if you don't use a domain name for obvious reasons. |
||
|
||
Alternatively, you can create a self-signed set of certificates. Again, this is beyond the scope of the article. However, you may need to create a trusted root certificate and provide its public cert instead of the one that Debian provides that is listed in the configuration below. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only "configuration below" that includes a CA cert is the Mosquitto configuration, which does not need a CA cert at all. Instead, when using self-signed certificates, the CA cert needs to be configured in Node-RED, but this aspect is missing in the article. |
||
|
||
**Mosquitto configuration** | ||
|
||
This assumes that you are using Let's Encrypt or other certificates signed by a root CA already trusted by the Debian operating system. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whether the CA is trusted by Debian is not relevant for the Mosquitto configuration. |
||
|
||
Note the entries in `<...>` which need to be replaced with your own folders and files. | ||
|
||
For Linux installations, this goes into a file of any name of the form `*.conf` in the folder `/etc/mosquitto/conf.d/`. So you have to edit it with root privalages (e.g. using `sudo`). On other platforms, please refer to the [Mosquitto configuration documentation](https://mosquitto.org/man/mosquitto-8.html). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still platform/setup specific. Other Linux distributions, other ways of installing Mosquitto, future versions of Debian all might use different paths. The official Docker container uses Linux and uses other paths. I'd suggest to narrow it down to a specific installation on a specific OS, or leave it out completely and point to the Mosquitto docs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about "Debian Linux versions..." ? |
||
|
||
{{ page.lcb }}% raw %} | ||
~~~text | ||
# Default Listener: 1883 | ||
port 1883 | ||
# Bind the default listener to localhost only if you want to force external connections to be TLS only | ||
#bind_address localhost | ||
|
||
# Secure listener | ||
listener 8883 | ||
# TLS | ||
## This is standard and should always be this when using Let's Encrypt | ||
## If using a self-signed certificate, this needs to be your custom Root CA public certificate | ||
cafile /etc/ssl/certs/DST_Root_CA_X3.pem | ||
Comment on lines
+48
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which cafile is configured here is only relevant for certificate based user authentication, it is not relevant for encrypted connections. The cafile entry can be left out completely. The only requirement is to have either a cafile-entry or a capath-entry in the listener configuration to enable SSL/TLS mode. This can be something like |
||
## These are from your installation of LE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...or the self-signed certs |
||
certfile /<path-to-LE-cert-files>/<fullchain>.cer | ||
keyfile /<path-to-LE-cert-files>/<private-key-name>.key | ||
## Forces use of modern version of TLS to avoid security issues | ||
tls_version tlsv1.2 | ||
|
||
## Forces ALL CLIENTs using this port to provide a valid certificate - change the node config to allow this from NR | ||
#require_certificate true | ||
TotallyInformation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
~~~ | ||
{: .shell} | ||
{{ page.lcb }}% endraw %} | ||
|
||
After making these changes, you have to restart the mosquitto broker. On Linux, you can usr the command: | ||
|
||
~~~text | ||
[~]$ sudo systemctl restart mosquitto | ||
TotallyInformation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
~~~ | ||
{: .shell} | ||
|
||
Other platforms, including Docker-based installations may be different. | ||
|
||
**<code class="node">MQTT Config</code> node configuration** | ||
|
||
![](/images/mqtt/tls-connect-1.png) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This image shows a configuration where the certificate is not validated. |
||
|
||
Notes | ||
|
||
* You need to use the IP name rather than IP address in the server name if using Let's Encrypt (otherwise the certificate isn't valid). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IP name -> domain name? |
||
* You need to change the server name to a url, prefixed with `mqtts://`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, this is not necessary when enabling the "Enable secure connection" flag, which needs to be enabled to have the server certificate verified. |
||
|
||
This disables the port field, I change that first to `8883` to remind me what the correct port will be. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another advantage of ticking the "Enable secure connection" checkbox: Because there is no need to add the protocol to the Server field, the port field stays enabled. |
||
|
||
If you need to change the port to something other than the default, include it on the URL: | ||
|
||
``` | ||
mqtts://broker.domain.tld:9999 | ||
``` | ||
|
||
* You **do not** need to set the "Enable secure connection" flag unless you want to authenticate the Node-RED client to the broker (if you set the require_certificate to true for example). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this line is still misleading, or at least prominently advertising a configuration where the server certificate is not validated. In the context of this article about encrypted connections, the note that the "Enable secure connection" flag is only relevant for authenticating clients looks even wrong to me, in two regards: |
||
* If you do not set the "Enable secure connection" flag however, the node will not validate the certificate chain. | ||
|
||
### Discussion | ||
|
||
Mosquitto allows you to create multiple ports for connectivity. This lets you use websockets and TLS encrypted connections in addition to the default connection. | ||
|
||
The folder `/etc/mosquitto/conf.d/` can contain any number of config files which will all be applied so that you can split your custom changes into separate files if you like. | ||
|
||
Just remember that once you use a custom file to set ports, the default port (1883) is no longer active so you have to specify that as well if you still want it to be active. The standard port for MQTT over TLS (MQTTS) is 8883. You can, however, use other ports if they are not in use. Make sure you use a port number greater than 1024 otherwise the broker must be run with root privalages which is not recommended for security reasons. | ||
TotallyInformation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
You can check which ports the broker has opened with the command: | ||
|
||
~~~text | ||
[~]$ sudo netstat -lptu | grep mosquitto | ||
tcp 0 0 0.0.0.0:8883 0.0.0.0:* LISTEN 17697/mosquitto | ||
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 17697/mosquitto | ||
tcp6 0 0 [::]:8883 [::]:* LISTEN 17697/mosquitto | ||
tcp6 0 0 [::]:1883 [::]:* LISTEN 17697/mosquitto | ||
~~~ | ||
{: .shell} | ||
|
||
You can test whether the server device is allowing connections on a port by using telnet from another device. | ||
|
||
~~~text | ||
[~]$ telnet <ip-name> 8883 | ||
~~~ | ||
{: .shell} | ||
|
||
If the connection opens, then the target device is accepting connections on that port. | ||
|
||
Note that the operating system automatically opens the required ports through the devices firewall. | ||
|
||
If you want to monitor what the broker is doing, including seeing which clients connect to which ports, use the following command: | ||
|
||
~~~text | ||
[~]$ sudo tail /var/log/mosquitto/mosquitto.log -f | ||
TotallyInformation marked this conversation as resolved.
Show resolved
Hide resolved
|
||
~~~ | ||
{: .shell} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this title in the Node-RED cookbook, I would expect more information about how to configure the mqtt-broker node for secure connections (e.g. clarification of the meanings of the fields in the TLS configuration dialog, usage of self signed certificates including validation) and not necessarily information about configuring the MQTT broker.
Maybe instead: "Set up the Mosquitto MQTT broker to accept encrypted connections and connect to it from Node-RED"? Or add more information about the configuration options in Node-RED?