emqx / MQTTX

A Powerful and All-in-One MQTT 5.0 client toolbox for Desktop, CLI and WebSocket.
https://mqttx.app
Apache License 2.0
3.64k stars 428 forks source link

CLI WSS auth using Client + Cert does not work, but Username + Password does #1663

Closed jason-grimme closed 4 weeks ago

jason-grimme commented 1 month ago

What did I do

I am trying to use CLI to connect to MQTT via WSS with client certificate & key. The same options work in GUI, but not with the CLI. When I use --debug I can see that CLI has some logic where it thinks protocol is mqtts even if I specify protocol as WSS.

What happened

Note: I am trying this with my internal MQTT broker. I am using broker.emqx.io just as example.

✅ Works (Username + Password) mqttx conn --debug --mqtt-version 3.1.1 --protocol "wss" --insecure -h "broker.emqx.io" -p 8084 --client-id "ThisWillWork" -u "user" -P "pass" ❌ Does not work (Key + Cert + CA) mqttx conn --debug --mqtt-version 3.1.1 --protocol "wss" --insecure -h "broker.emqx.io" -p 8084 --client-id "ThisWillNotWork" --key "C:\Temp\client.key" --cert "C:\Temp\client.pem" --ca "C:\Temp\server.pem"

Expected

I expect that I can use WSS and certificate based authentication to connect / subscribe / publish, which works in the GUI.

Environment

More detail

CLI Debug when using Cert + Key. Notice protocol = mqtts on second line

 mqttjs connecting to an MQTT broker... +0ms
  mqttjs:client MqttClient :: options.protocol mqtts +0ms
  mqttjs:client MqttClient :: options.protocolVersion 4 +0ms
  mqttjs:client MqttClient :: options.username undefined +1ms
  mqttjs:client MqttClient :: options.keepalive 30 +0ms
  mqttjs:client MqttClient :: options.reconnectPeriod 1000 +0ms
  mqttjs:client MqttClient :: options.rejectUnauthorized false +1ms
  mqttjs:client MqttClient :: options.topicAliasMaximum undefined +0ms
  mqttjs:client MqttClient :: clientId ThisWillNotWork +0ms
  mqttjs:client MqttClient :: setting up stream +0ms
  mqttjs:client _setupStream :: calling method to clear reconnect +0ms
  mqttjs:client _clearReconnect : clearing reconnect timer +1ms
  mqttjs:client _setupStream :: using streamBuilder provided to client to create stream +0ms
  mqttjs calling streambuilder for mqtts +4ms
  mqttjs:tls port 8084 host broker.emqx.io rejectUnauthorized %b false +0ms
  mqttjs:client _setupStream :: pipe stream to writable stream +21ms
  mqttjs:client _setupStream: sending packet `connect` +0ms
  mqttjs:client sendPacket :: packet: { cmd: 'connect' } +1ms
  mqttjs:client sendPacket :: emitting `packetsend` +1ms
  mqttjs:client sendPacket :: writing to stream +0ms
  mqttjs:client sendPacket :: writeToStream result true +8ms
[5/21/2024] [8:01:40 PM] » ...  Connecting...
  mqttjs:client streamErrorHandler :: error read ECONNRESET +67ms
  mqttjs:client streamErrorHandler :: emitting error +0ms
[5/21/2024] [8:01:40 PM] » ×  Error: read ECONNRESET
    at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20)
  mqttjs:client end :: (ThisWillNotWork) +1ms
  mqttjs:client end :: cb? true +1ms
  mqttjs:client _clearReconnect : clearing reconnect timer +0ms
  mqttjs:client end :: (ThisWillNotWork) :: immediately calling finish +1ms
  mqttjs:client end :: (ThisWillNotWork) :: finish :: calling _cleanUp with force false +0ms
  mqttjs:client _cleanUp :: done callback provided for on stream close +1ms
  mqttjs:client _cleanUp :: forced? false +0ms
  mqttjs:client _cleanUp :: (ThisWillNotWork) :: call _sendPacket with disconnect packet +0ms
  mqttjs:client _sendPacket :: (ThisWillNotWork) ::  start +1ms
  mqttjs:client _sendPacket :: client not connected. Storing packet offline. +0ms
  mqttjs:client _storePacket :: packet: { cmd: 'disconnect' } +0ms
  mqttjs:client _storePacket :: cb? true +1ms
  mqttjs:client _cleanUp :: (ThisWillNotWork) :: removing stream `done` callback `close` listener +0ms
  mqttjs:client end :: finish :: calling process.nextTick on closeStores +0ms
  mqttjs:client end :: closeStores: closing incoming and outgoing stores +1ms
  mqttjs:client end :: closeStores: emitting end +0ms
  mqttjs:client end :: closeStores: invoking callback with args +1ms
  mqttjs:client nop :: undefined +0ms
  mqttjs:client (ThisWillNotWork)stream :: on close +1ms
  mqttjs:client flushVolatile :: deleting volatile messages from the queue and setting their callbacks as error function +0ms
  mqttjs:client stream: emit close to MqttClient +0ms
  mqttjs:client close :: connected set to `false` +1ms
  mqttjs:client close :: clearing connackTimer +0ms
  mqttjs:client close :: clearing ping timer +1ms
  mqttjs:client close :: calling _setupReconnect +0ms
  mqttjs:client _setupReconnect :: doing nothing... +0ms
[5/21/2024] [8:01:40 PM] » ×  Connection closed

CLI when using username + password. Notice the second line indicates 'wss' and correctly forms the URI wss://broker.emqx.io:8084/mqtt

mqttjs connecting to an MQTT broker... +0ms
  mqttjs:client MqttClient :: options.protocol wss +0ms
  mqttjs:client MqttClient :: options.protocolVersion 4 +0ms
  mqttjs:client MqttClient :: options.username undefined +1ms
  mqttjs:client MqttClient :: options.keepalive 30 +0ms
  mqttjs:client MqttClient :: options.reconnectPeriod 1000 +0ms
  mqttjs:client MqttClient :: options.rejectUnauthorized false +0ms
  mqttjs:client MqttClient :: options.topicAliasMaximum undefined +1ms
  mqttjs:client MqttClient :: clientId ThisWillWork +0ms
  mqttjs:client MqttClient :: setting up stream +0ms
  mqttjs:client _setupStream :: calling method to clear reconnect +1ms
  mqttjs:client _clearReconnect : clearing reconnect timer +0ms
  mqttjs:client _setupStream :: using streamBuilder provided to client to create stream +0ms
  mqttjs calling streambuilder for wss +6ms
  mqttjs:ws streamBuilder +0ms
  mqttjs:ws createWebSocket +0ms
  mqttjs:ws protocol: MQTT 4 +0ms
  mqttjs:ws creating new Websocket for url: wss://broker.emqx.io:8084/mqtt and protocol: mqtt +0ms
  mqttjs:client _setupStream :: pipe stream to writable stream +27ms
  mqttjs:client _setupStream: sending packet `connect` +1ms
  mqttjs:client sendPacket :: packet: { cmd: 'connect' } +0ms
Red-Asuka commented 1 month ago

Thank you for your feedback. We have confirmed that this is a bug and it will be fixed in the next version.

Red-Asuka commented 1 month ago

This bug has already been addressed in a recent Pull Request. We will roll out the updated version as promptly as possible.

jason-grimme commented 1 month ago

Thank you team, this is great news. Is it expected that I wait until release is available to close this issue? Or do you close?

ysfscream commented 1 month ago

We will test after the release and close the issue once it's confirmed that there are no problems. v1.10.0 will be come soon.

jason-grimme commented 1 month ago

I built from main 19d4e69 and confirmed that issue is resolved.

ysfscream commented 4 weeks ago

Updated to https://github.com/emqx/MQTTX/releases/tag/v1.10.0. Thanks for your feedback.