IOT with Secure Mqtt in ESP32-c-mini4

Rohit
6 min readDec 20, 2022

--

This project demonstrate, how to secure MQTT connection with ssl/tsl self-signed certificates between broker, publisher and subscriber.

Also controlled the LED of microcontroller esp32 from Google Assistance.

Source Code avaialble at Git hub: https://github.com/rohitCodeRed/iot-with-secure-mqtt

Project Video link

https://www.youtube.com/watch?v=6La3IV40SMY

First part of video show the real time sensor data on graph at URL: http://localhost:4000 , It show the temperature and humidity data at 5 second interval and second graph show vibration sensor data in real time.

  • Data are updated with the help of Web socket from Html page to NodeJs server and sensor data subscribed by NodeJs server which published on MQTT broker by sensors used in microcontroller ESP32.

Sensors used

  1. Tempearture and humidity sensor(DHT11) https://components101.com/sensors/dht11-temperature-sensor
  2. Normally Open vibration sensor(SW-18015P) https://www.techtonics.in/vibration-sensor-module-normally-opened-type#:~:text=Vibration%20Sensor%20Module%20Normally%20Open%20Type%20is%20based%20on%20the,by%20the%20on%2Dboard%20potentiometer.

Microcontroller Used

Second part of video shows the led ON and OFF with help of Google Assistant to DialogFlow chat bot to Open end Point generated from local port 4000 by NgRok VPN to NodeJs server and server published to MQTT broker.

Basic Architecture

Architecture includes four network flows: A, B, C,D.

  • A” network flows are secured with tls/ssl, which are between subscriber, publisher and Broker. MQTT broker act as Broker, both microcontroller and NodeJs servers act as subscriber and publisher.
  • B” network flows are between DialogFlow Chat Bot and Nodejs server end points at localhost:4000, which converted online with help of NgRok VPN.
  • C” network flows are between local browser Html page and Nodejs server, which is connected with WeB socket for real time data update.
  • D” network flows are between Google asssistant and DialogFlow Chat bot. Google Assistance is integrated with DialogFlow Chat Bot.

Implementation Part!!

This project implemented in 4 parts:

  1. Setting up secure MQTT broker.
  2. NodeJs server with server side renderring Html Page.
  3. Code for ESP32-c-mini4 microcontroller.
  4. Integrating of Google Assistant with DialogFlow Chat Bot.

Setting Up Secure MQTT Broker

Installed MOSQUITTO message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. in my local ubuntu machine. link: https://mosquitto.org/

  • Config file path: /etc/mosquitto/mosquitto.conf

To bind all IP at port 8883 and activate ssl/tls connections, added configurations:

#It will bind all ip to listen at port 8883
listener 8883 0.0.0.0

#Certificates path
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/server.key
certfile /etc/mosquitto/certs/server.crt

#Enable certificated check
require_certificate true
use_identity_as_username true
  • For more configuration , check:

https://mosquitto.org/man/mosquitto-tls-7.html

https://blog.devolutions.net/2020/07/tutorial-how-to-generate-secure-self-signed-server-and-client-certificates-with-openssl/

Generation of self-signed certificates Steps:

  • I used OpenSSL tool to create all certificates.
  1. CA (certificate Authority)
#Generate a certificate authority certificate and key.
openssl req -new -x509 -days 500 -extensions v3_ca -keyout ca.key -out ca.crt

##above command generate two files "ca.key" and "ca.crt"

2. Server keys and certificate

# Generate a server key without encryption.
openssl genrsa -out server.key 2048

#Generate a certificate signing request to send to the CA.
openssl req -out server.csr -key server.key -new

## Above command generate two files "server.key" and "server.csr"
  • You will be prompted to provide some information about the server certificate. You can enter the same information you used for the CA certificate.
#Sign it with your CA key
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1000 -sha256

##Above command create file name: "server.crt"

3. Client key and certificate

## Create both client key and Client Certificate Signing Request
openssl req -out client.csr -key client.key -new

##Above command create file name: "client.key" and "client.csr"
  • You will be prompted to submit information about the client certificate. You can enter the same information as the CA certificate, except for the last two entries: Common Name and Email Address. These should be the name and email of an individual and not your server.
##Generate the Client Certificate
openssl x509 -req -in client1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client1.crt -days 1000 -sha256

##Above command create file name: "client.crt"

For MOSQUITTO broker use

  • ca.crt
  • server.key
  • server.crt

For Publisher or subscriber use

  • ca.crt
  • client.key
  • client.crt

NodeJs Server with server side renderring Html Page

Source code: https://github.com/rohitCodeRed/iot-with-secure-mqtt

For hosting server I used ExpressJs framework.

It has two End points, a Web Socket, act as publisher and subscriber for TOPICS: [“sensor_data”,”vibrate_data”,”rgb_light”]

app.get('/', (req, res) => {        //get requests to the root ("/") will route here
//res.sendFile('index.html', {root: TEMPALTE_PATH}); //server responds by sending the index.html file to the client's browser
res.render("pages/index",{
"ip": SERVER_IP,
"port":SERVER_PORT,
"endPoint": SERVER_SOCKET_ENDPOINT,
}) //the .sendFile method needs the absolute path to the file, see: https://expressjs.com/en/4x/api.html#res.sendFile
});


//Used for Dilaog flow agent POST API.....
app.post('/dialogflow_iot',function(req,res){

handleGoogleRequest(req,res,mConnection,"rgb_light");
});

For rendering HTML page, I used EJS framework. All pages anf script are present at path: “./views/pages” and “./views/partials”

Web Socket codes:

//At server side   at file path: "main.js"
const wss = new websocket.Server({server:server,path:"/"+SERVER_SOCKET_ENDPOINT});


//At client side or in client side script "./views/pages/script.ejs"
const socket = new WebSocket("ws:\/\/"+CURRENT_INFO.ip+":"+CURRENT_INFO.port+CURRENT_INFO.endPoint);

MQTT Publish and Subscribe

'use strict';

const mqtt = require('mqtt');

/*

let KEY = fs.readFileSync('./certs/client.key');
let CERT = fs.readFileSync('./certs/client.crt');
let CAfile = fs.readFileSync('./certs/ca.crt');

let options = {
clientId:"IOT_1",
rejectUnauthorized : false,
key: KEY,
cert: CERT,
ca:CAfile
};
*/

class mQTT{
constructor(url, port) {
this.url = url;
this.port = port;
this.client = {};
}

connect(options){
this.client = mqtt.connect(this.url+':'+this.port,options);
//console.log("Is client connected: ",this.client.connected);
return this.client;
}
}

module.exports = {
mQTT
}

TOPIC Detail

  • sensor_data: Data format recieve on this topic <temperature>:<humidity> e.g “20:60.5”.
  • vibration_data: This topic recieve Y or N. Y mean device vibrated or vice versa.
  • rgb_light: This topic also recieve Y or N. Y mean LED ON or vice versa.

Code for ESP32-c-mini4 microcontroller

Device code available at git hub: https://github.com/rohitCodeRed/iot-with-secure-mqtt in folder path: “./device_code/iot-device-code.ino”.

  • Used Arduino IDE for esp32-c-mini4, DHT11, PubSubClient arduino library for microcntroller.

Microcontroller Pin Used:

  • GPIO PIN 2 : Temperature sensor(DHT11) as DIGITAL INPUT mode.
  • GPIO PIN 4 : Vibration sensor(SW-18015P) as pin mode INPUT_PULLUP, Attached as an interrupt with RISING mode.
  • GPIO PIN 8 (RGB_BUILTIN): For ON and OFF the default rgb LED.
#include <Arduino.h>
#include "DHT.h"

struct Vibration {
const uint8_t PIN;
bool vibrate;
};

Vibration v1 = {4, false};

/*
Interrupt routine.....
*/
void ARDUINO_ISR_ATTR isr() {
v1.vibrate= true;
}


#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

static bool LED=false;

void setup() {
//.......
//......

Serial.println("Initiating vibration...");
pinMode(v1.PIN, INPUT_PULLUP); //Vibration sensor setup
attachInterrupt(v1.PIN, isr, RISING); //Vibration sensor setup

Serial.println("Initiating Temperature and humidity sensor...");
dht.begin();
}
//.....

Code for Wiffi connection, Publish and Subcribe

#include <WiFiClientSecure.h>
#include <PubSubClient.h>

const char* ssid = "--------";
const char* password = "--------";

IPAddress endPoint(192, 168, 8, 101);

//.................
// xxxxxxxxxx-certificate.pem.crt
const char* certificate_pem_crt = "..... client.crt content"

// xxxxxxxxxx-private.pem.key
const char* private_pem_key = "... client.key content"

const char* rootCA = "... ca.crt content"

WiFiClientSecure wiFiClient;
void msgReceived(char* topic, byte* payload, unsigned int len);
PubSubClient pubSubClient(endPoint, 8883, msgReceived, wiFiClient);

//....
void setup() {
//.....

Serial.print("Connecting to "); Serial.print(ssid);
WiFi.begin(ssid, password);
WiFi.waitForConnectResult();
Serial.print(", WiFi connected, IP address: "); Serial.print(WiFi.localIP());

wiFiClient.setCACert(rootCA);
wiFiClient.setCertificate(certificate_pem_crt);
wiFiClient.setPrivateKey(private_pem_key);
//.....
}

void loop() {

pubSubCheckConnect();
//.....
}

Integrating of Google Assistant with DialogFlow Chat Bot

Dialogflow is a natural language understanding platform that makes it easy to design and integrate a conversational user interface into your mobile app.

Agent Name: IOT

Integrated with Google assistant

Fulfilment Request

  • Added online URL generated by NGROK
ngrok http 4000   ## Will give online public url... 

Hope, you all like this project.

Thanks for reading.

--

--

Rohit

Experience in MEAN stack, python,Go, AWS, Docker and Linux. Intrested in learning AI&ML, IOT and blockchain and exploring blog writing to help others!!