emqx 开启 SSL证书

目录

1、生成SSL证书方式

2、创建自签名 CA 证书

3、签发服务器证书

4、客户端连接证书异常

5、指定subjectAltName(SANs)生成证书

5.1、证书配置文件创建

5.1.1、CA签发证书配置文件ca.cnf

5.1.2、服务端证书配置文件server.cnf

5.1.3、客户端证书配置文件client.cnf

5.2、证书生成

5.3.1、服务器端证书使用

5.3.2、客户端证书使用


1、生成SSL证书方式

根据emqx官方文档获取SSL证书有如下方式:

获取 SSL/TLS 证书 | EMQX 文档

您可通过以下两种方式获取相关 SSL/TLS 证书:

  1. 自签名证书:即使用自己签发的证书,由于自签名证书存在较多的安全隐患,因此只建议用于测试验证环境。
  2. 申请或购买证书:您可以向 Let's Encrypt 或华为云、腾讯云等云厂商申请免费证书,也可以向 DigiCert 等机构购买收费证书。对于企业级用户,一般建议申请收费的 OV 及以上类型的证书,以获取更高等级的安全保护。

本页介绍了如何创建自签名 Certificate Authority (CA) 证书并签发服务器和客户端证书的操作步骤。

SSL证书分为自签名 CA 证书、服务器端证书(安装eqmx的服务器)、客户端证书(连接的设备);

其中自签名 CA 证书和服务器端证书只需要生成一次就行,客户端证书是每一个设备都需要生成。

2、创建自签名 CA 证书

这一步会生成rootCA.key这一步会生成rootCA.key这一步会生成rootCA.key这一步会生成rootCA.key前置准备

已安装 OpenSSL

2.1、运行以下命令生成密钥对,该命令随即会提示您输入密钥保护密码,后续在生成、签发、验证证书时均需要此密码。请妥善保管相关密钥及密码。

bash

openssl genrsa -des3 -out rootCA.key 2048

这一步会生成rootCA.key

2.2、运行以下命令通过密钥对中的私有密钥生成 CA 证书,该命令随即会提示您设置证书的唯一标识名称 DN(Distinguished Name)。

bash

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt

这一步会生成rootCA.crt

此处的 -days 3650 指定了证书的有效期限 10年

3、签发服务器证书

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

(rootCA.key)、CA 证书( rootCA.crt)和服务端 CSR (server.csr)生成服务器证书。

3.1、运行以下命令生成服务器证书密钥对:

openssl genrsa -out server.key 2048

    这一步会生成server.key

    3.2、运行以下命令使用 Server 密钥对制作 CSR。经 CA 根证书私钥签名后,CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。

    openssl req -new -key server.key -out server.csr

    这一步会生成server.csr

    3.3、使用 CSR 生成服务器证书,此时也可指定证书的有效天数,此处为 365 天:

    openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365

    这一步会生成rootCA.srl、server.crt

    至此就生成了一组证书

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

    设备接入继续签发客户端证书就行了

    openssl genrsa -out client.key 2048
    openssl req -new -key client.key -out client.csr
    openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 3650

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

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

    4、客户端连接证书异常

    需要注意的是通过以上官方描述创建的证书在使用的时候,客户端连接会报错:

    Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative names present。

    这个错误 SSLHandshakeException: No subject alternative names present 表示你的 SSL 证书缺少 Subject Alternative Names (SANs),而客户端(如 Java MQTT 客户端)强制要求 SANs 扩展字段。

    所以需要根据下面的步骤来生成证书

    5、指定subjectAltName(SANs)生成证书

    5.1、证书配置文件创建

    5.1.1、CA签发证书配置文件ca.cnf

    # ca.cnf - 自建根证书颁发机构 (Root CA) 配置
    [ req ]
    default_bits       = 2048
    distinguished_name = req_distinguished_name
    x509_extensions    = v3_ca
    prompt             = no
    default_md         = sha256
    
    [ req_distinguished_name ]
    C            = CN               # 国家代码(如 CN/US)
    ST           = Jiangsu          # 省份/州
    L            = Nanjing          # 城市
    O            = Blbn            # 组织名称
    OU           = Yanfa              # 部门(可选)
    CN           = TestBlbn        # CA 名称(必须唯一)
    
    [ v3_ca ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints     = critical, CA:true    # 关键!标记为 CA 证书
    keyUsage             = critical, keyCertSign, cRLSign  # CA 用途

    5.1.2、服务端证书配置文件server.cnf

    [req]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    prompt = no
    
    [req_distinguished_name]
    CN = 192.168.3.64  # 服务端 IP
    
    [v3_req]
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth           # 关键!
    subjectAltName = IP:192.168.3.64        # 关键!

    有些版本keyUsage 可能是这样配置的,keyUsage = keyEncipherment, dataEncipherment  这个配置通过JAVA代码连接的时候正常,但是通过mqttx等客户端连接的时候会报如下错误:

    rror: write EPROTO 8774408:error:1000012e:SSL routines:OPENSSL_internal:KEY_USAGE_BIT_INCORRECT:../../third_party/boringssl/src/ssl/ssl_cert.cc:609:

    正确的配置是 keyUsage = digitalSignature, keyEncipherment

    digitalSignature 是必须的,因为 TLS 握手过程中需要数字签名操作。

    5.1.3、客户端证书配置文件client.cnf

    [req]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    prompt = no
    
    [req_distinguished_name]
    CN = client1  # 客户端唯一标识  不同的客户端不一样
    
    [v3_req]
    keyUsage = digitalSignature
    extendedKeyUsage = clientAuth           # 关键!
    # subjectAltName 通常不需要(除非服务端要求)

    5.2、证书生成

    生成CA密钥对,此处会让输入密钥保护密码
    openssl genrsa -des3 -out rootCA.key 2048
    通过密钥对中的私有密钥生成 CA 证书
    openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt -config ca.cnf
    
    生成服务器证书密钥对
    openssl genrsa -out server.key 2048
    使用 Server 密钥对制作 CSR。经 CA 根证书私钥签名后,CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。
    openssl req -new -key server.key -out server.csr -config server.cnf
    使用 CSR 生成服务器证书,此时也可指定证书的有效天数,此处为 3650 天:此处会让输入前面设置的CA密钥保护密码
    openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -extensions v3_req -extfile server.cnf
    
    
    生成客户端证书密钥对
    openssl genrsa -out client.key 2048
    使用 Client 密钥对制作 CSR。经 CA 根证书私钥签名后,CSR 可生成颁发给用户的证书公钥文件。该命令随即也会要求设置证书的唯一标识名称。
    openssl req -new -key client.key -out client.csr -config client.cnf
    使用 CSR 生成客户端证书,此时也可指定证书的有效天数,此处为 365 天:此处会让输入前面设置的CA密钥保护密码
    openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 365 -extensions v3_req -extfile client.cnf

    5.3、证书说明

    ├── rootCA.key     # CA 私钥(PEM 或 DER)
    ├── rootCA.crt     # CA 证书(PEM 或 DER)
    ├── rootCA.srl     # 序列号文件(可忽略)
    ├── server.crt     # 服务器证书(PEM 或 DER)
    ├── server.csr     # 证书签名请求(可忽略)
    └── server.key     # 服务器私钥(PEM 或 DER)

    如何判断它们是 PEM 还是 DER?

    # 如果是 PEM 格式,文件开头会是:
    # -----BEGIN CERTIFICATE----- 或 -----BEGIN PRIVATE KEY-----
    cat server.crt

    # 如果是 DER 格式,文件是二进制(乱码)
    file server.crt

    PEM vs CRT/KEY 的转换

    (1)如果文件已经是 PEM 格式

    • 直接重命名即可兼容 EMQX:

      bash

      cp server.crt cert.pem
      cp server.key key.pem
      cp rootCA.crt cacert.pem

    (2)如果文件是 DER 格式

    需转换为 PEM:

    bash

    # 证书 DER → PEM
    openssl x509 -inform der -in server.crt -out cert.pem
    
    # 私钥 DER → PEM
    openssl rsa -inform der -in server.key -out key.pem

    (3)合并证书链(如需)

    如果 server.crt 不包含中间 CA,需合并:

    bash

    cat server.crt rootCA.crt > fullchain.pem

    5.3、证书使用

    5.3.1、服务器端证书使用

    登录mqtt dashboard 在监听器中修改ssl配置,点击重新设置,TLS Cert此处把server.crt内容复制出来粘贴上去;TLS Key此处把server.key内容复制出来粘贴上去;CA Cert此处把rootCA.crt内容复制出来粘贴上去;然后点击更新按钮完成配置

    5.3.2、客户端证书使用

    以Java为示列,需要rootCA.crt、client.crt、client.key

    多个客户端可以使用同一个客户端证书 client.crt、client.key 这种用法只需要维护一个证书,维护方便,但是只要该证书泄露,所有设备都受影响;生产环境建议为每个设备都生成一个证书(使用客户端唯一id生成)

    5.3.3、emqx.conf配置ssl

    单向认证时配置

    listeners.ssl.default {
      bind = "0.0.0.0:8883"
      ssl_options {
        # PEM 格式的文件,包含一个或多个用于验证客户端证书的根 CA 证书
        # 单向认证时,该文件内容可以为空
        cacertfile = "${EMQX_ETC_DIR}/certs/rootCA.crt"
        # PEM 格式的服务器证书,如果证书不是直接由根 CA 签发,那么中间 CA 的证书必须加在服务器证书的后面组成一个证书链
        certfile = "${EMQX_ETC_DIR}/certs/server.crt"
        # PEM 格式的密钥文件
        keyfile = "${EMQX_ETC_DIR}/certs/server.key"
        # 设置成 'verify_peer' 来验证客户端证书是否为 cacertfile 中某个根证书签发。双向认证时,必须设置成 'verify_peer'。
        # 设置成 'verify_none' 则不验证客户端证书,即单向认证。
        verify = verify_none
        # 如果设置成 true,但是客户端在握手时候没有发送证书,服务端会终止握手。双向认证时,必须设置成 true。
        # 如果设置成 false,那么服务端只有在客户端发送一个非法证书时才会终止握手
        fail_if_no_peer_cert = false
      }
    }

    双向认证时配置

    listeners.ssl.default {
      bind = "0.0.0.0:8883"
      ssl_options {
        # PEM 格式的文件,包含一个或多个用于验证客户端证书的根 CA 证书
        # 单向认证时,该文件内容可以为空
        cacertfile = "${EMQX_ETC_DIR}/certs/rootCA.crt"
        # PEM 格式的服务器证书,如果证书不是直接由根 CA 签发,那么中间 CA 的证书必须加在服务器证书的后面组成一个证书链
        certfile = "${EMQX_ETC_DIR}/certs/server.crt"
        # PEM 格式的密钥文件
        keyfile = "${EMQX_ETC_DIR}/certs/server.key"
        # 设置成 'verify_peer' 来验证客户端证书是否为 cacertfile 中某个根证书签发。双向认证时,必须设置成 'verify_peer'。
        # 设置成 'verify_none' 则不验证客户端证书,即单向认证。
        verify = verify_peer
        # 如果设置成 true,但是客户端在握手时候没有发送证书,服务端会终止握手。双向认证时,必须设置成 true。
        # 如果设置成 false,那么服务端只有在客户端发送一个非法证书时才会终止握手
        fail_if_no_peer_cert = true
      }
    }

    需要注意的是,当你配置为单向认证时,客户端连接只需要设置自签名证书

    双向认证时,除了自签名证书,客户端证书也需要设置

    至此,证书使用介绍完成。

      ### 配置 EMQX 在 EC200 设备上启用 SSL #### 准备工作 为了在 EC200 上配置 EMQXSSL 功能,需准备有效的 SSL/TLS 证书文件。这些文件通常包括私钥、公钥以及 CA 根证书[^1]。 #### 修改 EMQX 配置文件 编辑位于 `/etc/emqx/emqx.conf` 或者安装路径下的 `emqx.conf` 文件,在该文件中找到并修改如下参数: ```ini listener.ssl.external.keyfile = /path/to/your/private_key.pem # 私钥位置 listener.ssl.external.certfile = /path/to/your/cert_file.crt # 客户端认证使用的证书链文件 listener.ssl.external.cacertfile = /path/to/ca_cert_file # 可信CA根证书的位置 (如果适用) ``` 上述命令指定了用于建立加密通信所需的密钥和证书所在的具体路径[^2]。 #### 启动监听器 确保启用了相应的 SSL 监听端口,默认情况下可能是8883端口: ```ini listener.ssl.external = 8883 # 开启SSL外部访问接口 ``` 此操作允许客户端通过指定的安全通道连接到服务器[^3]。 #### 测试与验证 完成以上设置之后重启 EMQX Broker 来使更改生效,并利用 MQTT 客户端工具测试能否成功创建 TLS 连接。可以使用 mosquitto_pub/mosquitto_sub 命令行工具来进行简单的发布订阅测试,记得加上 `-i`, `-u`, 和 `-P` 参数来提供必要的身份验证信息(如果有),同时还要加入 `--cafile` 指定信任的 CA 文件以实现双向认证[^4]。 ```bash mosquitto_sub -h your_emqx_host -p 8883 --cafile /path/to/ca-cert-file -t "test/topic" ```
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值