In this tutorial we will configure the mosquitto MQTT broker to use TLS security.
We will be using openssl to create our own Certificate authority (CA), Server keys and certificates.
We will also test the broker by using the Paho Python client to connect to the broker using a SSL connection.
You should have a basic understanding of PKI, certificates and keys before proceeding. See SSL and SSL Certificates Explained
The steps covered here will create an encrypted connection between the MQTT broker and the MQTT client just like the one between a web browser client and a Web Server.
In this case we only need a trusted server certificate on the Client.
We do not need to create client certificates and keys but this is covered in Creating and Using Client Certificates with MQTT and Mosquitto
Important Note: Many other tutorial on the web also configure username and password authentication at the same time. I don’t recommend you do this as errors could be cause by either SSL or authentication. Only do one thing at one time when testing.
- A CA (certificate authority) certificate of the CA that has signed the server certificate on the Mosquitto Broker.
- CA certificate of the CA that has signed the server certificate on the Mosquitto Broker.
- CA certificated server certificate.
- Server Private key for decryption.
Creating and Installing Broker Certificates and keys
To create these certificates and keys we use the openssl software.
For windows you will find the install download files here.
On Linux you can install openssl using :
sudo apt-get install openssl
Although the commands to create the various certificates and keys are given in this Mosquitto manual page. Here is a quick snapshot:
There is a problem with the page because openssl no longer comes with a CA certificate, and so you will need to create your own self signed CA certificate.
You should also note that when you generate keys you shouldn’t use encryption (the -ds3 switch) for the server certificate as this creates a password protected key which the broker can’t decode.
Note the certificates and keys created can be used on the Mosquitto broker/server, and also on a web server, which is why you see the term server used in the Mosquitto manual and not broker.
Overview of Steps
- Create a CA key pair
- Create CA certificate and use the CA key from step 1 to sign it.
- Create a broker key pair don’t password protect.
- Create a broker certificate request using key from step 3
- Use the CA certificate to sign the broker certificate request from step 4.
- Now we should have a CA key file,a CA certificate file, a broker key file, and a broker certificate file.
- Place all files in a directory on the broker e.g. certs
- Copy the CA certificate file to the client.
- Edit the Mosquitto conf file to use the files -details below
- Edit the client script to use TLS and the CA certificate. -details below
Note this as done on a windows XP machine.
The same commands and procedures apply to linux but the folder locations will be different and you may need to change permissions, as well as using the sudo command.
First create a key pair for the CA
Command is: openssl genrsa -des3 -out ca.key 2048
Note: it is OK to create a password protected key for the CA.
Now Create a certificate for the CA using the CA key that we created in step 1
Command is: openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
Now we create a server key pair that will be used by the broker
Command is: openssl genrsa -out server.key 2048
Now we create a certificate request .csr. When filling out the form the common name is important and is usually the domain name of the server.
Because I’m using Windows on a local network I used the Windows name for the computer that is running the Mosquitto broker which is ws4.
You could use the IP address or Full domain name. You must use the same name when configuring the client connection.
Command is: openssl req -new -out server.csr -key server.key
Note: We don’t send this to the CA as we are the CA
Now we use the CA key to verify and sign the server certificate. This creates the server.crt file
Important Note Jan2023– Due to problems with browsers requiring a SAN the command is now:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360 -extfile filename
Note: scripts have also been updated see note at end
The above steps created various files. This is what the directory looks like now:
Note: We don’t need to copy the CA.key file. This file is used when creating new server or client certificates.
Copy the files ca.crt, serever.crt and server.key to a folder under the mosquitto folder. I have used a folder called certs.
on Linux you should already have a ca_certificates folder under /etc/mosquitto/ and also a certs folder.
Use the ca_certificates folder for the CA certificate and the certs folder for the server certificate and key.
Copy the CA certificate file ca.crt to the client.
Edit the mosquitto.conf file as shown:
- I’ve used the default listener but you could also add an extra listener.
- The ca path is not used as I told it the file location instead.
- On my Linux install the entire TLS section of the mosquitto.conf file was missing I had to copy it from my windows install and then edit it. Here is the mosquitto.conf file documentation
Step 10 -Client Configuration:
Edit the client to tell it to use TLS and give it the path of the CA certificate file that you copied over.
I’m using the python client and the client method is tls_set(). Although there are several parameters that you can pass the only one you must give is the CA file as shown below.
The python client will default to TLSv1.
You shouldn’t need to change it as the mosquitto broker also defaults to TLSv1.( before v 1.6)
However to change it to TLSv1.2 use:
The pub and subscribe scripts that come with the mosquitto broker default to TLSv1.2.
Problems I Encountered and Notes
While creating and working through these procedures i encountered the following problems
- Error when connecting due to the common name on the server certificate not matching.
- I password protected the server key and the broker couldn’t read it. I found this command which will remove the passphrase from the key – openssl rsa -in server.key -out server-nopass.key.
- Not using the correct name for the broker. I used the IP address and not the name that I entered into the certificate.You can use the tls_insecure_set(True) option to override name checking as a temporary measure.
- Authentication errors as I had previously configured my broker to require passwords. Therefore try to start with a clean conf file and beware that the errors you are getting may not be SSL related.
Self Signed Certificates
Currently the Paho python client require a CA certificate file and so it is not possible to use a self signed certificate. I came across a couple github threads relating to this but no real solution.
I have had reports that the certificates do not work in a browser. see here. I’m not sure if this only applies to self signed certificates or also CA signed ones. The tutorial uses CA signed certificates and so do the scripts.
I have modified the scripts to require an external file. The DNS entries should match the common name you are using which is the DNS name or IP of the mosquitto broker.
The scripts have an example file included and you will need to edit it.
What is a SAN?
SAN (Subject Alternative Name) is an extension to the X.509 certificate standard that allows multiple domain names to be associated with a single SSL (Secure Sockets Layer) certificate. This allows a single certificate to be used for multiple website domains or subdomains.
If all goes well you should be able to publish and subscribe to topics as normal, but now the connection between client and broker is encrypted.
Unfortunately there is no easy way of seeing this.
This is the Python script I used:
To test using the mosquitto_pub client use:
This shows that the common name you enter on the certificate must match the name used by the client when it connects. If not it doesn’t work.
Video -Configuring SSL on the Mosquitto MQTT Broker
Starting with v1.6 I the support for tlsv1.1 was removed . You need to add the line
to your configuration file and when testing set the version e.g.
C:\mos>mosquitto_pub -h 192.168.1.41 -p 8883 -t test -m test --cafile c:/python34/steve/mqtt-demos/ca.crt --tls-version tlsv1.2
You can see the change log here -https://mosquitto.org/ChangeLog.txt
Reported Problems and Solutions
- Wrong/Old openssl version reported on Centos 7. Update openssl fixed it.
- Problems when using capath on mosquitto_pub tool. Use cafile instead -mosquitto_pub -h host.name -u username -P password -t test/topic -p 8883 –cafile ~/keys/ca.crt -m message
- Problems with Server name on certificate. Use the tls_insecure_set(True) on the python client or the –insecure switch in the mosquitto_pub tool.
Useful OpenSSL Commands
Verify that a server certificate is signed by a particular CA. Use the Ca.crt file and the server.crt file.
openssl verify -CAfile ca.crt server.crt
it should return
To save you typing I’ve created two Linux shell scripts that run the commands and create server and client certificates and keys as in this tutorial and the client certificate tutorial.
Mosquitto Configuration Tutorials
- SSL and SSL Certificates Explained For Beginners
- Installing The Mosquitto broker on Windows and Linux
- Quick Guide to The Mosquitto.conf File With Examples
- Configuring and Testing MQTT Topic Restrictions
- Mosquitto username and Password Authentication Configuration Guide
- Configuring Logging on Mosquitto
- Configure Mosquitto Bridge With SSL Encryption- Examples
- MQTT Security Mechanisms
Other Related Articles and Resources:
- MQTT for Beginners
- MQTT and Mosquitto WebSockets Working Notes
- Beginners guide to PKI
- Hive MQTT security essentials TLS