0

I use this code to connect to my own mqtt broker with socket from Nextjs and it works fine

import mqtt, { MqttClient } from "mqtt";
//...
mqtt.connect("ws://IPADDRESS:1884");
//....

Now, I want to change it to secure websocket (wss) and I have CRT file, but don't know how to add it.

import mqtt, { MqttClient } from "mqtt";
//...
mqtt.connect("wss://IPADDRESS:1884");
//....
JohnS
  • 204
  • 1
  • 2
  • 10
  • First point. You can't just change `ws://` to `wss://` without changing the port number as well. The broker can not service both on the same port. Second, it's not clear what you are trying to do, is the `crt` file to identify the client or to verify the broker? – hardillb Feb 17 '23 at 13:21
  • The site is https and if I use ws it tries to connect to wss and I can't to force it to connect to ws – JohnS Feb 17 '23 at 15:11
  • 1
    Yes, the browser sandbox will not allow sites loaded over HTTPS to connect to anything that is not also secure. But if this is in the browser there on way to use a `crt` file, you must import it into the certificate store in the browser (for ALL browsers that will ever try to access the site). The correct solution is use a https/wss certificate issued by a public trusted CA – hardillb Feb 17 '23 at 15:16
  • For example, if the website URL is test.com, I should get a valid certificate for test.com, right? Can't use ws in https site at all? – JohnS Feb 17 '23 at 15:23

2 Answers2

1

As hashed out in the comments.

  1. You can not load unsecure content from a page loaded over HTTPS. This means if the page loads over https://, then the WebSocket Connection must be wss://

  2. The browser will not ask you to approve a self signed or untrusted certificate when making WebSocket connections like it does when trying to navigate to HTTPS site with a certificate not signed by a trusted CA.

You have 2 choices

  1. You manually import your self signed certificate into the browsers trust store. This is only a valid option for dev/test as it would need be done to ALL browsers that ever access the site.
  2. You get a certificate from a trusted CA (e.g. LetsEncrypt) and use for both the HTTP server and the Broker (or you get get something like Nginx to proxy for the broker and to TLS termination for both)
hardillb
  • 54,545
  • 11
  • 67
  • 105
  • Thank you for your response, I bought a valid SSL certificate for my website, but don't know how to use it for websocket, because I just have one file (.crt file) and install it on IIS, but for websocket needs three files according to this tutorial https://medium.com/jungletronics/bulletproof-tls-ssl-mosquitto-e662c62a269b – JohnS Feb 17 '23 at 15:32
  • Without knowing what's in the crt file I can only guess (do not post it as that will most likely leak your private key) that it actually pkcs12 file that holds the key, cert and cacerts. I suggest you look at https://stackoverflow.com/questions/9497719/extract-public-private-key-from-pkcs12-file-for-later-use-in-ssh-pk-authenticati for suggestions on how to extract the content of the file. The other option is that it is just the key and cert in pem format concatenated and you can split them up with a text editor. But without knowing exactly what is in your crt file we can't say anything else. – hardillb Feb 17 '23 at 15:40
  • (just as an aside, you only need a certificate file and private key file to setup mosquitto) – hardillb Feb 17 '23 at 15:44
1

You can use the same certificate that you used for the website, using it for the web socket too. For example, if the website URL is https://test.com you should connect to test.com with wss (wss://test.com:1884) and use the same SSL certificate in your brocker. For the Mosquitto the config file should be like below.

listener 1883

allow_anonymous true


listener 1884
protocol websockets
socket_domain ipv4

cafile C:\Program Files\mosquitto\cert\ca.crt
keyfile C:\Program Files\mosquitto\cert\server.key
certfile C:\Program Files\mosquitto\cert\server.crt
tls_version tlsv1.2

The port 1883 use for Mqtt connection without TLS, for web socket use port 1884 and it needs SSL certificate.

The certificate files should be on the server, they are:

ca.crt is the CA file of your SSL certificate

server.key is the private key

server.crt is the CRT file of your SSL certificate

When you connect to the web socket from your website because it is HTTPS and you connect to the same URL for the web socket, it uses the same SSL certificate and doesn't need to import it to the browser.

SajjadZare
  • 2,487
  • 4
  • 38
  • 68