Close

Secure ESP8266 MQTT Client

A project log for Secure ESP8266 MQTT p.o.c.

Secure ESP8266 MQTT proof of concept

W. TaylorW. Taylor 02/07/2019 at 18:212 Comments

Secure ESP8266 MQTT Client

Copyright (c) 2019-2020 Warren Taylor.

There are many tutorials on how to program the ESP8266 as an MQTT Client using the Arduino libraries. But it's hard to find a single source clearly describing how to program the ESP8266 as a secure MQTT Client. As a long time software engineer I know how important security is these days.

This project uses the ESP8266 Arduino Core library and board specifications

The source for this project can be found at https://github.com/tsi-software/Secure_ESP8266_MQTT_poc

Disclaimer

The following documentation in no way guarantees a secure system

Security First

At a high level of abstraction secure connections for ESP8266 devices are straight forward when using the arduino-esp8266 BearSSL::WiFiClientSecure class. This is because the BearSSL::WiFiClientSecure class extends from the insecure arduino-esp8266 WiFiClient class. What gets complicated is properly initializing a BearSSL::WiFiClientSecure object, which is what this project focuses on. Once the secure initialization is done the remaining code is implemented mostly the same as the insecure WiFiClient class, of which there are many examples.

ArduinoOTA

The ArduinoOTA library was initially used but later removed from this code because there did not appear to be sufficient resources in the ESP8266 to have a secure connection open by both the MQTT Broker and ArduinoOTA at the same time. In the future, Secure OTA will be implemented differently in order to coexist with Secure MQTT.

Source Files

secure_esp8266_mqtt_client.ino

This is the top level application source code that:

SetupWifi.cpp and SetupWifi.h

This SetupWifi class handles the security and encapsulates the arduino-esp8266 BearSSL::WiFiClientSecure object. This class holds the ssid and password of the Wifi Router and implements the code to connect to that router. This class also holds the ca_cert, client_cert, and client_key used to make secure connections using the BearSSL::WiFiClientSecure class. These certificates and keys were generated when creating the MQTT Keys and Certificates in the Server Setup. Another detail handled by this class, that is not at first obvious, is accurately setting the ESP8266 clock. This is needed because security certificates can, and should, have an expiry date, which is very important in order to prevent old and possibly compromised certificates from being reused. Additionally, UTC (a.k.a. Zulu time) is the internal standard used throughout this project both for consistency and to avoid potential errors arising from differing time zones and daylight savings time.

secure_credentials.h

This file contains a copy of the required certificates and keys that were generated when creating the MQTT Keys and Certificates in the Server Setup.

Storing credentials in source code in considered both insecure and bad practice! One of the main reasons for this is because source code that is committed to your revision control system becomes openly accessible (the opposite of secure). In a subsequent version of this project "secure_credentials.h" will be removed and replaced with a method of securely injecting credentials into the target devices.

AsyncWait.h

AsyncWait.h is code that is independent of security but still worth mentioning here. One of my prime directives is to never write blocking code (code that waits for something to happen but also prevents any other code from executing). AsyncWait allows me to write code in one place that waits for a duration of time but still allows the main loop() to continue processing. I think I may write an entirely separate blog on this topic.

Zones.h

This is application level code, which is independent of security and, therefore, not discussed here.

globals.h

This is application level code, which is independent of security and, therefore, not discussed here.

Hardware Schematics

Schematics

Future Features

OTA (Over-the-Air) Updates

Future versions of this ESP8266 MQTT Client will have secure OTA updates enabled. The ESP8266 will be updated in a manner similar to that of the ArduinoOTA code but instead using the existing secure MQTT connection in order to keep memory use minimal. The AVR SPI Slave will be updated over-the-air by using the ESP8266 as an AVR ISP (In-System Programming) device. Again using the existing secure MQTT connection in order to keep memory use minimal.

MQTT Client References

Discussions

W. Taylor wrote 06/14/2020 at 21:24 point

Sorry, that's not nearly enough information to go on. The problems that I've most often run into relate to: being on the same LAN, incorrect IP or host-name, and expired or incorrect security certificates.

  Are you sure? yes | no

Jonathan wrote 02/10/2020 at 00:54 point

Great tutorial but I get the following error:

1581295795: New connection from 192.168.2.125 on port 8883.

1581295800: Socket error on client <unknown>, disconnecting.

Any ideas?

  Are you sure? yes | no