Skip to content

开启 SSL/TLS 连接

SSL/TLS 加密功能会在传输层对网络连接进行加密,它能在提升通信数据安全性的同时,保证数据的完整性。

本章节将向您详细介绍 SSL/TLS 加密连接的功能和优势以及在 EMQX 上开启 SSL/TLS 的步骤。

安全优势

启用 SSL/TLS 连接提供了以下安全优势:

  1. 强认证:开启 TLS 连接后,通讯双方将互相检查对方的身份,比如通过检查对方持有的 X.509 数字证书;这类数字证书通常是由受信机构 CA(Certificate Authority)颁发,不可伪造。
  2. 机密性:开启 TLS 连接后,每次会话都会根据双方协商得到的会话密钥进行加密。任何第三方都无法知晓通讯内容,因此即使一次会话的密钥泄露,也不影响其他会话的安全性。
  3. 完整性:加密通讯中的数据被篡改的可能性极低。

使用方式对比

您可以为包括 MQTT 在内的所有连接启用 SSL/TLS 加密连接,保证接入与消息传输安全。对于客户端的 SSL/TLS 连接,您可以根据使用场景选择以下两种使用方式之一:

使用方式优势缺点
在 EMQX 上开启 SSL/TLS简单易用,不需要额外的组件。会增加 EMQX 的资源消耗,如果连接数量巨大,可能会导致较高的 CPU 和内存消耗。
通过代理或负载均衡终结 TLS 连接不影响 EMQX 性能,同时提供了负载均衡能力。需要额外部署 HAProxyNGINX 或使用云厂商负载均衡服务,其中只有部分云厂商支持 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 启用

  1. 进入管理 -> 监听器

  2. 点击名为 defaultSSL 类型监听器,打开编辑监听器页面。

  3. 配置以下 SSL/TLS 相关选项:

    • 双向认证:默认关闭(单向认证)。关闭时,EMQX 不会校验客户端证书。

    • 强制验证对端证书:仅在开启双向认证时生效。对于单向认证场景,该选项应保持关闭。

    • 证书来源:选择服务器证书的提供方式:

      • 手动输入:使用传统的基于路径的证书文件。需要配置以下字段:

        • TLS Cert:服务器证书文件路径。
        • TLS Key:服务器私钥文件路径。
      • 从托管证书中选择:使用 EMQX 托管的证书包(EMQX 6.1+)。需要配置以下字段:

        • 命名空间:托管证书所在的命名空间(默认:全局)。
        • 托管证书包名称:选择一个已有的托管证书包。若需创建新的证书包,可点击创建托管证书。详情请参考:通过 Dashboard 创建托管证书包
        • SNI(可选):用于在同一监听器上配置多个证书时,根据客户端请求的 SNI 值匹配对应证书。

        你可以点击 “+” 按钮添加多个托管证书条目。当配置了多个证书时:

        • EMQX 会根据客户端发送的 SNI 动态选择证书。
        • 若未匹配到 SNI,则使用列表中的第一个证书作为默认证书。
    • SSL 版本:支持所有 TLS/DTLS 版本。默认设置为 tlsv1.3tlsv1.2。如果 PSK 验证中使用了 PSK 密码套件,确保在此处设置 tlsv1.2tlsv1.1tlsv1。更多关于 PSK 的内容请参阅 PSK 认证

    • 加密套件:用于指定允许使用的加密套件。

    • CA 证书深度:证书链允许的最大深度,默认值为 10

    • 密钥文件密码:如果密钥文件由密码保护,则需要输入密码。

    • 启用 OCSP Stapling: 默认为不启用;如需获取 X.509 数字证书的撤销状态,可以点击切换开关。具体可参阅 OCSP Stapling

    • 启用 CRL 检查:默认为不启用;如需设置证书吊销列表(CRL)检查功能,可以点击切换开关。具体可参阅 CRL 检查

  4. 配置完成后,点击更新以应用更改。

通过配置文件启用

你也可以通过修改配置文件中的 listeners.ssl.default 配置组来启用 SSL/TLS 连接。

  1. 将你的 SSL/TLS 证书文件放置到 EMQX 的 etc/certs 目录中。

  2. 打开配置文件 base.hocon(根据安装方式不同,该文件位于 ./etc/etc/emqx/etc 目录中)。

  3. 修改 listeners.ssl.default 配置组。

    • 如果您选择使用磁盘上的证书文件(基于路径的证书):将示例中的证书文件替换为您自己的证书。如需启用单向认证,请设置 verify = verify_none

      hocon
      listeners.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)命名空间中的证书

      hocon
      listeners.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 会默认使用全局命名空间。

      示例:引用非全局(租户)命名空间中的证书

      hocon
      listeners.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,则使用列表中的第一个证书作为默认证书。
  4. 重启 EMQX 以使配置生效。

完成 SSL/TLS 连接的配置后,您可以通过 MQTT 客户端连接到 EMQX。

单向认证客户端测试

您可以使用 MQTTX CLI 进行测试,单向认证通常需要客户端提供 CA 证书,以便客户端验证服务器的身份:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt

如果服务器证书 CN 与客户端连接时指定的服务器地址不匹配,将会出现以下错误:

bash
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 验证:

bash
mqttx sub -t 't/1' -h localhost -p 8883 \
  --protocol mqtts \
  --ca certs/rootCA.crt \
  --insecure

启用双向认证

双向认证是在单向认证的基础上,进一步配置 EMQX 对客户端证书进行验证,以确保客户端的身份合法性。

除此之外,您还需要为客户端生成证书,具体操作请参考签发客户端证书

对于 Dashboard 方式,您可以在验证客户端证书处选择启用,并配置没有证书则 SSL 失败选项为 true 强制开启双向认证。

您也可以在配置文件添加以下 2 项配置:

bash
listeners.ssl.default {
  ...
  ssl_options {
    ...
    # 双向认证,验证客户端证书
    verify = verify_peer
    # 如果客户端没有证书,SSL/TLS 连接将被拒绝
    fail_if_no_peer_cert = true
  }
}

双向认证客户端测试

您可以使用 MQTTX CLI 进行测试,双向认证除了需要客户端提供 CA 证书外,还应当提供客户端证书:

bash
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 与客户端连接时指定的服务器地址不匹配,将会出现以下错误:

bash
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 验证:

bash
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