Skip to content

Latest commit

 

History

History
198 lines (122 loc) · 12.7 KB

README.md

File metadata and controls

198 lines (122 loc) · 12.7 KB

IoT-Agent MQTT (VerneMQ)

Overview

An IoT-Agent is an adaptation service between physical devices and the dojot platform. The IoT-Agents are responsible for receiving messages from physical devices (directly or through a gateway) and sending them commands in order to configure. The dojot platform can have multiple IoT-Agents, each one of them being specialized in a specific protocol like in this case MQTT. It is also responsible for ensuring secure communication with devices.

The IoT-Agent MQTT extends VerneMQ with some features and services for dojot case. Basically, devices publishes MQTT messages in specific topics in VerneMQ. These messages are consumed by V2K-bridge service, which adapt them to the dojot's data model and forwards the modified messages to specific topics in Apache Kafka so that they can be consumed by other services. There is a reverse flow, where services publish messages to Apache Kafka in specific topics, these messages are consumed by the K2V-bridge service, which adapts the messages and forwards the modified messages to VerneMQ so that they can be consumed by the devices. These data flows are depicted in Fig. 1.

The currently accepted MQTT protocol versions are MQTT v3.1 and v3.1.1 respectively.

image

Fig. 1 - Data communication flows among the services that implement the IoT-Agent MQTT.

VerneMQ Broker with customizations for DOJOT

The VerneMQ Broker with customizations for DOJOT has some bash scripts were added to integrate VerneMQ with dojot's PKI. These scripts are responsible for providing an x509 certificate to the broker and periodically obtaining the CRL with revoked certificates.

For more details, please check the documentation at the service repository

V2K-bridge

The V2K-bridge service implements a bridge between VerneMQ broker and Kafka broker. Basically, it subscribes to some MQTT topics and forwards the messages to some Kafka topics following the dojot's topics rules. In order to scale the bridge service, shared MQTT subscriptions are used, which allows the instantiation of a group of consumers, i.e. a group of bridge instances, when necessary. The communication between the bridge and the VerneMQ is secured with mutual TLS. Soon, communication with Kafka will also use mutual TLS.

For more see here

K2V-bridge

The K2V-bridge service implements a bridge between a Kafka broker and a VerneMQ broker. It receives messages from some Kafka dojot's topics and publishes the messages to some MQTT topics. The communication between the bridge and the VerneMQ is secured with mutual TLS. Soon, the communication with Kafka will also use mutual TLS.

For more see here

ACL (Access-Control List)

An ACL (Access-Control List) based authorization is provided to manage permissions so that a device only publish and subscribe to its own topics, which are:

  • To publish: tenant:device_id/attrs
  • To subscribe: tenant:device_id/config

Where tenant is a context identifier into dojot and device_id is a identifier for the device in the corresponding context. By joining both identifiers (tenant:device_id), you have a unique identifier for the device into dojot.

See more about ACL Plugin for VerneMQ.

Security

We use TLS mutual authentication to provide secure communication between devices and broker VerneMQ through MQTT. Transport Layer Security (TLS) is a cryptographic protocol designed to provide communications security over a computer network.

In order for the device to communicate with the dojot platform, the platform must issue an x.509 certificate that must be installed on the device. The certificate represents the identity of the device to the platform, so the certificate is used to authenticate the device to the platform, thus avoiding the need to set up a username and password on the device. Security is applied at the TLS protocol level, so in addition to guaranteeing the identity of the device, it also guarantees the privacy and integrity of data traveling between the device and the platform.

The TLS connection has a maximum life time, see more about Disconnect Plugin for VerneMQ. The TLS connection also has a configurable timeout, which is a VerneMQ configuration.

To establish mutual TLS, in each device there must be a pair of asymmetric keys (generated by the device owner) and their respective x.509 certificate (issued by the dojot platform). However, this alone is not enough, for security to be effective, it is necessary that the root certificate (also known as CA certificate) of the dojot platform is also installed on the device and configured as the trust anchor for the communication channel with the dojot platform.

In summary, the following files must be installed on the device:

  • Device private key;
  • Device public certificate;
  • dojot platform root certificate.

The dojot platform issues certificates for devices using the x509-identity-mgmt component. Through its REST API it is possible to request the signing of a certificate for a given device. Check the documentation for that component for details on how to proceed so that your device receives a valid certificate and is able to communicate securely with the dojot platform.

In a nutshell, you just need to create a certificate signing request (CSR), having the device ID (previously generated by the platform during its registration) as a value for the CN field (also known as Common Name field) and submit the CSR within a JSON payload for the x509-identity-mgmt component API. It is necessary that the user responsible for this request has permission to do so.

Once the certificate is generated, it will be linked to the device ID informed in the CSR, together with the identification of the tenant that the platform will automatically include in the certificate.

Note: The certificate issued by the dojot platform has a validity period, so it is important to be aware of this period. Once this period has passed, the device will no longer be able to communicate with the platform, requiring the issuance of a new certificate so that the device can again establish a TLS communication with the platform.

How to connect a device with the IoT-Agent-MQTT with mutual TLS

Prerequisites

  • Creates a device on the dojot platform and gets its identifier (ID);
  • Has a user account with permission to issue certificates for devices.

To simplify the task of generating certificates, we will use a scripting tool created to connect to the platform and generate the necessary files so that the device can establish communication over TLS with dojot.
The scripting tool is called CertReq and it abstracts the OpenSSL commands required to generate the key pair and CSR, as well as obtain the root certificate and the device certificate.
It is important to note that this tool is nothing more than a bash script that must be run on a GNU/Linux operating system. You can open the script with a text editor and study it to access the details of the commands it executes. You can even use it to develop your own script based on the operating system of your choice.

With the script in hand (and after reading its documentation), execute it as follows:

./certreq.sh \
    -h "${DOJOT_HOST}" \
    -p "${DOJOT_PORT}" \
    -i "${DEVICE_ID}" \
    -u "${USERNAME}" \
    -s "${PASSWORD}"

In the example above, we use shell variables to inform the host (or IP) and the port where the dojot platform can be accessed, in addition to the username and password to be used to communicate with the certificate issuing API. You can enter a device ID or several, as long as they are separated by commas.

Note: You do not need to use variables to execute the script, just replace the variables with fixed values according to your deployment.

After executing the script, if successful, two directories will be generated next to the script, one of them will have the dojot root certificate (also known as CA certificate) and the other will have the device's private key and public certificate. It is important that the private key remains securely stored, because if it is stolen, all security will be compromised. We recommend that you seek to learn more about good practices regarding the handling of private keys.

Again, be sure to read the script documentation for details on its execution.

With the files generated by the script mentioned above, we can establish secure communication with the platform. Let's see how to do this below...

Simulating a device with mosquitto

In the examples below we will use the mosquitto client MQTT to simulate the device.

We will use two commands called mosquitto_pub and mosquitto_sub, the first will be used to publish data on the dojot platform and the second will be used to subscribe to the platform to receive data for the device that we will be simulating.

Note 1: The host and port of the dojot platform may vary according to its implementation, for this example we will use arbitrary values.

Note 2: The tenant is admin and device ID is a1998e for these examples. You must change them for your case.

The parameters that will be passed to these two commands are listed below:

  • -h: Specify the host to connect to. Defaults to localhost.
    In the case of this example: myhost.

  • -p: Connect to the port specified. If not given, the default of 1883 for plain MqTT or 8883 for MqTT over TLS will be used.
    In the case of this example: 30311.

  • -t: The MqTT topic on which to publish the message.
    In the case of this example: admin:a1998e/attrs to publish and admin:a1998e/config to subscription.

  • -m: Send a single message from the command line.

  • -u: Provide a username:device_id to be used for authenticating with the broker.
    In the case of this example: admin:a1998e

  • --cert: Defines the path to the certificate of the device we are simulating.
    In the case of this example: ./cert_a1998e/cert.pem

  • --key: Defines the path to the private key of the device we are simulating.
    In the case of this example: ./cert_a1998e/private.key

  • --cafile: Defines the path to the root certificate of the dojot platform. Used to enable TLS communication.
    In the case of this example: ./ca/ca.pem

With security

Use TLS to communicate with VerneMQ

The three files are require: cert.pem, private.key and ca.pem (remember, they were generated here).

See the examples:

Example on how to publish
mosquitto_pub \
  -h 'myhost' \
  -p 8883 \
  -t 'admin:a1998e/attrs' \
  -m '{"attr_example": 10 }' \
  --cert './cert_a1998e/cert.pem' \
  --key './cert_a1998e/private.key' \
  --cafile './ca/ca.pem'

Note: In this case, the message is a publication with an attribute, this attribute has the label attr_example and a new value 10 coming from the device with id a1998e with tenant admin.

Example on how to subscribe
mosquitto_sub \
  -h 'myhost' \
  -p 8883 \
  -t 'admin:a1998e/config' \
  --cert './cert_a1998e/cert.pem' \
  --key './cert_a1998e/private.key' \
  --cafile './ca/ca.pem'

Without security

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

Prerequisites

Create a device in Dojot and get a tenant and a device ID.

Example on how to publish
 mosquitto_pub \
  -h 'myhost' \
  -p 1883 \
  -t 'admin:a1998e/attrs' \
  -m '{"attr_example": 10 }' \
  -u 'admin:a1998e'

Note: In this case, the message is a publication on an attribute with the label attr_example and a new value 10 in device a1998e with tenant admin.

Example on how to subscribe
 mosquitto_sub \
  -h 'myhost' \
  -p 1883 \
  -t 'admin:a1998e/config' \
  -u 'admin:a1998e'

Load test

To perform load tests using the MQTT protocol, dojot provides a ready-made tool for this. click here for more details about it.