EMQX5.0.3部署在AWS服务器上开启SSL认证和客户端MQTTX连接测试

以下问题该怎么解决?或者说使用AWS 的LB TLS总结,应该如何配置?

环境

  • EMQX 版本:5.0.3
  • 操作系统版本:Ubuntu 16.04.7 LTS

重现此问题的步骤

1、在AWS上配置ALB,并创建目标组: 协议 http 端口1883,Health checks 这边的路径怎么填写?
2、在ALB上,添加监听:将Https 8883端口转发到 目标组 http 1883,使用的证书是AWS申请的公有证书。
3、MQTTX客户端配置连接

实际行为

连接时:MQTTX 弹出:Error: self signed certificate in certificate chain

MQTTX失败日志
[2023-02-27 17:48:18] [INFO] deviceHttps connect close, MQTT.js onClose trigger
[2023-02-28 09:50:28] [INFO] deviceHttps was edited, ID: 8c8f23c2-d4ed-4da4-928a-3d6ba4288fda
[2023-02-28 09:50:28] [INFO] MQTTX client with ID 8c8f23c2-d4ed-4da4-928a-3d6ba4288fda assigned
[2023-02-28 09:50:28] [INFO] Connect client deviceHttps, MQTT/SSL connection: mqtts://54.173.75.113:8883 with Properties: {“sessionExpiryInterval”:0,“receiveMaximum”:null,“maximumPacketSize”:null,“topicAliasMaximum”:null,“requestResponseInformation”:null,“requestProblemInformation”:null,“authenticationMethod”:null}
[2023-02-28 09:50:29] [ERROR] deviceHttps connect fail, MQTT.js onError trigger, Error: self signed certificate in certificate chain
at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
at TLSSocket.emit (events.js:315:20)
at TLSSocket._finishInit (_tls_wrap.js:932:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12)
[2023-02-28 09:50:29] [INFO] deviceHttps connect close, MQTT.js onClose trigger

1883 和 8883 都是 MQTT 的端口,连接报错看起来是 TLS 证书检查没过。你可以把 CA signed server
改成 Self signed,然后手动指定信任的根 CA 证书再试试。

可能你的根 CA 证书不在操作系统默认信任列表里面。

我这个测试,应该是单向认证的是吧?服务器端在AWS那边,用的是ALB,然后证书申请的是公有证书,没地方下载好像。

是的,是单向认证。也可以先看下 EMQX 这边的后台日志,看看是不是没有指定根 CA 证书的原因。

emqx.log.zip (733.0 KB)
这是服务端日志,帮忙看下

你好,看日志的话 1883 端口收到的都是 HTTP 请求。

2023-03-01T01:24:58.615749+00:00 [error] at_state: <<"clean">>, input_bytes: <<"GET / HTTP/1.1\r\nHost: 172.31.8.83:1883\r\nConnection: close\r\nUser-Agent: ELB-HealthChecker/2.0\r\nAccept-Encoding: gzip, compressed\r\n\r\n">>, line: 783, mfa: emqx_connection:parse_incoming/2, parsed_packets: [], peername: 172.31.86.27:33128, reason: function_clause, stacktrace: [{emqx_frame,parse_packet,[{mqtt_packet_header,4,false,3,true},<<"T / HTTP/1.1\r\nHost: 172.31.8.83:1883\r\nConnection: close\r\nUser-Agent: ">>,#{max_size => 1048576,strict_mode => false,version => 4}],[{file,"emqx_frame.erl"},{line,258}]},{emqx_frame,parse_frame,4,[{file,"emqx_frame.erl"},{line,231}]},{emqx_connection,parse_incoming,3,[{file,"emqx_connection.erl"},{line,761}]},{emqx_connection,handle_msg,2,[{file,"emqx_connection.erl"},{line,740}]},{emqx_connection,process_msg,2,[{file,"emqx_connection.erl"},{line,466}]},{emqx_connection,handle_recv,3,[{file,"emqx_connection.erl"},{line,428}]},{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]
2023-03-01T01:24:59.710971+00:00 [error] at_state: <<"clean">>, input_bytes: <<"GET / HTTP/1.1\r\nHost: 172.31.8.83:1883\r\nConnection: close\r\nUser-Agent: ELB-HealthChecker/2.0\r\nAccept-Encoding: gzip, compressed\r\n\r\n">>, line: 783, mfa: emqx_connection:parse_incoming/2, parsed_packets: [], peername: 172.31.10.182:44642, reason: function_clause, stacktrace: [{emqx_frame,parse_packet,[{mqtt_packet_header,4,false,3,true},<<"T / HTTP/1.1\r\nHost: 172.31.8.83:1883\r\nConnection: close\r\nUser-Agent: ">>,#{max_size => 1048576,strict_mode => false,version => 4}],[{file,"emqx_frame.erl"},{line,258}]},{emqx_frame,parse_frame,4,[{file,"emqx_frame.erl"},{line,231}]},{emqx_connection,parse_incoming,3,[{file,"emqx_connection.erl"},{line,761}]},{emqx_connection,handle_msg,2,[{file,"emqx_connection.erl"},{line,740}]},{emqx_connection,process_msg,2,[{file,"emqx_connection.erl"},{line,466}]},{emqx_connection,handle_recv,3,[{file,"emqx_connection.erl"},{line,428}]},{proc_lib,wake_up,3,[{file,"proc_lib.erl"},{line,236}]}]

1、以上这些日志,应该是AWS创建1883目标组时,填写的“health check”检测时,检查失败,就一直检查。
2、另外,我使用 tailf emqx.log.6 监测日志,然后同步在客户端点击连接,后台并未出现日志信息。
3、这个问题,会不会出现在AWS的ALB功能上?目前是ALB监听https 8883,然后“Forward to” 目标组http 1883。但是AWS创建目标组时,需要做端口的“health check”,填写端口的路径,并能得到接口的返回,如下图:

健康检查应该请求 18083 端口才对,1883 和 8883 都是 MQTT 的端口。

文档介绍是:推荐在 LB 终结 SSL/TLS 连接:设备与 LB 之间采用 SSL/TLS 安全连接,LB 与 EMQX 之间普通 TCP 连接。
这个就是单向认证,对于客户端来说,也是开启SSL认证,我理解没错吧?

是的,你理解是对的

嗯,那我这个问题应该要怎么解决,可以帮忙分析一下不?
目前在AWS上配置的方向是对的吗?如果方向对的话,那个目标组的“health check”要怎么配置?

你那个 Health check 的配置肯定是错的,虽然我不太了解 AWS 的这个健康检查会做什么事情,但如果是连接到 1883 端口的话,那肯定不能是用 HTTP 协议。

或者您这边知道咱们EMQX服务在AWS的ALB配置SSL,是怎么操作的吗?

AWS 的 ALB 我不是太了解,你可以看下它的这个文档:Health checks for your target groups

EMQX 提供的健康检查端点为:http://<Your Host>:18083/status,你也可以直接执行 curl http://localhost:18083/status 看下。

你应该需要让 ALB 请求上面这个 URL。

这个 API 目前没有暴露在文档中,我们会安排下文档更新。

好的,非常感谢解答,我这边继续试试。

请问1883端口有健康监测的路径吗?AWS创建的目标组,每个端口都需要健康检测。

这个没有单独的健康检测手段,你可以直接搞一个 MQTT 客户端连接来判断端口是否正常

[2023-03-01 14:40:38] [INFO] deviceHttps connect close, MQTT.js onClose trigger
[2023-03-01 14:41:42] [INFO] MQTTX client with ID 8c8f23c2-d4ed-4da4-928a-3d6ba4288fda assigned
[2023-03-01 14:41:42] [INFO] Connect client deviceHttps, MQTT/SSL connection: mqtts://54.173.75.113:8883 with Properties: {"sessionExpiryInterval":0,"receiveMaximum":null,"maximumPacketSize":null,"topicAliasMaximum":null,"requestResponseInformation":null,"requestProblemInformation":null,"authenticationMethod":null}
[2023-03-01 14:41:43] [ERROR] deviceHttps connect fail, MQTT.js onError trigger, Error: self signed certificate in certificate chain
    at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
    at TLSSocket.emit (events.js:315:20)
    at TLSSocket._finishInit (_tls_wrap.js:932:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12)
[2023-03-01 14:41:43] [INFO] deviceHttps connect close, MQTT.js onClose trigger

都是提示这种出错,单向认证,咱们MQTTX客户端,不行配置什么证书吧?客户端配置如下:

你应该是需要指定一下根 CA 证书

客户端指定根证书吗,有没通用的根证书?后台是AWS上申请的公有证书,是没办法下载的。