Skip to content

SSL/TLS 证书

SSL/TLS 证书是 EMQX 安全体系的重要组成部分,用于在通信过程中提供身份认证、数据加密和完整性保护。在 EMQX 中,以下场景需要使用 SSL/TLS 证书:

  • 基于 TLS 的 MQTT 连接(MQTTS)
  • 基于安全 WebSocket 的 MQTT 连接(WSS)
  • HTTPS 服务与 Dashboard 访问
  • 启用 TLS 的外部连接(例如数据集成)

从 EMQX 6.1 开始,证书不再仅仅被视为配置中的文件路径,而是作为可复用的资源进行管理。EMQX 支持以下两种证书管理方式:

  1. 基于路径的证书(传统方式):在配置中通过文件路径直接引用证书。
  2. 托管证书(EMQX 6.1+):将证书作为可复用资源进行集中管理,并通过名称进行引用。

这两种方式都使用标准的 PEM 编码文件,并与 EMQX 的 SSL/TLS 实现完全兼容。

本页面将介绍:

  • 如何获取 SSL/TLS 证书
  • EMQX 中证书的管理
  • EMQX 如何支持多证书配置
  • 更新 SSL/TLS 证书

获取 SSL/TLS 证书

在 EMQX 使用证书之前,必须先从受信任的来源获取 SSL/TLS 证书。选择哪种获取方式取决于您的部署环境和安全需求。

获取证书的方式

您可以通过以下方式获取 TLS 证书:

  • 自签名证书

    由您自己创建的证书颁发机构(CA)签发的证书。此类证书存在较多的安全隐患,仅建议用于测试环境或受控环境。

  • 申请或购买由受信任 CA 签发的证书

    从公共 CA 或企业级 CA 获取的证书,例如:

    在生产环境和企业级部署中,通常建议使用 OV(组织验证)或更高级别的证书,以获得更高的安全保障。

创建自签名 CA 证书

前置准备

已安装 OpenSSL

  1. 运行以下命令生成密钥对,该命令随即会提示您输入密钥保护密码,后续在生成、签发、验证证书时均需要此密码。请妥善保管相关密钥及密码。
bash
openssl genrsa -des3 -out rootCA.key 2048
  1. 运行以下命令通过密钥对中的私有密钥生成 CA 证书,该命令随即会提示您设置证书的唯一标识名称 DN(Distinguished Name)。
bash
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt

签发服务器证书

使用 CA 证书来签发服务器证书,用于验证服务器所有者的身份,服务器证书通常颁发给主机名、服务器名称或域名(如 www.emqx.com, localhost)。我们需要 CA 密钥(rootCA.key)、CA 证书( rootCA.crt)和服务端 CSR (server.csr)生成服务器证书。

  1. 运行以下命令生成服务器证书密钥对:
bash
openssl genrsa -out server.key 2048
  1. 运行以下命令使用 Server 密钥对制作 CSR。经 CA 根证书私钥签名后,CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。
bash
openssl req -new -key server.key -out server.csr

系统将提示以下信息,对应的含义如下:

bash
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: # 国家/地区
State or Province Name (full name) [Some-State]: # 省/市
Locality Name (eg, city) []: # 城市
Organization Name (eg, company) [Internet Widgets Pty Ltd]: # 组织机构(或公司名),如 EMQ
Organizational Unit Name (eg, section) []: # 机构部门,如 EMQX
Common Name (e.g. server FQDN or YOUR name) []: # 通用名称,此处应当设置为服务器域名如 mqtt.emqx.com
...
  1. 使用 CSR 生成服务器证书,此时也可指定证书的有效天数,此处为 365 天:
bash
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365

至此您就得到了一组证书。

bash
.
├── rootCA.crt
├── rootCA.key
├── rootCA.srl
├── server.crt
├── server.csr
└── server.key

签发客户端证书

签发客户端证书的步骤与签发服务器证书类似,只是在生成 CSR 时,需要将 Common Name 设置为客户端的唯一标识,如用户名、客户端 ID 等。

客户端证书与服务端证书使用相同的 CA 证书签名,因此客户端证书也可以使用上述 CA 证书签名。

EMQX 中的证书管理

在获取证书之后,EMQX 支持通过两种方式对证书进行管理和引用。

基于路径的证书

基于路径的证书通过在监听器或其他组件的 TLS 配置项中显式指定证书文件路径来进行配置,例如:

  • certfile
  • keyfile
  • cacertfile

在使用基于路径的证书时:

  • 证书文件完全由用户或外部工具进行管理。
  • 监听器直接引用证书文件路径。
  • 证书更新通常通过替换磁盘上的证书文件来完成。

EMQX 在 etc/certs 目录下提供了一组示例证书,仅用于测试目的。

基于路径的证书在所有 EMQX 版本中均得到完整支持,并保持兼容。

托管证书

从 EMQX 6.1 开始,EMQX 引入了托管证书,这是一种集中式管理 TLS 证书文件的机制,可在多个组件之间复用。

托管证书可以在多个资源中复用,包括:

  • MQTT SSL 监听器
  • WSS 监听器
  • HTTPS / Dashboard 监听器
  • 启用 TLS 的连接器(用于数据集成)

托管证书可以通过 Dashboard 或 REST API 创建和管理,并存储在 EMQX 数据目录下的 data/certs2/ 中。

在内部实现上,EMQX 在与 Erlang/OTP 的 SSL 库交互时,仍然使用基于路径的 PEM 文件方式,从而确保:

  • 与现有 TLS 行为完全向后兼容
  • 证书能够自动重新加载
  • 更新证书后无需重启监听器或连接器

托管证书包

托管证书包表示一组逻辑上的 TLS 相关文件,包括:

  • 服务器证书
  • 私钥
  • 可选的 CA 证书

每个证书包由一个名称以及一个可选的命名空间进行标识,并且可以被多个监听器或连接器引用。

托管证书是一种可复用资源。更新某个托管证书包后,所有引用该证书包的监听器或连接器都会自动生效。

证书格式与文件结构

EMQX 中的托管证书继续使用 PEM 编码文件,这与 EMQX 现有的 TLS 证书部署方式保持一致。

使用 PEM 文件具有以下优势:

  • 透明性:证书文件可以使用 openssl 等标准工具轻松查看和验证。
  • 兼容性:PEM 格式被 Erlang/OTP 的 SSL 库原生支持,并提供:
    • 基于文件的证书缓存
    • 证书文件更新后的自动重新加载
证书文件结构

每个托管证书包在磁盘上以一个目录的形式存储,该目录由证书名称和命名空间标识。

示例:

mqtt.example.com
tenant1/certs1

托管证书包可能包含以下文件:

文件名是否必需说明
key.pem私钥
chain.pem证书链(不包含根 CA)
ca.pem可选用于校验对端证书的根 CA 证书集合
key-password.pem可选用于解密私钥的密钥(当私钥被加密时)

使用 SNI 的多证书支持

当在同一个监听器上配置了多个托管证书包时,EMQX 会基于服务器名称指示(Server Name Indication,SNI)进行动态证书选择。

SNI 是 TLS 的一种扩展,允许客户端在 TLS 握手过程中、在安全连接完全建立之前,指定其要连接的主机名。

SNI 的工作方式
  • 每个托管证书引用都可以选择性地指定一个 sni 值。
  • 在 TLS 握手过程中:
    1. 客户端发送 SNI 主机名。
    2. EMQX 将该 SNI 与已配置的证书条目进行匹配。
    3. 如果找到匹配项,则使用对应的证书包。
    4. 如果未找到匹配项,则使用证书列表中的第一个证书作为默认证书。

该机制使得单个监听器可以在同一个 IP 地址和端口上,使用不同的 TLS 证书安全地为多个域名或租户提供服务。

示例
hocon
listeners.ssl.default {
  bind = "0.0.0.0:8883"

  ssl_options {
    managed_certs = [
      {
        bundle_name = "default-cert"
        sni = "example.com"
      },
      {
        bundle_name = "example-cert-1"
        sni = "mqtt.example.com"
      }
    ]
  }
}

创建和管理托管证书包

本节介绍了如何通过 Dashboard 和 REST API 创建和管理托管证书包。证书包创建完成后即可被选择,并可在多个监听器或连接器之间复用。

通过 Dashboard 创建托管证书包

你可以直接通过 Dashboard 创建托管证书包。

  1. 进入管理 -> 证书

  2. 点击创建

  3. 创建托管证书面板中,填写以下信息:

    • 名称(必填):托管证书包的唯一名称。

    • 命名空间:用于控制托管证书包是创建在全局命名空间还是某个租户命名空间中。

      默认情况下,该开关处于关闭状态,表示证书包将创建在全局(global)命名空间中。开启后,您可以选择一个租户命名空间,并在该命名空间下创建证书包。

      • 全局管理员可以在 global 命名空间或任意租户(非全局)命名空间中创建证书包。
      • 命名空间级用户只能在其所属的命名空间中创建证书包。
    • TLS Cert(必填):PEM 格式的服务器证书,可直接粘贴或上传文件。如客户端有要求,应包含完整证书链。

    • TLS Key(必填):与服务器证书对应的私钥(PEM 格式)。

    • 私钥密码:可选。如果私钥被加密,需要填写对应密码。

    • CA Cert:可选。PEM 格式的 CA 证书,通常在双向 TLS 认证或被需要 CA 证书的连接器复用时使用。

  4. 点击创建保存托管证书包。

通过 Dashboard 管理托管证书包

创建证书包后,它会显示在 Dashboard 的证书列表中,您可以在此集中查看和管理所有托管证书包。

  • 使用页面顶部的命名空间下拉框,在全局(global)命名空间与指定的租户(非全局)命名空间之间切换,证书列表会根据所选命名空间自动更新。
  • 每个证书包都会显示其名称以及可用的操作

在该页面中,您可以:

  • 查看当前命名空间下的证书包;
  • 编辑证书包,以更新证书内容、私钥或 CA 证书;
  • 删除不再需要的证书包。

托管证书包存储在磁盘上,并由 EMQX 自动重新加载。更新托管证书无需重启 EMQX。

certificate_bundle_list

通过 REST API 管理托管证书包

除了 Dashboard,EMQX 还提供 REST API 用于管理托管证书包。通过 API 创建的托管证书包与通过 Dashboard 创建的证书包完全一致,并可通过相同方式被监听器和连接器引用。

上传证书文件

上传证书文件以创建或更新托管证书包。支持的文件类型包括:

  • key:私钥
  • chain:证书链(不包含根 CA)
  • ca:CA 证书包
  • key-password:用于解密私钥的密钥

上传到指定命名空间:

POST /certs/ns/:NAMESPACE/name/:NAME?file=key|chain|ca|key-password

上传到全局命名空间:

POST /certs/global/name/:NAME?file=key|chain|ca|key-password

列出托管证书包

  • 列出指定命名空间下的证书包:

    GET /certs/ns/:NAMESPACE
  • 列出全局命名空间下的证书包:

    GET /certs/global/list

删除托管证书包

  • 从指定命名空间删除:

    DELETE /certs/ns/:NAMESPACE/name/:NAME
  • 从全局命名空间删除:

    DELETE /certs/global/name/:NAME

更新 SSL/TLS 证书

为确保连接的安全性,SSL/TLS 证书必须在过期之前进行更新。在 EMQX 中,证书的更新方式取决于所使用的证书管理方式。

更新基于路径的证书

基于路径的证书是在配置中通过文件路径直接引用的证书(例如 certfilekeyfilecacertfile)。

更新基于路径的证书时,请按以下步骤操作:

  1. 使用新的证书文件、私钥文件或 CA 证书文件,替换 ./etc/etc/emqx/etc 目录中现有的证书文件。
  2. 确保配置中引用的证书文件路径保持不变。

EMQX 会自动重新加载更新后的证书文件:

  • EMQX 会定期检查并重新加载证书文件。
  • 默认情况下,证书每 120 秒重新加载一次。
  • 在大多数情况下,无需重启监听器。

更新托管证书

托管证书通过更新证书包的方式进行更新。

要更新托管证书,可以通过 Dashboard 或托管证书 API,向已有的托管证书包中上传新的证书、私钥或 CA 证书。

证书包更新完成后:

  • 所有引用该托管证书的监听器和启用 TLS 的组件都会自动使用更新后的证书。
  • 无需重启监听器或 EMQX。

托管证书被设计为可复用资源。更新某个证书包会影响所有引用该证书包的资源。

下一步

一旦您获得了 SSL/TLS 证书,您便可以启用客户端的 SSL/TLS 连接。