MQTTnet icon indicating copy to clipboard operation
MQTTnet copied to clipboard

Server error when using TLS 1.2: CONNECT packet must have at least 7 bytes

Open ovidiaconescu opened this issue 1 year ago • 6 comments

When connecting to the MQTT Server with TLS, the following error is thrown:

[20:57:49 Debug Apm-Trace: Apm-Transaction:] Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
Connection id "0HMVPO9R8V5EA" communication error.
MQTTnet.Exceptions.MqttProtocolViolationException: **CONNECT packet must have at least 7 bytes.**
   at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket)
   at MQTTnet.Formatter.MqttPacketFormatterAdapter.DetectProtocolVersion(ReceivedMqttPacket receivedMqttPacket)
   at MQTTnet.AspNetCore.ReaderExtensions.TryDecode(MqttPacketFormatterAdapter formatter, ReadOnlySequence`1& input, MqttPacket& packet, SequencePosition& consumed, SequencePosition& observed, Int32& bytesRead)
   at MQTTnet.AspNetCore.MqttConnectionContext.ReceivePacketAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal.SocketConnection.DoSend()
   at MQTTnet.Server.MqttClientSessionsManager.ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
   at MQTTnet.Server.MqttClientSessionsManager.HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)

[20:57:49 Debug Apm-Trace: Apm-Transaction:] Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
Connection id "0HMVPO9R8V5EA" sending RST because: "CONNECT packet must have at least 7 bytes."

Which component is your bug related to?

  • .net8.0
  • Client - MQTTnet 4.3.3.952
  • Server - MQTTnet 4.3.3.952 and MQTTnet.AspNetCore 4.3.3.952 Note: this works with a server that is version 3.x

Client Code example

  var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  var certificate = new X509Certificate2(Path.Combine(currentPath, "certificate.pfx"), "password-redacted", X509KeyStorageFlags.Exportable);

  // Create a new MQTT client.
  var factory = new MqttFactory();
  mqttClient = factory.CreateMqttClient();

  var options = new MqttClientOptionsBuilder()
     .WithClientId(clientId)
     .WithTcpServer("localhost", 8883)
     .WithTlsOptions(o =>
     {
         o.UseTls(true);
         o.WithClientCertificates(new List<X509Certificate2> { certificate });
         o.WithCertificateValidationHandler(_ => true);
         o.WithAllowUntrustedCertificates(true); 
         o.WithIgnoreCertificateChainErrors(true);
         o.WithIgnoreCertificateRevocationErrors(true);  

         // the default value is determined by the os. set manually to force version.
         o.WithSslProtocols(SslProtocols.Tls12);
     })
     .WithCredentials(username, password)
     .WithCleanSession()
     .Build();

  await mqttClient.ConnectAsync(options, CancellationToken.None); //server crashes when the client reaches this line

ovidiaconescu avatar Dec 10 '23 21:12 ovidiaconescu

Using v4.2.1.781 of the library.

I have a customer seeing a similar issue, but I am not able to reproduce the issue in a local test bed (also using TLS). I suspect there is something on the network causing issues, but that is just a guess. Here is the stack I currently have:

Here are the stacks I see from both sides:

20:25:47.226] Broker: CONNECT packet must have at least 7 bytes. Exception:MQTTnet.Exceptions.MqttProtocolViolationException: CONNECT packet must have at least 7 bytes. at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.Adapter.MqttChannelAdapter.<ReceivePacketAsync>d__36.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Server.MqttClientSessionsManager.<ReceiveConnectPacket>d__30.MoveNext()

[20:25:47.248] Broker: Error while handling TCP client connection Exception:System.IO.IOException: The handshake failed due to an unexpected packet format. at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Implementations.MqttTcpServerListener.<TryHandleClientConnectionAsync>d__16.MoveNext()

If the client and server communicate without TLS, there are no issues.

Also note we are using the ManagedClient.

jwbrothers avatar Jan 30 '24 23:01 jwbrothers

For what it is worth, I had my customer disable TLS and the 'CONNECT packet must have at least 7 bytes.' error is still being seen from time to time.

jwbrothers avatar Feb 05 '24 19:02 jwbrothers

This is still an issue in v4.3.6.1152

Stack trace: MQTTnet.Exceptions.MqttProtocolViolationException: CONNECT packet must have at least 7 bytes. at MQTTnet.Formatter.MqttPacketFormatterAdapter.ParseProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.Formatter.MqttPacketFormatterAdapter.DetectProtocolVersion(ReceivedMqttPacket receivedMqttPacket) at MQTTnet.AspNetCore.ReaderExtensions.TryDecode(MqttPacketFormatterAdapter formatter, ReadOnlySequence``1& input, MqttPacket& packet, SequencePosition& consumed, SequencePosition& observed, Int32& bytesRead) at MQTTnet.AspNetCore.MqttConnectionContext.ReceivePacketAsync(CancellationToken cancellationToken) at MQTTnet.Server.MqttClientSessionsManager.ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken) at MQTTnet.Server.MqttClientSessionsManager.HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)

ovidiaconescu avatar Jun 25 '24 22:06 ovidiaconescu

@chkr1011 any thoughts?

ovidiaconescu avatar Jun 25 '24 22:06 ovidiaconescu

@ovidiaconescu

This issue seems to occur when TLS decryption isn't set up correctly. I was trying to use a custom ICertificateProvider because my root CA and intermediate broker certificate were unavailable during the configuration of my .NET 8 backend.

Unfortunately, I couldn't get it to work. As a workaround, I added UseHttps to my Kestrel configuration to handle the decryption, followed by UseMqtt to add the MqttConnectionHandler.

nakerlund avatar Aug 11 '24 18:08 nakerlund