HiveMQ

MQTT Authentication relies on TLS cache problem

Scenario:

  • A device send CONNECT message to HiveMQ broker with wrong credentials over TLS. Clean Session Flag is set to 1
  • HiveMQ broker sends CONNACK back to client with Return Code Response is 0x05
  • The device reconnect again with valid credentials. However, HiveMQ broker continues to refuse connection by sending CONNACK back to client with Return Code Response is 0x05. The ISSUE is here

If I reset device and then connect with valid credentials, the device connected to the broker successfully. The HiveMQ broker returns “0x00 Connection Accepted” in CONNACK .

I think that HiveMQ broker ignores the authentication result from extension and uses the cache information in TLS to decide whether device is authenticated or not (when reconnecting)

I used the HiveMQ extension, I am able to know that in the re-connection, my extension worked well.

Could you please tell me how to solve it?

Thank you in advance,
Best regards,

Hello!

Would you be so kind and share more details about the setup you are testing with?
Are you using the latest version of HiveMQ. Which extensions are being loaded?

May we see an excerpt of your config.xml?
The and section are of particular interest.

Any relevant log output would also be helpful.

Regards,
Finn from the HiveMQ team

Dear zingiber,

Thank you for answering.

I used hivemq-ce-2019.1

I used client certificates. I debug and there is no problem with certificate validation in all cases. I also do extra authentication in upper layer (MQTT layer). Problem happens here. Extension is developed by myself. I am able to write debugging message.

The important code in my authenticator:

if (isAuthenticated) {
	output.authenticateSuccessfully();
	log.info("Authentication Extension>> " + clientID + ": authenticateSuccessfully");
} else {
	output.failAuthentication(reasonCode, reasonString);
	log.info("Authentication Extension>> " + clientID + ": " + reasonString);
}

The log is complicated, therefore, I summarizes it.

In the scenario I mentioned in the post:

  • The first CONNECT message, the log indicated that isAuthenticated == false => Connection Refused (see in client) => It is normal.
  • The next CONNECT messages, the log indicated that isAuthenticated == true => Connection SHOULD be accepted. However, Connection is still Refused (see in client). it is abnormal.

If I reset device (all cache in device is deleted) and set isAuthenticated = true, Connection Accepted

Note that in the above, I do NOT reboot server or extension. Extension get isAuthenticated variable from other source that I can control.

I guess the problem is related to TLS session resumption . I think the MQTT broker should be independent with TLS cache.

The below is my config.xml

<?xml version="1.0"?>
<hivemq>

	<listeners>

		<tls-tcp-listener>
			<port>8883</port>
			<bind-address>0.0.0.0</bind-address>
			<tls>
				<keystore>
					<!-- Configuring the path to the key store -->
					<path>/opt/hivemq-ce-2019.1/conf/certs/mykeystore.jks</path>
					<!-- The password of the key store -->
					<password>************</password>
					<!-- The password of the private key -->
					<private-key-password>**********</private-key-password>
				</keystore>
				<truststore>
					<!-- Configuring the path to the key store -->
					<path>/opt/hivemq-ce-2019.1/conf/certs/ca.truststore.jks</path>
					<!-- The password of the key store -->
					<password>***********</password>
				</truststore>
				<client-authentication-mode>REQUIRED</client-authentication-mode>
				<cipher-suites>
					<cipher-suite>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</cipher-suite>
					<cipher-suite>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</cipher-suite>
				</cipher-suites>
				<protocols>
					<protocol>TLSv1.2</protocol>
				</protocols>
				<native-ssl>true</native-ssl>
			</tls>
		</tls-tcp-listener>

	</listeners>

	<anonymous-usage-statistics>
		<enabled>true</enabled>
	</anonymous-usage-statistics>

</hivemq>