node-red-contrib-aedes
node-red-contrib-aedes copied to clipboard
Aedes over mTLS
Hi,
I am trying to use aesed on nodered with an mTLS connection. The only port that can be used is the https port so connection will be over websockets.
so I expect that I can connect to the broker on: wss://my.domain.com/ws/mqtt
I created a nodejs client to connect like this:
import mqtt from "mqtt";
import fs from "fs";
const protocol = "wss";
const host = "my.domain.com/ws/mqtt";
const port = "443";
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`;
const connectUrl = `${protocol}://${host}:${port}`;
// certs for mtls
var caFile3 = fs.readFileSync("./certs/ISRoot.crt");
var certFile = fs.readFileSync("./certs/client_cert.pem");
var keyFile = fs.readFileSync("./certs/client_key.pem");
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
ca: [caFile3],
cert: certFile,
rejectUnauthorized: true,
key: keyFile,
connectTimeout: 4000,
reconnectPeriod: 1000,
});
client.on("connect", () => {
console.log("Connected");
});
client.on("error", (err) => {
console.log("Connection error: ", err);
client.end();
});
client.on("reconnect", (error) => {
console.log("Reconnecting...");
});
The result in the console is always: Reconnecting ...
When we deploy a simple nodejs program with aedes broker in stead of the nodered application, the connection over mTLS is working.
code of the simple nodejs broker:
import Aedes from "aedes";
import { createServer } from "http";
import ws from "websocket-stream";
const httpServer = createServer();
const port = process.env.PORT || 8888;
const aedes = new Aedes();
// emitted when a client connects to the broker
aedes.on("client", function (client) {
console.log(
`[CLIENT_CONNECTED] Client ${
client ? client.id : client
} connected to broker ${aedes.id}`
);
});
// emitted when a client disconnects from the broker
aedes.on("clientDisconnect", function (client) {
console.log(
`[CLIENT_DISCONNECTED] Client ${
client ? client.id : client
} disconnected from the broker ${aedes.id}`
);
});
// emitted when a client subscribes to a message topic
aedes.on("subscribe", function (subscriptions, client) {
console.log(
`[TOPIC_SUBSCRIBED] Client ${
client ? client.id : client
} subscribed to topics: ${subscriptions
.map((s) => s.topic)
.join(",")} on broker ${aedes.id}`
);
});
// emitted when a client unsubscribes from a message topic
aedes.on("unsubscribe", function (subscriptions, client) {
console.log(
`[TOPIC_UNSUBSCRIBED] Client ${
client ? client.id : client
} unsubscribed to topics: ${subscriptions.join(",")} from broker ${
aedes.id
}`
);
});
// emitted when a client publishes a message packet on the topic
aedes.on("publish", async function (packet, client) {
if (client) {
console.log(
`[MESSAGE_PUBLISHED] Client ${
client ? client.id : "BROKER_" + aedes.id
} has published message on ${packet.topic} to broker ${aedes.id}`
);
}
});
ws.createServer({ server: httpServer }, aedes.handle);
httpServer.listen(port, function () {
console.log("websocket server listening on port ", port);
});
What are we missing in the nodered configuration to run the mqtt broker over websockets and mTLS?
kr, Joachim
I think you need to enable SSL/TLS including server certificates in order to setup a secure connection. What error messages do you get in the Node-RED logs?