Add support for SSL in MQTT Bridge - #223
Conversation
Signed-off-by: António Pedro <tonio.pedro99@gmail.com>
tinaselenge
left a comment
There was a problem hiding this comment.
Thank you @antonio-pedro99 for the well written proposal. I don't have an experience with MQTT Bridge, therefore I can't offer in-depth feedback for this proposal. However, what has been proposed generally makes sense and sounds good to me but as I said, I can't say much on the actual implementation part that you explained.
I've just left one small comment.
katheris
left a comment
There was a problem hiding this comment.
Hey @antonio-pedro99 I took a quick look and have suggested some changes to better align with config we have elsewhere. However this proposal was discussed on the most recent community call and @ppatierno is going to take a look and see if he thinks this feature should be prioritised right now or not. So I've added the comments incase we decide to go ahead but there's no need to address these comments now as we can wait until Paolo has taken a look first.
|
I'm removing myself from the reviewers, as I don't have needed expertise for this and should be reviewed by @kyguy and @ppatierno mainly as experts. |
|
I had a quick look but I think the proposal is mixing authN, authZ and TLS support.
Comparing what we have today within the HTTP bridge, only the TLS support would be "easy" to add and providing a minimum of security. |
|
Hey @antonio-pedro99 based on Paolo's comments can you update the proposal to focus only on enabling TLS and remove the configuration that is specific to authentication and any other parts that are auth related? |
Hi @katheris, yes, I will update it once I have some time. |
Co-authored-by: Kate Stanley <11195226+katheris@users.noreply.github.com> Signed-off-by: António Pedro <42675180+antonio-pedro99@users.noreply.github.com>
Co-authored-by: Kate Stanley <11195226+katheris@users.noreply.github.com> Signed-off-by: António Pedro <42675180+antonio-pedro99@users.noreply.github.com>
Co-authored-by: Kate Stanley <11195226+katheris@users.noreply.github.com> Signed-off-by: António Pedro <42675180+antonio-pedro99@users.noreply.github.com>
Signed-off-by: Antonio Pedro <tonio.pedro99@gmail.com>
kyguy
left a comment
There was a problem hiding this comment.
Hi @antonio-pedro99 so sorry I am late to the party. Great start on the proposal, I think it is awesome you are driving this! I left a couple of comments to start. I'll help you flesh this out with periodic reviews if you would like to help get this over the line.
|
|
||
| After this, we are going to create a new configuration wrapper class to load and manage these new config options, say `MqttSslConfig`. | ||
| This class will then be part of the existing `MqttConfig`. | ||
| The SSL/TLS state will be derived from the configured MQTT server port rather than from a separate enable flag; for example, `MqttSslConfig.isEnabled()` can return true when the configured port is 8883. |
There was a problem hiding this comment.
I understand that 8883 is the standardized port for MQTT over TLS but what happens when a user configures TLS on a another port? What if mqtt.server.port=8883 but TLS is not configured? Would it be more reliable to use the the mqtt.server.ssl.* to check whether TLS is enabled?
There was a problem hiding this comment.
I agree with Kyle we should try to follow as much as possible the same approach we have in the HTTP bridge so that people using the two will be comfortable. So yes, I think that a flag like mqtt.server.ssl.enable=true would be beneficial (as HTTP bridge has http.ssl.enable=true).
| protected void initChannel(SocketChannel ch) { | ||
| if (sslConfig.isEnabled()) { | ||
| MqttSslContextProvider sslContextProvider = new MqttSslContextProvider(sslConfig); | ||
| SslContext sslContext = sslContextProvider.createSslContext(); |
There was a problem hiding this comment.
Do we need to call createSslContext() for every new client connection? Couldn't we call this once in MqttServerInitializer and reuse it?
| mqtt.server.ssl.certificate.location=path/to/server-cert.pem | ||
| mqtt.server.ssl.key.location=path/to/server-key.pem | ||
| mqtt.server.ssl.certificate=--BEGIN CERTIFICATE--\n...\n--END CERTIFICATE-- | ||
| mqtt.server.ssl.key=--BEGIN PRIVATE KEY--\n...\n--END PRIVATE KEY-- |
There was a problem hiding this comment.
I imagine we would want some configurations for a truststore as well right? (assuming we want to support MTLS)
There was a problem hiding this comment.
It is just an encryption. Truststore would be needed for mTLS authentication only. Or are there some internal connections between instances of the MQTT bridge etc.? I do not think so, or?
There was a problem hiding this comment.
It is just an encryption.
Ah yes, you are right, I forgot this proposal is just for encryption. The mTLS can be addressed in the future proposal for authentication.
@antonio-pedro99 ignore this thread!
There was a problem hiding this comment.
Yes let's focus on encryption only as I requested. We'll move with authN and authZ (by also adding mTLS) in the future.
| We will begin by adding new configuration options to the MQTT Bridge. | ||
| These options will allow users to enable secure MQTT connections and specify the necessary SSL/TLS configurations. | ||
| We will not add a separate TLS port configuration. | ||
| The MQTT Bridge will continue to use a single MQTT listener, and MQTT over TLS will use the existing MQTT server port configuration with the standard MQTT over TLS port, 8883. |
There was a problem hiding this comment.
So the bridge would only allow either all connections over TLS or all plaintext, it won't support both TLS and non-TLS connections simultaneously, correct? If so, is that something maybe worth mentioning explicitly here?
Is the purpose of doing this to simplify the iimplementation? If so, maybe it is a potential "future work" item we could add at the end of the proposal if it is not going to be supported initially. WDYT?
There was a problem hiding this comment.
I would stick with plan or encrypted but not supporting them at the same time. It's the same behavior as HTTP bridge and I would stick with consistency.
scholzj
left a comment
There was a problem hiding this comment.
I left some nits, mainly about the formal side of the proposal. You should make sure the proposal sounds authoritative as it describes how it will be done and how it might be done.
Apart from that, I'm not a subject matter expert for the MQTT Bridge. But the technical aspects seemed reasonable.
There was a problem hiding this comment.
This should not be committed I guess.
| @@ -0,0 +1,181 @@ | |||
| # Add SSL/TLS support to MQTT Bridge | |||
There was a problem hiding this comment.
| # Add SSL/TLS support to MQTT Bridge | |
| # Add SSL/TLS encryption support to MQTT Bridge |
Maybe this way it would be a bit more clear what we focus on here?
| Optionally, we can also support the configuration for specifying the protocols and cipher suites: | ||
|
|
||
| ```application.properties | ||
| mqtt.server.ssl.enabled.protocols=TLSv1.2,TLSv1.3 | ||
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 | ||
| ``` |
There was a problem hiding this comment.
You mean ... these configurations will be supported, but they will be optional only for the user I guess?
| Optionally, we can also support the configuration for specifying the protocols and cipher suites: | |
| ```application.properties | |
| mqtt.server.ssl.enabled.protocols=TLSv1.2,TLSv1.3 | |
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 | |
| ``` | |
| We will also support the configuration for specifying the enabled protocols and cipher suites. | |
| These options will be optional for the users and when not set, the Netty / JRE default values will be used. | |
| ```application.properties | |
| mqtt.server.ssl.enabled.protocols=TLSv1.2,TLSv1.3 | |
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 |
|
|
||
| > If these options are not specified, the MQTT Bridge will use the default SSL/TLS configurations provided by the Java runtime. | ||
|
|
||
| After this, we are going to create a new configuration wrapper class to load and manage these new config options, say `MqttSslConfig`. |
There was a problem hiding this comment.
If you mention things such as class names etc., it should be clear that that would be the name used. Or you should not mention the name at all and leave it for the PR. E.g.
| After this, we are going to create a new configuration wrapper class to load and manage these new config options, say `MqttSslConfig`. | |
| A new class named `MqttSslConfig` will be used as a new configuration wrapper class to load and manage these new config options. |
The way you fraze sounds like it is one of the many options, but that is not how the proposal should sound.
| After this, we are going to create a new configuration wrapper class to load and manage these new config options, say `MqttSslConfig`. | ||
| This class will then be part of the existing `MqttConfig`. | ||
| The SSL/TLS state will be derived from the configured MQTT server port rather than from a separate enable flag; for example, `MqttSslConfig.isEnabled()` can return true when the configured port is 8883. | ||
| It would look something like this: |
There was a problem hiding this comment.
Again, the proposal needs to be exact in the things it covers. So it should not looks something like this.
| It would look something like this: | |
| It would look like this: |
|
|
||
| To handle SSL/TLS connections, we will need to add the Netty SSL handler to the pipeline of the server. | ||
| This will require us to modify the existing `MqttServerInitializer` class to include the new handler. | ||
| The final look of the `MqttServerInitializer` class will be something like this: |
There was a problem hiding this comment.
Same as above ... leave out the something.
| Thankfully, Netty provides APIs to easily add SSL/TLS support, so we can leverage those APIs without having to implement the SSL/TLS logic from scratch. | ||
|
|
||
| We will introduce a new component to encapsulate the logic for creating the Netty `SslContext` before adding the SSL handler to the pipeline. | ||
| This component will look something like this: |
There was a problem hiding this comment.
Same as above ... I will not repeat this comment anymore. But please fix it in other places where you use this as well.
|
|
||
| ## Affected/not affected projects | ||
|
|
||
| This proposal will primarily affect the MQTT Bridge component of Strimzi. |
There was a problem hiding this comment.
| This proposal will primarily affect the MQTT Bridge component of Strimzi. | |
| This proposal will affect only the MQTT Bridge component of Strimzi. |
I don't think it will affect anything else, or?
ppatierno
left a comment
There was a problem hiding this comment.
@antonio-pedro99 Thanks for the changes, I have added additional comments.
|
|
||
| ```application.properties | ||
| mqtt.server.ssl.enabled.protocols=TLSv1.2,TLSv1.3 | ||
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 |
There was a problem hiding this comment.
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 | |
| mqtt.server.ssl.enabled.cipher.suites=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 |
I would follow the same parameter name pattern as the HTTP bridge.
| # Add SSL/TLS support to MQTT Bridge | ||
|
|
||
| This proposal is to add support for SSL/TLS to the MQTT Bridge component of Strimzi. | ||
| This would allow MQTT clients to connect to the MQTT Bridge over an encrypted MQTT over TLS connection. |
There was a problem hiding this comment.
| This would allow MQTT clients to connect to the MQTT Bridge over an encrypted MQTT over TLS connection. | |
| This would allow MQTT clients to connect to the MQTT Bridge over an TLS encrypted connection. |
| The MQTT Bridge will continue to use a single MQTT listener, and MQTT over TLS will use the existing MQTT server port configuration with the standard MQTT over TLS port, 8883. | ||
| It will look something like this: | ||
|
|
||
| ```application.properties |
There was a problem hiding this comment.
As already mentioned above we should have a dedicated mqtt.server.ssl.enable configuration property.
|
|
||
| ## Proposal | ||
|
|
||
| This proposal adds support for MQTT over TLS by allowing users to configure a server certificate and private key for the MQTT listener. |
There was a problem hiding this comment.
We should say explicitly that, like the HTTP bridge, it supports certificate and key in PEM format and not PKCS12 for example.
| mqtt.server.ssl.enabled.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 | ||
| ``` | ||
|
|
||
| > If these options are not specified, the MQTT Bridge will use the default SSL/TLS configurations provided by the Java runtime. |
There was a problem hiding this comment.
Let's do the same as the bridge which defaults to TLSv1.2,TLSv1.3
This is a proposal to implement support for TLS/SSL as requested by strimzi/strimzi-mqtt-bridge#84