thingsboard / tbmq

Open-source, scalable, and fault-tolerant MQTT broker able to handle 4M+ concurrent client connections, supporting at least 3M messages per second throughput per single cluster node with low latency delivery. The cluster mode supports more than 100M concurrently connected clients.
https://thingsboard.io/products/mqtt-broker/
Apache License 2.0
570 stars 46 forks source link

How do I enable SSL Bidirectional authentication? #97

Closed GeXin666 closed 7 months ago

GeXin666 commented 7 months ago

I set config "SECURITY_MQTT_SSL_ENABLED:true",I want to enable SSL bidirectional authentication。

thingsboard-mqtt-broker.yml cert_file: my_server_cert.crt key_file: my_server_key.key

Where is caRootCert configured?

Component

GeXin666 commented 7 months ago
   @Override
    public void checkClientTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
        // think if better to add credentials validation here
        //System.out.println("checkClientTrusted" + Arrays.toString(chain) + "authType:" + authType);
        //trustManager.checkClientTrusted(chain, authType);
         Why is the client certificate check logic removed?
    }
dmytro-landiak commented 7 months ago

Hi @GeXin666!

The cert_file (LISTENER_SSL_PEM_CERT) config should be used in this case. You need to form the certificate chain in the following way:

image

After that, create MQTT client credentials of the type "X.509 Certificate Chain". The validation is done within SslMqttClientAuthProvider class. I will review once again the logic and the mentioned method checkClientTrusted.

GeXin666 commented 7 months ago

thank you! Here's what I did

The cert_file (LISTENER_SSL_PEM_CERT) is -----BEGIN CERTIFICATE----- rootCa.crt(x509) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- serverCa.crt(x509) -----END CERTIFICATE-----

modified class ThingsboardMqttX509TrustManager @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // think if better to add credentials validation here trustManager.checkClientTrusted(chain, authType); }

modified class AbstractMqttHandlerProvider SSLEngine sslEngine = sslContext.createSSLEngine(); sslEngine.setUseClientMode(false); sslEngine.setNeedClientAuth(true); //here set is true //sslEngine.setWantClientAuth(false); I annotated it here This will allow for two-way authentication

dmytro-landiak commented 7 months ago

@GeXin666, thank you for the provided info and your examples. I think it will be useful to make it configurable (i.e. sslEngine.setNeedClientAuth(needClientAuth); and sslEngine.setWantClientAuth(wantClientAuth); or something similar). This will be considered for change and improvement.

GeXin666 commented 7 months ago

Thanks to open Source for such an excellent project, I have learned a lot of knowledge