4. Using MQTT with security (TLS)

Note

  • Audience: users

  • Level: intermediate

  • Reading time: 15 m

This document describes how to configure the dojot and publish/subscribe using MQTT over TLS (MQTTS) when using the microservice Broker MQTT IotAgent-VerneMQ or Legacy Broker MQTT IotAgent-Mosca.

4.1. Components

4.1.1. X.509 Identity Management

The purpose of this component is to provide x.509 identification for final dojot entities, that is, IoT devices that communicate with the dojot IoT platform. See more about in X.509 Identity Management.

4.1.1.1. What is a certificate?

A certificate contains the public key for an entity (a user, device, website), along with information about this entity, about the CA which signs the certificate, the allowed certificate usage and a checksum. When a entity wants a certificate to be signed, the entity should create a CSR file and send it to the desired CA. The CSR file is an ‘intention of certification’. The file contains the information required from the entity and some information about the certificate use, hostnames and IPs where the certificate will reside, alternative names for the entity, etc.

4.1.2. MQTT Brokers

4.1.2.1. IotAgent VerneMQ (Default)

The IotAgent VerneMQ extends VerneMQ with some features and services for dojot case, see more in IotAgent-VerneMQ. This is the default Broker MQTT in dojot deployments.

4.1.2.2. IotAgent Mosca (Legacy)

The IotAgent Mosca uses Mosca that is a node.js mqtt broker, see more about this service in IotAgent-Mosca. This is the not default Broker MQTT in dojot deployments.

4.1.2.3. About using IotAgent VerneMQ or IotAgent Mosca

You shouldn’t use the two brokers together to avoid port conflicts. Use either VerneMQ (default) or Mosca (legacy). By default, our deployments are using VerneMQ.

It is necessary to configure the domain in which the broker will be accessible:

For the Ansible deployment:

  • It is necessary to configure the variable dojot_domain_name before starting with the domain or the ip that will be used to communicate with MQTT via TLS.

For the Docker-compose deployment:

  • It is necessary to configure the variable DOJOT_DOMAIN_NAME in the .env file. before starting with the domain or the ip that will be used to communicate with MQTT via TLS.

In addition, you can choose between IotAgent VerneMQ or IotAgent Mosca when configuring the Ansible deployment (i.e. Kubernetes). In Docker-compose, you need to uncomment and comment the services in the docker-compose.yml, there’s a commented explanation about that in this file.

Check the Installation Guide for more info.

All the certificates will be automatically created, so there is no need to manually configure the brokers’ ones.

4.2. How to connect a device with the IotAgent VerneMQ or IotAgent Mosca with mutual TLS

Attention

First of all, you will need a running dojot’s environment. Then you should create a new device (or use an existing one if you prefer) and retrieve its ID.

4.2.1. Retrieving certificate for a device

For a device to connect using MQTT over TLS (MQTTS), it must possess:

  • A key pair (.key file);

  • A certificate signed by a Certificate Authority (CA) trusted by dojot (.crt file);

  • The certificate of this CA (.crt file);

The objective when retrieving the certificate for a device is to obtain these three files: the device’s certificate, the device’s key pair and the CA certificate.

There are two tools to facilitate obtaining certificates from the dojot platform:

In addition, you can use OpenSSL to create certificates and sign using the API - x509-identity-mgmt, see more at X.509 Identity Management.

4.2.1.1. A brief explanation of how to use CertReq

As prerequisites this uses git, OpenSSL, curl and jq .

On Debian-based Linux distributions, you can install these prerequisites by running:

sudo apt install git curl jq openssl

Download CertReq on your machine directly from dojot repository and switch to the corresponding version of your dojot environment:

git clone https://github.com/dojot/dojot.git
cd dojot
git checkout v0.7.1

Enter in certreq directory:

cd tools/certreq

Finally, you can run the script to generate certificates and keys as follows:

./bin/certreq.sh \
   -h http://localhost \
   -p 8000 \
   -i 'a1998e' \
   -u 'admin' \
   -s 'admin'

Given a username admin and password admin, this command will request a certificate with device ID (identifier) a1998e for the dojot platform host localhost on port 8000.

Note

For more details about the CertReq parameters, check the CertReq - Parameters document. Other useful resources for this matter are the How to connect a device with the IoTAgent-VerneMQ with mutual TLS tutorial and the CertReq documentation.

And in the end this tool will create the directories ./ca and ./cert_{DEVICE_ID} to store the certificates and public/private keys.

4.2.2. Simulating a device with mosquitto

We are going to use mosquitto to simulate a device; it will publish and subscribe in dojot via MQTT.

Before continuing, install mosquitto_pub and mosquitto_sub from the mosquitto-clients package on Debian-based Linux distributions:

Attention

Some Linux distributions, Debian-based Linux distributions in particular, have two packages for mosquitto, one containing tools to access it (i.e. mosquitto_pub and mosquitto_sub for publishing messages and subscribing to topics) and another one containing the MQTT broker too. In this tutorial, only the tools from package mosquitto-clients on Debian-based Linux distributions are going to be used. Please check if another MQTT broker is not running before starting dojot (by running commands like ps aux | grep mosquitto) to avoid port conflicts.

On Debian-based Linux distributions you can install mosquitto-clients running:

sudo apt-get install mosquitto-clients

4.2.2.1. IotAgent VerneMQ (Default)

To publish and subscribe using the appropriate certificates, you must have IotAgent VerneMQ Broker, V2K Bridge, K2V Bridge and the X.509 Identity Management running, see more in IotAgent-VerneMQ.

Simulating a device publishing with mosquitto

mosquitto_pub  -h localhost -p 8883 -t <tenant>:<deviceId>/attrs  -m '{"attr_example": 10}' --cert <device .crt file> --key <device .key file> --cafile <ca .crt file>

An example of publication with the certificates and keys generated in the previous topic with CertReq tool.

mosquitto_pub \
-h localhost \
-p 8883 \
-t admin:a1998e/attrs \
-m '{"attr_example": 10 }' \
--cert './cert_a1998e/cert.pem' \
--key './cert_a1998e/private.key' \
--cafile './ca/ca.pem'

Simulating a device subscribing with mosquitto

mosquitto_sub  -h localhost -p 8883 -t <tenant>:<deviceId>/config  --cert <device .crt file> --key <device .key file> --cafile <ca .crt file>

For more details about simulate a device see in Simulating a device with mosquitto and more about simulate a device with security in Simulating a device with mosquitto with security.

4.2.2.2. IotAgent Mosca (Legacy)

To publish and subscribe using the appropriated certificates, you must need to be with the IotAgent Mosca Broker and the X.509 Identity Management running, see more in IotAgent-Mosca. In addition, you need to use a different topic from VerneMQ and pass the identifier to publish and subscribe, as follows:

How to publish:

mosquitto_pub  -h localhost -p 8883 -t /<tenant>/<deviceId>/attrs -i <tenant>:<deviceId> -m '{"attr_example": 10}' --cert <device .crt file> --key <device .key file> --cafile <ca .crt file>

How to subscribe:

mosquitto_sub  -h localhost -p 8883 -t /<tenant>/<deviceId>/config -i <tenant>:<deviceId> --cert <device .crt file> --key <device .key file> --cafile <ca .crt file>

Note

In these examples, the published message has the attribute attrs_example. You need to change its name to comply to your device’s attribute.

4.2.3. Unsecured mode MQTT (without TLS)

Attention

MQTT without security is not recommended, use this for testing only.

In ansible-dojot (kubernetes deployment) you can disable the unsecured mode by changing the dojot_insecure_mqtt variable to false, this is valid in both Brokers. Check the Installation Guide for more info.

4.2.3.1. IotAgent VerneMQ (Default)

You can disable the unsecured mode if you make port 1883 unavailable for external access.

For more details about simulating a device without security, check the Simulating a device with mosquitto without security tutorial.

4.2.3.2. IotAgent Mosca (Legacy)

You can disable the unsecured mode in Mosca by changing the ALLOW_UNSECURED_MODE environment variable to 'false' or by removing external access to the port 1883. See more in IotAgent-Mosca.

4.3. How to read a certificate

A certificate file can be in two formats: PEM (base64 text) or DER (binary). OpenSSL offers tools to read such formats:

Reading certificate:

openssl x509 -noout -text -in certFile.crt

Getting certificate fingerprint:

openssl x509 -in certFile.crt -noout -fingerprint -sha256