Hello. I set up an MQTT broker cluster on AWS as explained here: Building an elastic high availability MQTT broker cluster on AWS. Then I wanted to implement mutual TLS authentication. I have a RootCA, a BrokerCA and a ClientCA that are both signed by RootCA. Actual broker certificates are signed by intermediate BrokerCA and client ones are signed by ClientCA (RootCA → BrokerCA → broker and RootCA → ClientCA → client). After having generated all certificates, what I did was:
- Creating broker keystore, with a broker certificate signed by intermediate BrokerCA (common name set to Cluster Load Balancer DNS name):
keytool -import -file ~/myCA/brokerCA/certs/hivemq.cert.pem -alias hivemq -keystore hivemq-keystore.jks -storepass password -storetype JKS
- Creating broker truststore, with ClientCA certificate (Broker has to accept only certificates signed by ClientCA)
keytool -import -file ~/myCA/clientCA/certs/client.cert.pem -alias client -keystore hivemq-truststore.jks -storepass password -storetype JKS
- Copying keystores into broker’s /opt/hivemq/conf directory, modifying /opt/hivemq/conf/config.xml accordingly and restarting hivemq daemon. At this point TLS listener is ready to accept connections, according to logs:
Enabled protocols for TCP Listener with TLS at address 0.0.0.0 and port 1883: [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1]
2023-06-26 22:13:26,723 INFO - Enabled cipher suites for TCP Listener with TLS at address 0.0.0.0 and port 1883: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384]
2023-06-26 22:13:26,725 INFO - Starting TLS TCP listener on address 0.0.0.0 and port 1883
2023-06-26 22:13:26,771 INFO - Started TCP Listener with TLS on address 0.0.0.0 and on port 1883.
- Now, i use mqtt cli to connect to the broker, specifying cafile as the BrokerCA cert file, that signed the hivemq broker, key as the private key of a certificate signed by the ClientCA that represents the current client, cert representing the certificate chain that contains a concatenation of current client certificate, ClientCA certificate and RootCA certificate (as suggested here: NOTE: *In production, we recommend using client and server certificates that are signed by a trusted CA or the internal CA of your company. To create individual client certificates for IoT devices, create an intermediary from your ROOT CA and sign individual certificates with this intermediary. Make sure that clients present the entire certificate chain on connection, this way, you only need to include your ROOT certificate in the HiveMQ truststore. *)
mqtt sub -t topic -q 1 -h HiveMQCluster-XXX.elb.eu-central-1.amazonaws.com -i client --cafile ~/myCA/brokerCA/certs/broker.cert.pem --key ~/myCA/clientCA/private/publisher.key.pem --cert ~/myCA/clientCA/certs/client-chain.cert.pem -d
CLIENT LOGS: failure: com.hivemq.client.mqtt.exceptions.ConnectionFailedException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
BROKER LOGS: SSL Handshake failed for client with ID UNKNOWN and IP X.X.X.X: no cipher suites in common
It works if I use the simple TLS configuration provided here Setting up TLS for your cloud-based MQTT broker, but does not If I use this setup.
Could you please help?