开启 SSL/TLS 连接
SSL/TLS 加密功能会在传输层对网络连接进行加密,它能在提升通信数据安全性的同时,保证数据的完整性。
本章节将向您详细介绍 SSL/TLS 加密连接的功能和优势以及在 EMQX 上开启 SSL/TLS 的步骤。
安全优势
启用 SSL/TLS 连接提供了以下安全优势:
- 强认证:开启 TLS 连接后,通讯双方将互相检查对方的身份,比如通过检查对方持有的 X.509 数字证书;这类数字证书通常是由受信机构 CA(Certificate Authority)颁发,不可伪造。
- 机密性:开启 TLS 连接后,每次会话都会根据双方协商得到的会话密钥进行加密。任何第三方都无法知晓通讯内容,因此即使一次会话的密钥泄露,也不影响其他会话的安全性。
- 完整性:加密通讯中的数据被篡改的可能性极低。
使用方式对比
您可以为包括 MQTT 在内的所有连接启用 SSL/TLS 加密连接,保证接入与消息传输安全。对于客户端的 SSL/TLS 连接,您可以根据使用场景选择以下两种使用方式之一:
| 使用方式 | 优势 | 缺点 |
|---|---|---|
| 在 EMQX 上开启 SSL/TLS | 简单易用,不需要额外的组件。 | 会增加 EMQX 的资源消耗,如果连接数量巨大,可能会导致较高的 CPU 和内存消耗。 |
| 通过代理或负载均衡终结 TLS 连接 | 不影响 EMQX 性能,同时提供了负载均衡能力。 | 需要额外部署 HAProxy、NGINX 或使用云厂商负载均衡服务,其中只有部分云厂商支持 TCP SSL/TLS 终结。 |
有关如何通过代理或负载均衡终结 TLS 连接,请参考集群负载均衡。
单/双向认证对比
EMQX 提供了非常完整的 SSL/TLS 能力支持,支持通过 X.509 证书实现单向和双向客户端/服务器互信认证:
| 认证方式 | 说明 | 验证方式 | 优缺点 |
|---|---|---|---|
| 单向认证 | 客户端验证服务器身份,但服务器不验证客户端的身份 | 客户端通常不需要提供证书,仅需验证服务器的证书是否由受信任的证书颁发机构(CA)签发 | 只能实现通信数据的机密性和完整性,但无法保证通信双方的身份 |
| 双向认证 | 服务器和客户端彼此验证对方的身份 | 需要为每个设备签发证书,服务器验证客户端的证书以确认其身份的合法性 | 可以确保服务器和客户端之间的互信关系,并防止中间人攻击 |
SSL/TLS 证书
在启用 SSL/TLS 连接之前,您需要准备 SSL/TLS 证书,用于对连接进行身份验证并保障通信安全。
EMQX 同时支持传统的基于文件路径的证书管理方式,以及托管证书(EMQX 6.1+)。托管证书提供集中化管理能力,可在多个监听器和连接器之间复用。
有关在 EMQX 中获取、管理和使用 SSL/TLS 证书的完整指南,包括托管证书的使用方式,请参阅 SSL/TLS 证书。
启用单向认证的 SSl/TLS 连接
默认情况下,EMQX 在端口 8883 上启用 SSL/TLS 监听器,并配置为单向认证模式,即:
- 客户端验证服务器证书
- 服务器不验证客户端证书
你可以通过 Dashboard 或配置文件来配置 SSL/TLS 监听器。在这两种方式下,EMQX 都支持以下两种证书提供方式:
- 基于路径的证书(传统 PEM 文件):在配置中通过文件路径直接引用证书文件。
- 托管证书(EMQX 6.1 引入):将证书作为可复用的资源由 EMQX 统一管理,并通过名称进行引用。
请根据你的部署方式和运维需求选择合适的方式。
通过 Dashboard 启用
进入管理 -> 监听器。
点击名为 default 的 SSL 类型监听器,打开编辑监听器页面。
配置以下 SSL/TLS 相关选项:
双向认证:默认关闭(单向认证)。关闭时,EMQX 不会校验客户端证书。
强制验证对端证书:仅在开启双向认证时生效。对于单向认证场景,该选项应保持关闭。
证书来源:选择服务器证书的提供方式:
手动输入:使用传统的基于路径的证书文件。需要配置以下字段:
- TLS Cert:服务器证书文件路径。
- TLS Key:服务器私钥文件路径。
从托管证书中选择:使用 EMQX 托管的证书包(EMQX 6.1+)。需要配置以下字段:
- 命名空间:托管证书所在的命名空间(默认:
全局)。 - 托管证书包名称:选择一个已有的托管证书包。若需创建新的证书包,可点击创建托管证书。详情请参考:通过 Dashboard 创建托管证书包。
- SNI(可选):用于在同一监听器上配置多个证书时,根据客户端请求的 SNI 值匹配对应证书。
你可以点击 “+” 按钮添加多个托管证书条目。当配置了多个证书时:
- EMQX 会根据客户端发送的 SNI 动态选择证书。
- 若未匹配到 SNI,则使用列表中的第一个证书作为默认证书。
- 命名空间:托管证书所在的命名空间(默认:
SSL 版本:支持所有 TLS/DTLS 版本。默认设置为
tlsv1.3和tlsv1.2。如果 PSK 验证中使用了 PSK 密码套件,确保在此处设置tlsv1.2,tlsv1.1和tlsv1。更多关于 PSK 的内容请参阅 PSK 认证。加密套件:用于指定允许使用的加密套件。
CA 证书深度:证书链允许的最大深度,默认值为
10。密钥文件密码:如果密钥文件由密码保护,则需要输入密码。
启用 OCSP Stapling: 默认为不启用;如需获取 X.509 数字证书的撤销状态,可以点击切换开关。具体可参阅 OCSP Stapling。
启用 CRL 检查:默认为不启用;如需设置证书吊销列表(CRL)检查功能,可以点击切换开关。具体可参阅 CRL 检查。
配置完成后,点击更新以应用更改。
通过配置文件启用
你也可以通过修改配置文件中的 listeners.ssl.default 配置组来启用 SSL/TLS 连接。
将你的 SSL/TLS 证书文件放置到 EMQX 的
etc/certs目录中。打开配置文件
base.hocon(根据安装方式不同,该文件位于./etc或/etc/emqx/etc目录中)。修改
listeners.ssl.default配置组。如果您选择使用磁盘上的证书文件(基于路径的证书):将示例中的证书文件替换为您自己的证书。如需启用单向认证,请设置
verify = verify_none:hoconlisteners.ssl.default { bind = "0.0.0.0:8883" ssl_options { cacertfile = "etc/certs/rootCAs.pem" certfile = "etc/certs/server-cert.pem" keyfile = "etc/certs/server-key.pem" verify = verify_none fail_if_no_peer_cert = true } }配置项说明:
cacertfile:用于验证客户端证书的受信任 CA 证书(PEM 格式)文件路径。对于单向认证,该文件可以为空或不包含任何 CA 证书。certfile:服务器 SSL/TLS 证书链(PEM 格式)文件路径。如果监听器使用的服务器证书不是由根 CA 直接签发,需要将中间 CA 证书按顺序追加在服务器证书之后,以形成完整的证书链。keyfile:与服务器证书对应的私钥文件(PEM 格式)路径。verify:控制 EMQX 是否验证客户端证书:verify_none:不验证客户端证书(单向认证)。verify_peer:验证客户端证书(双向认证 / mTLS 必需)。
fail_if_no_peer_cert:当客户端未提供证书时的握手行为:false:允许客户端不提供证书,仅在客户端提供了无效证书时拒绝连接(单向认证)。true:客户端未提供证书时直接拒绝连接(mTLS 必需)。
如果您使用 EMQX 统一管理并通过名称引用的托管证书,配置示例如下:
托管证书包需要事先通过 Dashboard 或 HTTP API 创建。监听器配置中只需引用已存在的托管证书。
示例:引用全局(global)命名空间中的证书
hoconlisteners.ssl.default { bind = "0.0.0.0:8883" ssl_options { managed_certs = [ { bundle_name = "example-cert-1" sni = "example.com" }, { bundle_name = "example-cert-2" sni = "api.example.com" } ] # 单向认证 verify = verify_none fail_if_no_peer_cert = false } }当引用全局(global)命名空间中的托管证书时,
namespace字段需要省略。如果省略namespace,EMQX 会默认使用全局命名空间。示例:引用非全局(租户)命名空间中的证书
hoconlisteners.ssl.default { bind = "0.0.0.0:8883" ssl_options { managed_certs = [ { namespace = "tenant-a" bundle_name = "mqtt-cert" sni = "mqtt.tenant-a.example.com" } ] verify = verify_none fail_if_no_peer_cert = false } }当使用创建在非全局(租户)命名空间中的托管证书时,必须显式指定
namespace字段。当配置了多个托管证书时:
- EMQX 会根据客户端发送的 SNI 动态选择匹配的证书。
- 如果没有匹配到 SNI,则使用列表中的第一个证书作为默认证书。
重启 EMQX 以使配置生效。
完成 SSL/TLS 连接的配置后,您可以通过 MQTT 客户端连接到 EMQX。
单向认证客户端测试
您可以使用 MQTTX CLI 进行测试,单向认证通常需要客户端提供 CA 证书,以便客户端验证服务器的身份:
mqttx sub -t 't/1' -h localhost -p 8883 \
--protocol mqtts \
--ca certs/rootCA.crt如果服务器证书 CN 与客户端连接时指定的服务器地址不匹配,将会出现以下错误:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: localhost. is not cert's CN: Server此时可以设置客户端证书 CN 与服务器地址匹配,或者通过 --insecure 选项忽略证书 CN 验证:
mqttx sub -t 't/1' -h localhost -p 8883 \
--protocol mqtts \
--ca certs/rootCA.crt \
--insecure启用双向认证
双向认证是在单向认证的基础上,进一步配置 EMQX 对客户端证书进行验证,以确保客户端的身份合法性。
除此之外,您还需要为客户端生成证书,具体操作请参考签发客户端证书。
对于 Dashboard 方式,您可以在验证客户端证书处选择启用,并配置没有证书则 SSL 失败选项为 true 强制开启双向认证。
您也可以在配置文件添加以下 2 项配置:
listeners.ssl.default {
...
ssl_options {
...
# 双向认证,验证客户端证书
verify = verify_peer
# 如果客户端没有证书,SSL/TLS 连接将被拒绝
fail_if_no_peer_cert = true
}
}双向认证客户端测试
您可以使用 MQTTX CLI 进行测试,双向认证除了需要客户端提供 CA 证书外,还应当提供客户端证书:
mqttx sub -t 't/1' -h localhost -p 8883 \
--protocol mqtts \
--ca certs/rootCA.crt \
--cert certs/client-0001.crt \
--key certs/client-0001.key如果服务器证书 CN 与客户端连接时指定的服务器地址不匹配,将会出现以下错误:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: localhost. is not cert's CN: Server此时可以设置客户端证书 CN 与服务器地址匹配,或者通过 --insecure 选项忽略证书 CN 验证:
mqttx sub -t 't/1' -h localhost -p 8883 \
--protocol mqtts \
--ca certs/rootCA.crt \
--cert certs/client-0001.crt \
--key certs/client-0001.key \
--insecure