Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MQTT TLS] Add TLS support for MQTT #3788

Merged
merged 257 commits into from
Oct 2, 2024
Merged

Conversation

TD-er
Copy link
Member

@TD-er TD-er commented Sep 26, 2021

ESP8266 running TLS is adviced to run at 160 MHz.
Tested this frequency, it does seem to work quite OK, so that may be useful for other use cases too.
Power consumption increases with roughly 5 - 7 mA between 80 MHz and 160 MHz.

Currently this does not work on ESP8266 as it continuously runs out of memory.
Maybe when using 2nd heap on core 3.0.0 this may be usable.

ESP32 does seem to work just fine. (tested with Mosquitto)

Included is a selector (in the controller settings) to just allow any TLS certificat presented. Nothing will be checked, thus it is a perfect receipe for a man-in-the-middle attack.
Work-in-progress on adding support for PSK (Pre-Shared-Key), which is supported by Mosquitto.
But it is not widely used along with TLS and so far I have not found other MQTT brokers which support TLS/PSK.

Other options in development:

  • CA certificate compare with root certificate (e.g. from Let's Encrypt, or your own if using self-signed certificates)
  • CA CLI certificate Same as CA certificate + login using client certificate (replacement of user/pass)
  • Certificate fingerprint, just include HEX formatted fingerprint of certificate. Is a lot smaller than full certificate and may be easier to update nodes in the field via for example HTTP get, MQTT messages, etc.
  • Public key of a certificate.
  • Keep TLS session to speed up reconnect

Fixes: #2271
Fixes: #4783

This may prevent additional calls to load the CSS from the file system in a separate HTTP GET call and also not loading the file into memory when streaming.
Making it easier for users to copy/paste certificate code into a file. It will be patched at load from the file system.
There is a memory leak in Mbed TLS, when connection failed.
For example when using a CA root certificate which does not match the certificate of the host we're connecting to.
This will take about 1880 bytes of memory on each attempt.

Still a work-in-progress as it is not yet fixed.
Otherwise you may not always use the latest CA root certificate stored on the file system
In a lot of places an object was allocated on the heap, but not always it was deleted thus leading to memory leaks.
I made an error in previous commit for this PR
@TD-er TD-er merged commit b2e4713 into letscontrolit:mega Oct 2, 2024
168 checks passed
@TD-er TD-er deleted the feature/MQTT_TLS branch October 2, 2024 12:33
@ilsicca
Copy link

ilsicca commented Oct 3, 2024

Hi @TD-er What about MQTT_TLS? Can I test a firmware with that feature?

@TD-er
Copy link
Member Author

TD-er commented Oct 3, 2024

Yep.
See: https://td-er.nl/ESPEasy/latest/
All ESP32-xx custom and "MAX" builds have it included.
And I'm working on some more features where we need SSL/TLS.

N.B. keep in mind there currently is NO validation of certificates, so a man-in-the-middle attack is still possible without you notice it.

@OmarTheEngineer
Copy link

Hi @TD-er, Interesting work man, I was really looking into MQTT TLS in ESP-Easy
Could you perhaps guide me as to where I could assign my certificates for HiveMQ so I could connect to it using MQTT TLS?
I'm using an ESP32.
Thanks
Omar

@TD-er
Copy link
Member Author

TD-er commented Oct 8, 2024

Right now I only have been using username/password for connecting to a MQTT broker.
Using certificates for login is still on my todo list, so not yet possible.

N.B. please note that since I'm now using a stripped down version of BearSSL, I have disabled actually checking the server side certificate.
So the connection is encrypted, but the essence -to make it secure- is not yet implemented as you can still easily use any man-in-the-middle attack.

Initially I did add quite a lot of those checks, fetching certificates, CA, fingerprint, etc.
But that was using mbedTLS. This was a real nightmare as the structs used by mbedTLS were not properly initialized and thus a lot of crashes or memory-leaks when doing a reconnect.
Now I'm using a tailored PlatformIO package of ESP-IDF5.x/Arduino3.x for ESP32-xx to keep the build size manageble, but this also means I needed to have a stripped down version of BearSSL which doesn't allow for a lot of these checks as easy as mbedTLS does.

And since this PR was 'pending' way too long, I now decided to merge it so it is usable and we can see what is actually used by users and add it.

Can you make a new issue for your cert-based connecting to MQTT broker?
Then we can also see/discuss what else is missing.
For example, quite a lot of ciphers have been stripped out to keep the build size down. (adding all would make the bin size about ~600k larger)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FR] Secure MQTT for ESP32 Devices MQTT TLS support
6 participants