文章目录
- 背景信息
- 1、CA证书信任模型
- 2、创建证书
- 2.1 Root CA 证书创建
- 2.2 emqx 服务端证书签发
- 2.3 中间CA证书签发
- 2.4 设备证书签发
- 3、配置EMQX服务端证书
- 4、客户端使用TLS连接EMQX
背景信息
本文主要介绍了通过建立三层CA证书链,为EMQX集群提供PKI服务,实现客户端与云端的双向认证。EMQX集群部署,请参考:支持上亿物联网终端设备接入的MQTT集群。
1、CA证书信任模型
根CA为EMQX服务签发服务器端证书,以及给中间CA签发中间证书,由中间CA给设备签发设备证书。
2、创建证书
使用不同的 CA 服务,证书签发的流程以及需要的参数不同,如大部分支持安全芯片的设备,其私钥通常由设备端生成,通过向 CA 发送 csr 请求文件的方式获取CA机构签发的证书。下文仅借助流行的 cfssl 工具来完成证书的创建工作,设备端私钥由 cfssl 工具生成,如果尚未安装 cfssl 工具,请查看 cfssl 工具下载相关文章
2.1 Root CA 证书创建
- 创建 ca-csr.json
{
"CN": "emqx",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "emqx",
"OU": "system"
}
],
"ca": {
"expiry": "87600h"
}
}
- 创建根CA私钥与公钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
通过上边命令得到根CA的私钥 ca-key.pem
以及Root CA的字签名根证书 ca.pem
。
- 创建CA签发证书的配置文件 ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"emqx": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
2.2 emqx 服务端证书签发
- 创建 emqx-server-csr.json 文件
{
"CN": "emqx",
"hosts": [
"*"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "emqx",
"OU": "system"
}
]
}
- 使用Root CA 私钥签发 emqx 服务端证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=emqx emqx-server-csr.json | cfssljson -bare emqx-server
通过上边的命令,将会得到 emqx 服务端的私钥 emqx-server-key.pem
,以及证书文件 emqx-server.pem.
这两个文件将会写入到 EMQX 配置文件 /etc/emqx/emqx.conf
中
2.3 中间CA证书签发
- 创建
emqx-intermediate-csr.json
文件
{
"CN": "emqx",
"hosts": [
"*"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "emqx",
"OU": "system"
}
]
}
- 使用Root CA 私钥签发中间CA的证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=emqx emqx-intermediate-csr.json | cfssljson -bare emqx-intermediate
通过上边的命令,将会得到中间CA的私钥 emqx-intermediate-key.pem
,以及中间CA的证书 emqx-intermediate.pem
。中间CA的证书将会被写入到 EMQX 配置文件 /etc/emqx/emqx.conf
中。
2.4 设备证书签发
- 创建设备证书签发配置参数模板文件 emqx-device-csr.json
{
"CN": "emqx",
"hosts": [
"*"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "emqx",
"OU": "system"
}
]
}
- 为设备A签发证书
cfssl gencert -ca=emqx-intermediate.pem -ca-key=emqx-intermediate-key.pem -config=ca-config.json -profile=emqx emqx-device-csr.json | cfssljson -bare emqx-device-A
通过指定上边命令将会得到设备A的私钥 emqx-device-A-key.pem
,以及设备A的证书 emqx-device-A.pem
。
- 为设备B签发证书
cfssl gencert -ca=emqx-intermediate.pem -ca-key=emqx-intermediate-key.pem -config=ca-config.json -profile=emqx emqx-device-csr.json | cfssljson -bare emqx-device-B
通过指定上边命令将会得到设备A的私钥 emqx-device-B-key.pem
,以及设备A的证书 emqx-device-B.pem
。如需给更多的设备签发证书,只需将上边的参数 emqx-device-B
换成其他设备名称即可。
3、配置EMQX服务端证书
emqx 默认的配置文件在 /etc/emqx/emqx.conf
中,修改配置文件,添加 ssl 证书配置信息,以及开启双向认证。
listeners.ssl.default {
bind = "0.0.0.0:8883"
max_connections = 512000
ssl_options {
keyfile = "/etc/ssl/emqx/emqx-server-key.pem"
certfile = "/etc/ssl/emqx/emqx-server.pem"
cacertfile = "/etc/ssl/emqx/emqx-intermediate.pem"
verify = verify_peer
# 强制开启双向认证,如果客户端无法提供证书,则 SSL/TLS 连接将被拒绝
fail_if_no_peer_cert = true
}
}
- keyfile: 设置 emqx 服务端私钥文件
- certfile:设置 emqx 服务端证书文件
- cacertfile:设置为终端签发证书的CA机构证书
ssl 配置修改完成后,需要重启 emqx 服务,在重启服务之前,建议给证书文件设置可读权限,防止emqx服务端没有权限读取证书文件。
chmod +r /etc/ssl/emqx/*
systemctl restart emqx
4、客户端使用TLS连接EMQX
上图是 EMQX 提供的客户端工具,里边设计到的关键参数有:
- 服务器地址:EMQX 服务的域名或IP地址,协议选择:
mqtts://
,表示连接EMQX的 ssl 坚挺类型。 - SSL/TLS:选中开启后,表示客户端与服务端使用 TLS 加密传输,发起连接请求需要携带证书。
- SSL安全:如果开启该功能项,将会校验证书以及证书链的有效性,由于上问中字签发证书 hosts 没有填写具体的服务器IP或域名,如果开启该功能,将会导致证书校验失败,所以此处没有开启该功能。
- 证书类型:选择 Self signed 表示使用自签发证书。
- CA 文件:填写 Root CA 机构的根证书文件;
- 客户端证书:填写设备证书。
- 客户端 key 文件:填写设备私钥。
参数设置完成后,点击链接按钮,连接成功后会有提示信息,如上图右上角已连接
提示消息。同时 emqx 的管理控制台也会有连接成功的客户端信息
到此,通过自签发证书的方式实现了 EMQX 集群与客户端之间的双向认证。EMQX 集群直接与设备采用TLS加密传输,在性能上有一定的损耗,官方建议将设备与云之间的双向认证由负载均衡服务终结,即:设备到负载均衡服务采用双向认证,负载均衡服务终结TLS,然后与 EMQX 集群采用非TLS传输。后续将会选择 HAPorxy 来作为负载均衡服务,实现官方推荐的双向认证服务。敬请期待…