MQTT TLS 连接

发布于 2025-01-10 21:58:52 字数 1626 浏览 0 评论 0原文

我想将测试 MQTT-Client 作为 MQTT-Broker 连接到我的 Node.js 应用程序。我正在使用 moscajs 中的 aedes 库

我的 MQTT-Client 是工具“MQTT-Explorer”,在这里是我的 Node.js 应用程序:

const fs = require('fs');
const aedes = require('aedes')();

const options = {
  key: fs.readFileSync('certs/server_key.pem'),
  cert: fs.readFileSync('certs/server_cert.pem'),
};

// const server = require('net').createServer(aedes.handle);
const server = require('tls').createServer(options, aedes.handle);

const PORT = 8881;

server.listen(PORT, () => {
  console.log(`server is up and running: PORT [${PORT}] - ID [${aedes.id}]`);
});

我可以使用 const server = 毫无问题地连接到 PORT=1881 require('net').createServer(aedes.handle) 我还可以使用 const server = require('tls').createServer(options) 连接到 PORT=8881 , aedes.handle)

使用工具 xca-2.4.0.msi XCA 2.4.0 我创建了一个 ca.pem 证书文件和一个证书 server_cert.pem 以及一个 server_key.pem 私钥(从 ca.pem 签名)作为服务器。 CA 和服务器的密钥不同:

XCA

对于我的 MQTT 客户端,在 ADVANCED、CERTIFICATES、SERVER CERTIFICAT (CA) 下,我选择了ca.pem 文件。如果我选择“加密”,它就会起作用。但如果选择“验证证书”,则会出现错误:主机名/IP 与证书的替代名称不匹配:IP:127.0.0.1 不在证书列表中

MQTT Explorer

不幸的是我不知道什么我做错了,提前谢谢:(

I would like to connect a test MQTT-Client to my Node.js application as a MQTT-Broker. I am using the aedes library from moscajs

My MQTT-Client is the tool "MQTT-Explorer" and here is my Node.js application:

const fs = require('fs');
const aedes = require('aedes')();

const options = {
  key: fs.readFileSync('certs/server_key.pem'),
  cert: fs.readFileSync('certs/server_cert.pem'),
};

// const server = require('net').createServer(aedes.handle);
const server = require('tls').createServer(options, aedes.handle);

const PORT = 8881;

server.listen(PORT, () => {
  console.log(`server is up and running: PORT [${PORT}] - ID [${aedes.id}]`);
});

I can connect without any problems to PORT=1881 with const server = require('net').createServer(aedes.handle) and I also can connect to PORT=8881 with const server = require('tls').createServer(options, aedes.handle)

With the Tool xca-2.4.0.msi XCA 2.4.0 I have created a ca.pem CERTIFICATE File and a CERTIFICATE server_cert.pem and a server_key.pem PRIVATE KEY (signed from ca.pem) as a Server. The key for CA and the Server are different:

XCA

For my MQTT-Client, under ADVANCED, CERTIFICATES, SERVER CERTIFICAT (CA) I selected the ca.pem File. If I select "Encryption", it works. But if select "validate certificate", error: Hostname/IP does not match certificate's altnames: IP: 127.0.0.1 is not in the certs list

MQTT Explorer

Unfortunately I don't know what I'm doing wrong, thanks in advance :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥有 2025-01-17 21:58:52

MQTT Explorer 使用 Node.js 和 MQTT 库 MQTT.js。根据此问题

Node.js 要求 IP 地址位于证书的 subjectAltNames 中,而不是 CN 中。也许 MQTT.fx 不需要这样做,但它应该这样做。

和:

如果您的服务器证书在主题字段中显示 CN=localhost,请使用 localhost 而不是 127.0.0.1 进行连接,它应该可以工作。如果显示 CN=127.0.0.1,则必须创建一个新地址,因为 Node.js 不会验证 IP 地址,除非它位于 SAN 扩展中。有一种方法可以在代码中解决这个问题(我认为这是一个名为 checkServerIdentity 的选项),但如果遇到此问题,我更愿意修复我的证书。

此答案中阐述了 Node 中采用的方法的基本原理,其中包括来自 RFC2818:基于 TLS 的 HTTP

在某些情况下,URI 被指定为 IP 地址而不是主机名。在这种情况下,iPAddress subjectAltName 必须出现在证书中,并且必须与 URI 中的 IP 完全匹配。

当您使用基于 TLS 的 MQTT(而不是基于 TLS 的 HTTP)时,您可能会认为上述内容不适用,但是考虑到 TLS 库的主要用途是用于 HTTP 流量,因此它通过以下方式向 RFC 确认是有意义的:默认。

您有几个选项,包括:

  • 创建证书/连接时使用主机名(例如 localhost)而不是 IP。
  • 添加 IP 作为 subjectAltName
  • 修改库以使用 noop checkServerIdentity (请参阅此答案) 。
  • 使用另一个应用程序进行测试(不真正推荐,因为有些应用程序可以工作,而另一些则不能)。上面引用的问题提到 MQTT.fx 可以工作。

MQTT Explorer is built using Node.js and the MQTT library MQTT.js. As per this issue:

Node.js requires the IP address to be in the subjectAltNames for the cert and not in the CN. Maybe MQTT.fx isn't requiring that, but it should.

and:

If your server's certificate says CN=localhost in the Subject field, connect using localhost and not 127.0.0.1 and it should work. If it says CN=127.0.0.1, you have to make a new one because Node.js won't validate the IP address unless it's in the SAN extension. There is a way to work around it in code (I think it's an option called checkServerIdentity), but I would prefer to fix my certificate if I had this problem.

A rationale for the approach taken in Node is set out in this answer which includes the following quote from RFC2818: HTTP Over TLS
:

In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI.

As you are using MQTT over TLS (as opposed to HTTP Over TLS) you could argue that the above does not apply but, given that the main use of the TLS library is for HTTP traffic, it makes sense that it confirms to the RFC by default.

You have a few options including:

  • Use a hostname (e.g. localhost) rather then an IP when creating the certificate/connecting.
  • Add the IP as a subjectAltName
  • Modify the library to use a noop checkServerIdentity (see this answer).
  • Use another application for testing (not really recommended as some applications will work and others will not). The issue quoted above mentions that MQTT.fx works.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文