I try to secure-connect to mosquitto with MQTT.js (https://www.npmjs.com/package/mqtt) and I always get the following error:
node.js
Error: self-signed certificate in certificate chain
at TLSSocket.onConnectSecure (node:_tls_wrap:1677:34)
at TLSSocket.emit (node:events:518:28)
at TLSSocket._finishInit (node:_tls_wrap:1076:8)
at ssl.onhandshakedone (node:_tls_wrap:862:12) {
code: 'SELF_SIGNED_CERT_IN_CHAIN'
}
mosquitto
1749810067: New connection from 127.0.0.1:52519 on port 8883.
1749810067: OpenSSL Error[0]: error:0A000126:SSL routines::unexpected eof while reading
1749810067: Client <unknown> disconnected: protocol error.
It is somehow clear that there's a self-signed certificate
in the chain - the root-CA
- so I find that error message weird...
Maybe I understand something wrong?
I created a own certificate chain which I also verified via openSSL
. Also two-way TLS connecting using MQTTX (https://mqttx.app/) works without any problem so I guess my certificates + chain is fine.
Verified with openSSL and working great when using MQTTX.
For mosquitto I combined the intermediate.crt
and the ca.crt
to one ca_all.crt
.
listener 8883
protocol mqtt
cafile ca_all.crt
certfile server.crt
keyfile server.key
allow_anonymous true
require_certificate true
this._mqttClient = await mqtt.connectAsync(
'mqtts://localhost:8883',
{
protocol: 'mqtts',
caPaths: 'ca_all.crt',
certPath: 'client.crt',
keyPath: 'client.key',
});
OK
intermediate.crt
,ca.crt
] as sting[] -> NOK
ca_all.crt
as string -> NOK
NODE_EXTRA_CA_CERTS
as system variable pointing to ca_all -> NOK
I'm happy for every hint which could make this work! Thanks in advance.
Similar issue nodejs - error self signed certificate in certificate chain
This issue seems to be similar but the solutions are not applicable for my use case.
The files must be read and then passed to ca, cert and key
of the options.
NodeJS does not take paths to certificates or keys, you need to pass the actual content e.g.
const { readFileSync } = require('node:fs');
this._mqttClient = await mqtt.connectAsync(
'mqtts://localhost:8883',
{
protocol: 'mqtts',
ca: [readFileSync('ca_all.crt')],
cert: readFileSync('client.crt'),
key: readFileSync('client.key'),
});
Also NODE_EXTRA_CA_CERTS
needs to be a Environment variable in scope for the process, it is only read once at startup, so you can not set it using process.env.NODE_EXTRA_CA_CERTS='/path/to/file.crt'