In this article we will see in detail how to add encryption to our MQTT communications.
If you have not yet seen how to install an MQTT server on a Raspberry Pi, I invite you to read this Article.
What is TLS/SSL and what is it for?
To begin with, TLS is a standard based on SSL, which appeared after the SSLv3 vulnerabilities were discovered. So when we talk about SSL, today we are generally referring to TLS.
The purpose of using SSL/TLS is to provide authentication, encryption, and integrity.
This means the following:
- Authentication: Whoever sends the message is who he says he is.
- encryption: Nobody on the path can read the message.
- Integrity: The message cannot be modified.
To achieve this, a digital signature (certificate) and public and private keys are used to encrypt and decrypt the message. Next we will see, step by step, how to add encryption to the communication with MQTT.
Steps to follow
- Create a public key and a private key for the certificate authority (CA).
- Create a certificate for the CA and sign it with the previously generated private key.
- Generate a public key and a private key for the MQTT broker.
- Create a certificate signing requirement for the keys from the previous step.
- Use the certificate from step 2 to sign the requirement from the previous step.
- Copy all the certificates to a directory of the MQTT broker.
- Copy the CA certificate to the client.
- Edit Mosquitto settings.
- Edit the client settings to use TLS and the CA certificate.
All this seems quite complicated, but let's go step by step. Let's first install ssl on our Raspberry Pi using the following command.
sudo apt-get install openssl
1.- Create the key pair for the CA
We execute the following command on the Raspberry. Note that we use the option sudo to run the command with permissions root.
sudo openssl genrsa -des3 -out ca.key 2048
Running the command will generate the certificate and prompt for a passphrase.
2.- Create a certificate for the CA and sign it
We execute the following command. When doing so, we will be asked for the key phrase that we entered in the previous point and then a series of data. The most important is the Common Name, which can be any name. In the case of websites, the domain name of the site (www.siteweb.com, website.com) is used. In our case we can choose any name, I have used the host name (raspberry). Remember that we must be able to resolve the name of our Raspberry.
We can also use the IP address if we do not wish to use a name.
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
3.- Create a key pair for the MQTT broker
In this step we will create the key pair for the broker, using the following command:
sudo openssl genrsa -out server.key 2048
4.- Create a certificate request
We will now create a certificate request (.csr) file. During creation, the same values will be requested as for the authority certificate (CA) and the same comments are valid. However, one of these values must be changed so that they are not exactly the same in both certificates, as this will cause the connection to not work. In my case, I have omitted to enter the "City" parameter.
sudo openssl req -new -out server.csr -key server.key
5.- Sign the certificate requirement
In this step we will use the CA certificate to sign the request we made in the previous step. This procedure will create the .crt file for the broker. The command is the following.
sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360
Again we will be asked for the key phrase that we generated at the beginning
6.- View created files
Using the command ls we see all the files we have created. The ca.key file will not be copied to the broker or the client, since it is only used to generate new certificates.
7.- Copy files to the broker
Now we copy the ca.crt, server.crt and server.key files into the Mosquitto configuration directories.
These directories are in /etc/mosquito. In ca_certificates we copy the file ca.crt and in certificates the server.crt and server.key files.
8.- Copy the certificates in the client
Now we copy the ca.crt file to our client. The exact location will obviously vary depending on where we have the client. In my case I will use the client developed by HiveMQ, which by the way have a lot of documentation on MQTT. In this page You can download the client for your operating system.
9.- Configure Mosquito
We must modify the Mosquitto configuration so that it uses SSL/TLS.
Mosquitto comes with an example configuration file, which is located in the /usr/share/doc/mosquitto/examples directory. This file can be named mosquitto.conf or mosquito.conf.example. In any case we copy it to the /etc/mosquitto/conf.d directory and rename it to mosquitto.conf if it has the .example suffix.
sudo cp /usr/share/doc/mosquitto/examples/mosquitto.conf.example /etc/mosquitto/conf.d/mosquitto.conf
Once copied we edit it with
sudo nano /etc/mosquitto/conf.d/mosquitto.conf
The first thing we do is set the port to 8883, which is the one used for encrypted communications.
Then we indicate where the certificate files are.
then we do
sudo service mosquitto restart
And we can verify that the broker was started by running the following command
10.- Test the connection with the broker
Finally, it is time to test the connection with the broker from the client that we are going to use. To do this we are going to use the hostname, so first we must edit our hosts file (if we are in Windows) or the one that corresponds according to our operating system.
If we now ping the raspberry host, our Raspberry should respond to us
Now we are going to open two command windows in Windows to run two clients, one publishing and one subscribing. The commands are the following. It is necessary to first run the subscription, so you can see the message we send when publishing.
mqtt-cli.exe sub -t test -h raspberry -p 8883 -s –cafile ca.crt -V 3 -v
mqtt-cli.exe pub -t test -m "hello" -h raspberry -p 8883 -s –cafile ca.crt -V 3 -v
Some Notes on Publish and Subscribe Options
|sub||option to subscribe|
|pub||option to publish|
|-t||topic to subscribe or post|
|-m||message to post|
|-V||version of MQTT, in this case version 3 should be used|
In this article we have seen how to add encryption to our communications with MQTT. There are several steps, but the procedure itself is not complicated. Tell me in the comments what you think of this article and if you have any questions.
See you in the next article ;).