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

Add support for secure MQTT connections with TLS #106

Merged
merged 5 commits into from
Nov 28, 2024

Conversation

Martinius79
Copy link
Collaborator

Add support for secure MQTT connections with TLS.
Now it is possible to connect to MQTT broker with TLS support, like HiveMQ or a local Mosquitto, with TLS enabled.

  • New #define MQTT_USE_TLS in _USER_DEFINES.h in the MQTT broker session
  • If defined, Wifi uses the WiFiClientSecure instead of WiFiClient
  • As default, the Let's Encrypt CA root certificate is hardcoded in the code and used to verify the connection certs. Any other root CA cert can be added (depends on the used broker and there cert used to establish TLS). Normally, one cert should be enough in memory, because only one broker is used.

Note: HiveMQ is one of the internet-based brokers, which supports Home Assistant messages and can be used.

WiFiClientSecure espClient;
// ************ Let's encrypt CA Root Certificate *****************
// Valid To 04 Jun 2035
const char *SSL_CA_PEM = "-----BEGIN CERTIFICATE-----\n"
Copy link

@eku eku Nov 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything to be said against not embedding the certificate in the code but reading it from the file system instead? Or at least include it from a user config header file here and leave it up to the user to decide which Root CA is used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea to load the cert from a PEM file in the data partition. I will modify the code and test it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea to load the cert from a PEM file in the data partition.

If the cert expires, the code does not have to be recompiled and flashed.

@aly-fly
Copy link
Owner

aly-fly commented Nov 25, 2024

How much extra flash consumes the certificate + Secure client? It may be worth checking if this fits into existing partition table for 4M Flash version. And adding a note in the Config file next to the MQTT_USE_TLS option.

@Martinius79
Copy link
Collaborator Author

How much extra flash consumes the certificate + Secure client? It may be worth checking if this fits into existing partition table for 4M Flash version. And adding a note in the Config file next to the MQTT_USE_TLS option.

Cert is ~2k and now in the data folder. No problem to store it there.

image

Code with secure client needs a bit more space in the app partition.

Without:
image

With:
image

Other settings are no relevant to see the increase for the sec client.

The pem file can be deleted, if no TLS is used. So don't know, if it should be there as default. Limited amount of user will need it, I guess.

What are your thoughts?

@aly-fly
Copy link
Owner

aly-fly commented Nov 26, 2024

Secure client adds ~500 bytes to the app size. That's fine.

My suggestions:

  1. Write a note like:
    // #define MQTT_USE_TLS // Enable this is your MQTT server requires TLS secure connection. // Don't forget to copy the correct certificate file into the Data folder and rename it to "MQTT_CERT.PEM". Example file can be found in .... folder.

  2. Before loading the PEM file check if file exists, print an error message, and halt further execution.

@eku
Copy link

eku commented Nov 26, 2024

2. Before loading the PEM file check if file exists, print an error message, and halt further execution.

Would be falling back to unencrypted communication an option?

@aly-fly
Copy link
Owner

aly-fly commented Nov 26, 2024

That would mean that firmware has to load both TCP clients (unencrypted and secure) and then on the fly switch between them. Waste of Flash and RAM.
Also, the user (and server) which need secure communication would be left unencrypted, if not paying attention to a small warning message in the flood of other boot messages.

…AVE_PREFERENCES_AFTER_SEC up - changed filenmae for CA root cert - Added check if file exists - Moved CA file as example to 'data - other graphics' folder
@Martinius79
Copy link
Collaborator Author

  1. Write a note like:
    // #define MQTT_USE_TLS // Enable this is your MQTT server requires TLS secure connection. // Don't forget to copy the correct certificate file into the Data folder and rename it to "MQTT_CERT.PEM". Example file can be found in .... folder.

Done

  1. Before loading the PEM file check if file exists, print an error message, and halt further execution.

Done

@Martinius79
Copy link
Collaborator Author

Would be falling back to unencrypted communication an option?

All what aly-fly mentioned is true.

And in the moment, there can only be one port defined and that means, TLS or no TLS as well, so it is this or that, never both.
Of course, it is possible to define two ports and have a fallback, but if someone knows, that he/she wants to use MQTT with TLS, there should be no unencrxpted fallback IMO.

@aly-fly aly-fly merged commit 2420502 into aly-fly:main Nov 28, 2024
2 checks passed
@Martinius79 Martinius79 deleted the AddedMQTTAbleToUseTLS branch November 28, 2024 18:46
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.

4 participants