首页 > 解决方案 > Issues connecting to mosquitto broker with node mqtt client via SSL/TLS

问题描述

Helllo, I created a mosquitto broker via the eclipse docker image and recently followed this guide to add SSL/TLS support: http://www.steves-internet-guide.com/mosquitto-tls/.

When I am sshed in the VPS which is running the broker, I can use the command:

mosquitto_pub -h VPS_NAME -t test/topic -p 8883 --cafile ca.crt -m message -u BROKER_USERNAME -P BROKER_PASSWORD

and it publishes all fine and dandy. However when I run the same command on a local computer, I get the error:

'Unable to connect (Lookup error.).

I don't get any new logs from the broker container, so I think it's not even reaching the container. However when I run:

mosquitto_pub -h BROKER_IP_ADRESS -t test/topic -p 8883 --cafile ca.crt -m message -u BROKER_USERNAME -P BROKER_PASSWORD

I do get a response which is Error: A TLS error occured, and on my docker logs I get:

1583004287: New connection from LOCAL_IP_ADDRESS on port 8883.
1583004287: OpenSSL Error: error:14037438:SSL routines:ACCEPT_SR_KEY_EXCH:tlsv1 alert internal error
1583004287: OpenSSL Error: error:140370E5:SSL routines:ACCEPT_SR_KEY_EXCH:ssl handshake failure
1583004287: Socket error on client <unknown>, disconnecting.

I am only able to get a sucessful publish send when I add the --insecure command to the publish however I want to make sure the client knows that it's talking to the right server so I don't think this is the right solution.

In the end I want to run an mqtt client on a node application, I've tried this piece of code:


const fs = require('fs');

const optionsz = {
  ca: [ fs.readFileSync(__dirname + '/ca.pem') ],
  host: 'BROKER_IP_ADDRESS',
  servername: 'VPS_NAME',
  port: 8883,
  rejectUnauthorized : false,
  username : 'BROKER_USERNAME', // mqtt credentials if these are needed to connect
  password : 'BROKER_PASSWORD',
  clientId : 'test',
  // Necessary only if the server's cert isn't for "localhost".
  checkServerIdentity: () => { return null; },
};


class MqttHandler {
  constructor() {
    this.mqttClient = null;

  };


  connect() {
    // Connect mqtt with credentials (in case of needed, otherwise we can omit 2nd param)
    this.mqttClient = mqtt.connect(this.host, optionsz);
...

when I run this i keep getting disconnect events, and on my docker logs i get:

1583004505: New connection from LOCAL_IP_ADDRESS on port 8883.
1583004505: OpenSSL Error: error:140260FC:SSL routines:ACCEPT_SR_CLNT_HELLO:unknown protocol
1583004505: Socket error on client <unknown>, disconnecting.

I am really confused on how to even tackle this issue, I've been able to connect to a broker without SSL/TLS protection, but I wanted to make my device communication more secure. Thank you for your time!

标签: node.jssslmqtt

解决方案


2 separate problems here.

  1. Looks like you don't have a valid DNS entry for your VPS. mosquitto_pub is failing because it can't resolve the name to an IP address. It works with the --insecure and the IP address because you are telling mosquitto_pub to ignore the fact that the CN or SANs in the brokers certificate doesn't include the IP address only the name.

  2. You are trying to connect with raw MQTT not MQTT over TLS, you need to use a URL not just a hostname or the first argument of the connect() function. e.g.

    this.mqttClient = mqtt.connect("mqtts://" + this.host, optionsz);
    

To be honest you need to fix both of these to get things working properly.

To fix 1 you need to sort your DNS entries out so you have a valid fully qualified hostname that points to your VPS and matches the certificate you've deployed there.


推荐阅读