In this previous post I used Certbot & Letsencrypt to secure a node-RED server, and wanted to use the same Letsencrypt certificates to secure MQTT communication with a remote server.
I also wanted to ensure that all local network devices could continue to communicate with the server without encryption.
To be clear, the mosquitto 'Broker' is to be installed & running on my Raspberry Pi, and the remote 'Client' is another node-RED instance running in a Oracle VM.
Secure MQTT normally uses port 8883, so using port-forwarding, open up port 8883 on your Raspberry Pi (broker). It is not necessary to open port 8883 on the client instance.
Install mosquitto on the broker;
sudo apt install -y mosquitto mosquitto-clients
We must then tell mosquitto to listen to port 8883 and use TLS to handshake with the client. This is done by creating a mosquitto configuration file;
sudo nano /etc/mosquitto/conf.d/TLSconfig.conf and paste into it;
# Local MQTT listener 1883 # Secure MQTT listener 8883 ## This is standard and should always be this cafile /etc/ssl/certs/DST_Root_CA_X3.pem ## These are from your installation of LE certfile /home/pi/.node-red/certs/fullchain.pem keyfile /home/pi/.node-red/certs/privkey.pem ## Forces use of modern version of TLS to avoid security issues tls_version tlsv1.2 ## Force all clients in this listener to provide a valid certificate, change the node config to allow this from NR #require_certificate true
Save the file, then restart mosquitto -
sudo systemctl restart mosquitto
Note the paths to the certificates. These can be changed if your certificates are at a different location, but use the full path to them.
Because the Mosquitto configuration (above) is not enforcing that clients must present a valid certificate, you will be able to connect to the broker without any certification whatsover, but by changing the Mosquitto broker configuration to;
## Force all clients in this listener to provide a valid certificate, change the node config to allow this from NR require_certificate true
..and restarting Mosquitto, that rule will now be enforced, and any MQTT client must present a valid certificate before the broker will allow it to connect.
To prepare a node-RED MQTT node to use a SSL/TLS connection, the client must also have valid certificates of it's own, and add them to the MQTT node like this;
Then add a new tls-config;
That is all the configuration that you need to do in the MQTT node, apart from setting the topic, QoS & Retain options. It should now connect to your broker.
The default mosquitto MQTT listener is port 1883, which allows local network connection to be made without certification, yet because you haven't opened up port 1883 (port forwarding) in the brokers router, all external messages on port 1883 will not get through the firewall, only TLS encrypted 8883 traffic.