0

I'm using Angular 14 and the ngx-mqtt front-end lib.

Here's my connection string which works fine:

getEmqxCloudConnection(): IMqttServiceOptions {       
    return {
        hostname: 'xx.xx.xx.182',
        port: 8083,
        path: '/mqtt',
        clean: true, // retain
        connectTimeout: 4000,
        reconnectPeriod: 4000,
        clientId: 'HarBrowserTest1',
        username: 'myUser',
        password: 'myPass',
        protocol: 'ws',
        connectOnCreate: false,
    };
}

As per their Broker dashboard the available ports are:

Ports: 1883(mqtt), 8883(mqtts), 8083(ws), 8084(wss)

I have already imported our SSL Certificate into the EMQX Dashboard, yet when I change my conn string to port: 8084 and protocol: 'wss' - IT DOESN'T CONNECT !

enter image description here enter image description here

They have some screenshots here showing their Client Tool, but for reason every one shows port=1883 (a mistake maybe). https://docs.emqx.com/en/cloud/latest/connect_to_deployments/mqttx.html#connection-configuration

In my Chrome browser network tab, here's what I see for the std insecure ws - A successful ws conn to the Mqtt Broker.

enter image description here

enter image description here

enter image description here

Here is the certificate UI which I used to imported the PEM-Encoded cert body and key: enter image description here

enter image description here

*********** UPDATE **************

As per comment down below, binding the IP to your domain was the final solution which allowed us to connect over wss`. (e.g. emqx.my-domain.com)

bob.mazzo
  • 5,183
  • 23
  • 80
  • 149

3 Answers3

2

This will most likely be down to the certificate you have used for the broker.

First unless you have created the certificate just right (using the correct SAN entries) that include the IP address as the principal for the certificate, then the connection will get rejected because the certificate doesn't match the hostname/IP address the broker is using to connect.

Second, if it is a self signed certificate then the browser will just reject it, unless you have manually imported the CA (or if it really is self signed the cert it's self) into the browsers trust store and marked it as trusted. The browser will NOT show you a warning and ask to accept for a WebSocket connection like it does with a webpage, it will just fail with an error in the console and nothing else.

P.S. - You should not hard code the client id in web apps, this is because client ids must be unique across ALL clients, so hardcoding it means that everybody that visits the page will use the same client id and each new connection will kick off the last one (and probably end up in a reconnect fight)

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • yes it's true about the ClientID. I'm the only one in my company testing this right now, so I figured it was okay. However, I'll take your advice and generate a random one each time in my ts code. In terms of the digi cert, it's the same one we are using for our Azure test websites - so it is trusted; and yes, I have manually imported the certificate using the EMQX Broker Dashboard. It essentially required a PEM-Encoded Cert Body and Private Key. I was able to generate both of them using the OpenSSL tool on my box. – bob.mazzo Feb 13 '23 at 22:31
  • But does the cert have the right entries for the IP address you are using to test? The even if the browser has been told to trust it, it will still not accept it if it doesn't match properly – hardillb Feb 13 '23 at 22:49
  • I'll start from scratch in terms of importing the cert. I also reached out to EMQX support for this. – bob.mazzo Feb 13 '23 at 23:32
1

If you check the logs of EMQX, maybe you can get more helpful information.

The following are possible reasons for common TLS connection failures.

First of all, as mentioned in the previous answer, your certificate may have a domain name or IP address set as CN or SAN when it is issued, but the address you specified when connecting does not match the values of the CN and SAN fields.

In this case, the TLS client will think that the server you are connecting to may not be what you really expect, so it will refuse the connection.

We have three ways to solve it:

  1. Turn off the verification of the peer certificate, if your client has this option. However, we do not recommend this as it increases the security risk.
  2. Reissue a certificate that matches your server address
  3. Set the SNI field (full name Server Name Indication) when the client connects, so that TLS will check whether the SNI matches the CN and SAN fields of the certificate, instead of your actual connection address.

The second possible reason is that your certificate path is incomplete, such as the lack of intermediate certificates, or the client does not specify a trusted root certificate, its keyword in the EMQX log is unknown_ca.

For more TLS error reasons, you can refer to SSL Connection Error.

t1ger
  • 26
  • 1
  • the only log entry I always see is a username error - 2023-02-15 13:07:44 (UTC-05:00)[emqx-node-2] Warning CENSYS@167.248.133.119:43684 [Channel] Client CENSYS `(Username: 'undefined') login failed for not_authorized` - I can connect, however, via an insecure 8083 ws port. – bob.mazzo Feb 15 '23 at 19:34
  • In fact, this is a good sign. CENSYS is an Internet detection and scanning tool that periodically scans the IP address space and detects the default ports of protocols such as HTTP, SSH, and MQTT. If you see this log, it just means that your EMQX has intercepted these unknown clients. You can add the CENSYS client to the blacklist, so that the warning log will not appear again. – t1ger Feb 19 '23 at 12:23
1

In a browser environment, you should use a server certificate issued by a CA Signed than a self-signed certificate.

Self-Signed SSL Vs Trusted CA Signed SSL Certificate, see the https://cheapsslsecurity.com/blog/self-signed-ssl-versus-trusted-ca-signed-ssl-certificate/

enter image description here enter image description here

Eds_k
  • 944
  • 10
  • 12
  • 1
    You will also need to resolve the domain name to an ip address and connect using the domain name instead of the ip address. – Eds_k Feb 14 '23 at 02:32
  • Okay so that EMQX IP binding to our domain name has to be done on my side, right? And NOT thru the EMQX Broker interface...in their docs I see this example explanation: "Point the A record from mqtt.abc.com to 123.123.123.123 in your domain setting panel." – bob.mazzo Feb 15 '23 at 18:40
  • our GoDaddy cert is CA Signed. I checked with a colleague, and we verify the IIS certifcates - `CN = Go Daddy Secure Certificate Authority - G2 OU = http://certs.godaddy.com/repository/ O = GoDaddy.com, Inc. ` – bob.mazzo Feb 15 '23 at 20:36
  • 1
    Yes, you need to add your own domain name resolution records – Eds_k Feb 16 '23 at 01:31
  • You can submit a ticket to EMQX Cloud and they will give you more professional support. – Eds_k Feb 16 '23 at 01:32
  • thanks, I already submitted a ticket. Your answer here matches their response to my issue. – bob.mazzo Feb 16 '23 at 16:36
  • if you can please put the `binding IP` suggestion into your answer above, I will check it as answered. That was the final solution in getting tls/ssl to work over wss. – bob.mazzo Feb 17 '23 at 16:37