SECURE MOSQUITTO

Merve KILINC YILDIRIM
6 min readMar 5, 2024

--

Photo by https://dreamstudio.ai/

MQTT

MQTT (MQ Telemetry Transport) is a lightweight open messaging protocol. This protocol uses publish/subscribe (pub/sub) communication pattern for machine-to-machine communication.

In the pub/sub model, a client that sends data is called as the publisher and the client(s) that receive(s) data is called as the subscriber(s). These two parties are not connected to each other. The communication is handled by the broker. All the messages must go to the broker, then the broker sends the messages to the subscriber(s).

Mosquitto

Mosquitto is an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. It’s written in C. You can install binaries for various platforms. For details of installing process, you can refer to https://mosquitto.org/download/ page.

When you install the mosquitto to your local Windows environment. You will see a similar folder structure as you can see in the figure below:

After the installation of the binary package, the broker must have been started automatically. You can also check it from the Services App.

The installation also contains two example application: mosquitto_pub and mosquitto_sub.

For a quick test you can use mosquitto_sub to subscribe to a topic:

`mosquitto_sub -t ‘test/topic’ -v`

and mosquitto_pub to send a message:

`mosquitto_pub -t ‘test/topic’ -m “hello world”`

Eclipse Mosquitto Docker Image

Eclipse Mosquitto also provides an official docker image eclipse-mosquitto to the community. Without any installation you can just pull and use the image:

`docker pull eclipse-mosquitto`

In the image there are three directories to be used for configuration, persistent storage and logs.

mosquitto.conf is the configuration file for mosquitto. To use a custom configuration file, you can mount a local configuration file and update the configuration. You can use following configuration as mosquitto.conf. With this configuration settings:

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
  • Connection, subscription and message data will be written to the disk in mosquitto.db under the /mosquitto/data folder.
  • Log messages will be stored at mosquitto.log file which is located under /mosquitto/log folder.
  • The network port for the default listener is set to 1883.

Authentication in Mosquitto

By default MQTT broker is open to any clients. It means that clients can connect without providing any credentials. But in v2.0 and up, you can choose the authentication option before clients can connect. There are three choices for authentication: password files, authentication plugins, and unauthorized/anonymous access. It is possible to use a combination of all three choices. We will first take a look at how we can use password files as an authentication mechanism.

Username and Password Authentication

Mosquitto provides username/password authentication method. To use this option, you must first create a password file. To do this, first create a simple text file with username and password seperated by a colon.

`username:password`

This is not a good way to store the password in a clear text. Therefore you can use mosquitto_passwd application which is located in mosquitto folder to manage password files for the mosquitto MQTT broker.

With the following command, the password will be stored in an encrypted way as you can see in the image below:

To start using the password file, you should also configure your mosquitto.conf file as below:

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
allow_anonymous false
password_file /mosquitto/config/p2.txt

Be sure that you have copied the password file to the location where you have stated in the mosquitto.conf file. For the example, in this example, this location is “mosquitto/config/p2.txt”.

To connect to the message broker which uses the username/password authentication method, you must also do some configuration at the client application.

In our example, our client application is written in JavaScript language. We are using MQTT.js framework. For the details, you can checkout the link (https://github.com/mqttjs/MQTT.js). For the installation, you can use the command below:

npm install mqtt

You can look at the example applications to understand how to use the framework (https://github.com/mqttjs/MQTT.js#example).

To connect to a broker which is configured to use username/password authentication method, you need to do a similar configuration also in client application. Otherwise, the connection will be rejected. Here in the example, you need to set the username and password values in the options field.

const topic = 'test';
const mqttUrl = 'mqtt://mosquitto:1883'
const options = {
clientId: 'mqttjs_test',
protocolId: 'MQTT',
username: 'edge',
password: 'edge',
};
mqttClient = mqtt.connect(mqttUrl, options);
mqttClient.on('connect', (err) => {
if (err) {
console.log(err);
}

console.log('Connected to ' + mqttUrl);
mqttClient.subscribe([topic], () => {
console.log('Subscribed to ' + topic);
});
});

Using this authentication does not provide full security because username and password is sent in plain text. An attacker who monitor the traffic between the services can get this authentication information.

MQTT with TLS Security

As we see in the previous section, username and password authentication is not secure without encrypted connection between broker and the clients. To have this feature, client and server certificated must be generated. We use openssl to generate these certificates. We need the following files for a secure connection between MQTT Client and MQTT Broker.

- MQTT Client Required Files:

  • Client certificate file (client.txt),
  • Client private key (client_key.txt),
  • Certificate Authority certificate (ca.txt)

- MQTT Broker Required Files:

  • Server certificate file (server.txt),
  • Server private key (key.txt),
  • Certificate Authority certificate (ca.txt)

You can find the detailed commands to create these certificates in https://mosquitto.org/man/mosquitto-tls-7.html.

*Configuring MQTT Broker

First, the generated MQTT Broker certificate files should be copied under /mosquitto/certs folder. Then you should also configure your mosquitto.conf file as below:

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 8883
allow_anonymous false

cafile /mosquitto/certs/ca.txt
keyfile /mosquitto/certs/key.txt
certfile /mosquitto/certs/server.txt

require_certificate true
use_identity_as_username true

*Configuring MQTT Client

In MQTT Client side, you should update the connection url, port and client connection options. Here in the example, you need to set the certificate files in the options field.

const topic = 'test';
const mqttUrl = 'mqtts://mosquitto:8883';

const caFile = fs.readFileSync("ca.txt");
const keyFile = fs.readFileSync("client_key.txt");
const certFile = fs.readFileSync("client.txt");

const options = {
clientId: 'mqttjs_test',
protocolId: 'MQTT',
ca: caFile,
key: keyFile,
cert: certFile
};
mqttClient = mqtt.connect(mqttUrl, options);
mqttClient.on('connect', (err) => {
if (err) {
console.log(err);
}

console.log('Connected to ' + mqttUrl);
mqttClient.subscribe([topic], () => {
console.log('Subscribed to ' + topic);
});
});

MQTT with TLS is resistant to some kind of attacks (e.g. an attack that the attacker changes the configuration file of the message broker or has an alternative broker to send messages to the clients).

As you can see in the image, the network package between the broker and the client is monitored with Wireshark. If with TLS feature the message data is sent encrypted over the network.

Future Work

In MQTT with TLS solution, the broker is using certificate files and these files are stored in the /mosquitto/cert folder. Storing certificate files in a plain text format may cause a security leak in an application. A fake broker that has these certificate files can sent messages to the clients. To prevent this issue, you can embed your MQTT Broker certificates and build mosquitto from source code.

In my next blog, I would like to share this solution for you, stay tuned…:)

--

--