MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

Question regarding TLS over MQTTNet in Mosquitto

Open xyderos opened this issue 1 year ago • 11 comments

Describe your question

I am trying to configure a local development environment using TLS and mosquitto on Ubuntu.

I have generated some certificates that work on authentication using mosquitto's test pub client (I am providing both the cacert, client private key as well as the client certificate).

I followed all the possible solutions provided here and this is the result on the mosquitto side 1698226011: New connection from 127.0.0.1:42850 on port 8883. 1698226011: Client <unknown> disconnected: Protocol error.

I am using the managed client.

In order to generate the .pfx file I tried both with the ca certificate, client key and client certificate as well as just the client key and the client certificate.

Is there a different approach that I should follow in order to generate the .pfx? WOuld there be a workaround to just pass the client key, cert and/or even the ca certificate in order to authenticate?

Which project is your question related to?

  • ManagedClient
  • Generic

xyderos avatar Oct 25 '23 09:10 xyderos

This is the testing code snippet, the output is always false

using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using ConsoleApp1;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol;


var caCert =X509Certificate.CreateFromCertFile(@"../../../../../ca/certificate.crt");
var clientCert = new X509Certificate2(@"../../../../../client/client.pfx");

var options = new ManagedMqttClientOptionsBuilder()
    .WithClientOptions(new MqttClientOptionsBuilder()
        .WithClientId(Guid.NewGuid().ToString())
        .WithTcpServer("0.0.0.0", 8883)
        .WithTls(new MqttClientOptionsBuilderTlsParameters()
        {
            UseTls = true,
            SslProtocol = System.Security.Authentication.SslProtocols.Tls13,
            Certificates = new List<X509Certificate>()
            {
                clientCert
            },
            CertificateValidationHandler = static _ => true,
        })
        .Build())
    .Build();


var client = new MqttFactory().CreateManagedMqttClient();

await client.StartAsync(options);

await Task.Delay(180);
await client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("kostas")
    .WithPayload("hi").Build());

await Task.Delay(180);


Console.WriteLine(client.IsConnected);

xyderos avatar Oct 25 '23 09:10 xyderos

I think you have at least two issues.

Did you add any of the certificates to the machine’s certificate store?

I don’t see where you specified the address of the server.

On Wed, Oct 25, 2023, at 05:58, xyderos wrote:

This is the testing code snippet, the output is always false

`using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using ConsoleApp1; using MQTTnet; using MQTTnet.Client; using MQTTnet.Extensions.ManagedClient; using MQTTnet.Protocol;

var caCert =X509Certificate.CreateFromCertFile(@"../../../../../ca/certificate.crt"); var clientCert = new X509Certificate2(@"../../../../../client/client.pfx");

var options = new ManagedMqttClientOptionsBuilder() .WithClientOptions(new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString()) .WithTcpServer("0.0.0.0", 8883) .WithTls(new MqttClientOptionsBuilderTlsParameters() { UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls13, Certificates = new List<X509Certificate>() { clientCert }, CertificateValidationHandler = static _ => true, }) .Build()) .Build();

var client = new MqttFactory().CreateManagedMqttClient();

await client.StartAsync(options);

await Task.Delay(180); await client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("kostas") .WithPayload("hi").Build());

await Task.Delay(180);

Console.WriteLine(client.IsConnected);

`

— Reply to this email directly, view it on GitHub https://github.com/dotnet/MQTTnet/issues/1864#issuecomment-1778918443, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7LEC2V7WFS4YZ4XI3LYBDPEHAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZYHEYTQNBUGM. You are receiving this because you are subscribed to this thread.Message ID: @.***>

ShawnStoddard avatar Oct 25 '23 11:10 ShawnStoddard

I think you have at least two issues. Did you add any of the certificates to the machine’s certificate store? I don’t see where you specified the address of the server. On Wed, Oct 25, 2023, at 05:58, xyderos wrote: This is the testing code snippet, the output is always false using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using ConsoleApp1; using MQTTnet; using MQTTnet.Client; using MQTTnet.Extensions.ManagedClient; using MQTTnet.Protocol; var caCert =X509Certificate.CreateFromCertFile(@"../../../../../ca/certificate.crt"); var clientCert = new X509Certificate2(@"../../../../../client/client.pfx"); var options = new ManagedMqttClientOptionsBuilder() .WithClientOptions(new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString()) .WithTcpServer("0.0.0.0", 8883) .WithTls(new MqttClientOptionsBuilderTlsParameters() { UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls13, Certificates = new List<X509Certificate>() { clientCert }, CertificateValidationHandler = static _ => true, }) .Build()) .Build(); var client = new MqttFactory().CreateManagedMqttClient(); await client.StartAsync(options); await Task.Delay(180); await client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("kostas") .WithPayload("hi").Build()); await Task.Delay(180); Console.WriteLine(client.IsConnected); — Reply to this email directly, view it on GitHub <#1864 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7LEC2V7WFS4YZ4XI3LYBDPEHAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZYHEYTQNBUGM. You are receiving this because you are subscribed to this thread.Message ID: @.***>

Hi! The address of the server is 0.0.0.0, this is used in the local dev machine that I tested the mosquitto pub and sub commands.

On what concerns the certificate store, isnt this the reason we are providing the ca certificate to the sample code? Or do I explicitly need to add them to the store (I have configured mosquitto with a custom config directory, it will not load the certs from /etc/mosquitto folder)

xyderos avatar Oct 25 '23 12:10 xyderos

Maybe I missed it - what’s the environment you’re operating in? Windows? Linux?

On Wed, Oct 25, 2023, at 08:46, xyderos wrote:

I think you have at least two issues. Did you add any of the certificates to the machine’s certificate store? I don’t see where you specified the address of the server. On Wed, Oct 25, 2023, at 05:58, xyderos wrote: This is the testing code snippet, the output is always false using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using ConsoleApp1; using MQTTnet; using MQTTnet.Client; using MQTTnet.Extensions.ManagedClient; using MQTTnet.Protocol; var caCert =X509Certificate.CreateFromCertFile(@"../../../../../ca/certificate.crt"); var clientCert = new X509Certificate2(@"../../../../../client/client.pfx"); var options = new ManagedMqttClientOptionsBuilder() .WithClientOptions(new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString()) .WithTcpServer("0.0.0.0", 8883) .WithTls(new MqttClientOptionsBuilderTlsParameters() { UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls13, Certificates = new List<X509Certificate>() { clientCert }, CertificateValidationHandler = static _ => true, }) .Build()) .Build(); var client = new MqttFactory().CreateManagedMqttClient(); await client.StartAsync(options); await Task.Delay(180); await client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("kostas") .WithPayload("hi").Build()); await Task.Delay(180); Console.WriteLine(client.IsConnected); … <#> — Reply to this email directly, view it on GitHub <#1864 (comment) https://github.com/dotnet/MQTTnet/issues/1864#issuecomment-1778918443>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7LEC2V7WFS4YZ4XI3LYBDPEHAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZYHEYTQNBUGM. You are receiving this because you are subscribed to this thread.Message ID: @.***>

Hi! The address of the server is 0.0.0.0, this is used in the local dev machine that I tested the mosquitto pub and sub commands.

On what concerns the certificate store, isnt this the reason we are providing the ca certificate to the sample code? Or do I explicitly need to add them to the store (I have configured mosquitto with a custom config directory, it will not load the certs from /etc/mosquitto folder)

— Reply to this email directly, view it on GitHub https://github.com/dotnet/MQTTnet/issues/1864#issuecomment-1779198742, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7IQVUGX5HRIC4ONLLTYBECZNAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZZGE4TQNZUGI. You are receiving this because you commented.Message ID: @.***>

ShawnStoddard avatar Oct 25 '23 13:10 ShawnStoddard

Maybe I missed it - what’s the environment you’re operating in? Windows? Linux? On Wed, Oct 25, 2023, at 08:46, xyderos wrote: > > I think you have at least two issues. Did you add any of the certificates to the machine’s certificate store? I don’t see where you specified the address of the server. > On Wed, Oct 25, 2023, at 05:58, xyderos wrote: This is the testing code snippet, the output is always false using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using ConsoleApp1; using MQTTnet; using MQTTnet.Client; using MQTTnet.Extensions.ManagedClient; using MQTTnet.Protocol; var caCert =X509Certificate.CreateFromCertFile(@"../../../../../ca/certificate.crt"); var clientCert = new X509Certificate2(@"../../../../../client/client.pfx"); var options = new ManagedMqttClientOptionsBuilder() .WithClientOptions(new MqttClientOptionsBuilder() .WithClientId(Guid.NewGuid().ToString()) .WithTcpServer("0.0.0.0", 8883) .WithTls(new MqttClientOptionsBuilderTlsParameters() { UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls13, Certificates = new List<X509Certificate>() { clientCert }, CertificateValidationHandler = static _ => true, }) .Build()) .Build(); var client = new MqttFactory().CreateManagedMqttClient(); await client.StartAsync(options); await Task.Delay(180); await client.EnqueueAsync(new MqttApplicationMessageBuilder().WithTopic("kostas") .WithPayload("hi").Build()); await Task.Delay(180); Console.WriteLine(client.IsConnected); > … <#> > — Reply to this email directly, view it on GitHub <#1864 (comment) <#1864 (comment)>>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7LEC2V7WFS4YZ4XI3LYBDPEHAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZYHEYTQNBUGM. You are receiving this because you are subscribed to this thread.Message ID: @.> > Hi! The address of the server is 0.0.0.0, this is used in the local dev machine that I tested the mosquitto pub and sub commands. On what concerns the certificate store, isnt this the reason we are providing the ca certificate to the sample code? Or do I explicitly need to add them to the store (I have configured mosquitto with a custom config directory, it will not load the certs from /etc/mosquitto folder) — Reply to this email directly, view it on GitHub <#1864 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARTX7IQVUGX5HRIC4ONLLTYBECZNAVCNFSM6AAAAAA6PCBEHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZZGE4TQNZUGI. You are receiving this because you commented.Message ID: @.>

Linux

xyderos avatar Oct 25 '23 13:10 xyderos

These samples include instructions to setup mosquitto with TLS, and sample code to connect with MQTTNet:

https://github.com/Azure-Samples/MqttApplicationSamples/tree/main/scenarios/getting_started#fly-configure-mosquitto

rido-min avatar Oct 25 '23 14:10 rido-min

https://github.com/Azure-Samples/MqttApplicationSamples/tree/main/scenarios/getting_started#fly-configure-mosquitto Thank you for your response, I went through the tutorial and it seems that I am following the exact same logic. Since I am authenticating via the pub and sub clients it means that the authentication part is up and running (whether I add the ca cert to the trust store or not). I do not have a two level CA with an middle CA (I am the CA for the local development) and thus the chain can be discarded to the CA cert only. openssl verify with the cacert and the pfx validates to true also.

xyderos avatar Oct 25 '23 16:10 xyderos

@xyderos can you try MqttApplicationSamples? If you have any issues, please open a ticket in that repo, and we will help you.

There are multiple moving parts, such as how the TLS is configured in mosquitto that are very "tricky", eg see this mosquitto.conf

There are details on how you configure the cafile (extension of the file, IIRC it has to be .pem instead of .crt, and the orther of the certs, if there is a chain) that might impact in your scenario.

however the protocol error seems like an error with the TLS negotiation, can you try with TLSv1.2 ?

rido-min avatar Oct 25 '23 17:10 rido-min

@xyderos can you try MqttApplicationSamples? If you have any issues, please open a ticket in that repo, and we will help you.

Hi again, I tried generating some certificates via step but the test clients of mosquitto failed to connect with a tlsv1 internal error on the broker side and Client (null) sending CONNECT Error: host name verification failed. OpenSSL Error[0]: error:0A000086:SSL routines::certificate verify failed

Perhaps there is an issue with the documentation, but I am also assuming that in my case there is probably some faulty part on the openssl side, will have to investigate more.

I will keep this ticket open until I fix the issue since it might be handy to someone in the future :)

xyderos avatar Oct 26 '23 13:10 xyderos

@xyderos can you move this ticket to the other MqttApplicationSample repo?

seems to me the cert does not have the SAN with your hostname.

rido-min avatar Oct 26 '23 18:10 rido-min

@rido-min Absolutely, will move it there!

xyderos avatar Oct 27 '23 08:10 xyderos