服务器工具:
EMQX:(版本:4.2.8/4.3.0)
客户端工具:
MQTTX(版本:5.0)
注意事项:
1.在生成ca.crt、服务端证书请求emqx.csr,客户端证书请求client.csr过程中有出现输入配置时,COMMON NAME一定要填,而且是互不相同:例如ca.crt->common name: sunada.com;emqx.csr->common name: emqx.sunada.com; client.csr->common name: emqx-client.sunada.com.其他的可以默认,直接按回车键
自生成证书工具openssl(ubuntu/windos base):
一:生成自签名的CA key和证书(mqtt服务端和mqtt客户端公用一个CA)
(备注:自签名证书在ubuntu/windows 用任意系统上的openssl生成均可,建议在ubuntu上,理由是快捷方便,反正最终签发客户端/服务端证书都要用同一个自签名证书)
1.生成自签名证书的私钥:
openssl genrsa -out ca.key 2048
2.用该私钥生成根证书:
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt(ca.pem,后面crt都可以定义为pem)
3.用此根证书是用来给其他实体(指EMQX/不同的client)签发实体证书的。
解释根证书:
1).根证书是整个信任链的起点
2).有了这个根证书,我们就可以用它来给其他实体签发实体证书了
3).可以有多级根证书,且如果一个证书的每一级签发者向上一直到根证书都是可信的,那个我们 就可以认为这个证书也是可信的
二:生成EMQX(一个mqtt服务端的实体),并且用上面生成的ca.crt跟证书签发EMQX的实体证书
1.用ubuntu 侧操作
2.生成emqx的私钥:
openssl genrsa -out server.key 2048
3.生成一个用来配置相关配置的配置文件openssl.cnf文件,也可以用默认的
openssl.cnf(etc/ssl/openssl.cnf):
1).[req_distinguished_name] :根据情况进行修改
2).[alt_names]: BROKER_ADDRESS 修改为 EMQ X 服务器实际的 IP 或 DNS 地址,例如:IP.1 = 127.0.0.1,DNS代理也可以不填
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
countryName = CN
stateOrProvinceName = ShangHai
localityName = Shanghai
organizationName = EMQX
commonName = minion.lemonstudio.tech
[req_ext]
subjectAltName = @alt_names
[v3_req]
subjectAltName = @alt_names
[alt_names]
IP.1 = BROKER_ADDRESS
DNS.1 = BROKER_ADDRESS
4.用私钥emqx.key 和配置openssl.cnf签发一个证书的请求 emqx.csr
1).用emqx.key和自定义配置openssl.cnf签发生成:
openssl req -new -key ./emqx.key -config ./openssl.cnf -out emqx.csr
2).只要emqx.key 和默认配置生成:
openssl req -new -key ./emqx.key -out emqx.csr
备注:用此方式确认的过程中输入指定参数配置,也可以直接按回车用默认的
3).带subj参数输入(此先输入要注释掉/etc/ssl/openssl # RANDFILE = $ENV::HOME/.rnd)
openssl req -new -key emqx.key -out emqx.csr -subj "/C=CN/ST=ShangHai/L=ShangHai/CN=emqx.xxxx.com"
5.用根证书ca来签发实体EMQX的实体证书:
1).用自定义的配置openssl.cnf
openssl x509 -req -in ./emqx.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out emqx.crt -days 3650 -sha256 -extensions v3_req -extfile ./openssl.cnf
2).用默认的配置生成:
openssl x509 -req -in ./emqx.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out emqx.crt -days 3650 -sha256
3).查看证书内容:
openssl x509 -in ./emqx.crt -noout -text
内容省略
4).验证签发证书是否被根证书通过:
openssl verify -CAfile ./ca.crt ./emqx.crt
备注:要是失败说明验证不通过,检查生成文件失败的原因,重新生成,下面是通过的
sudo openssl verify -CAfile ./ca.crt ./emqx.crt
./emqx.crt: OK
三:用根证书给客户端实体签发证书:
1).可以用ubuntu 生成,也可以用windows上,注意windows 利用openssl.cnf会报错,为少麻烦建议在ubuntu 上操作。
2.生成客户端私钥:
openssl genrsa -out client.key 2048
3).用客户端私钥签发一个证书的请求client.csr
a).用client.key 和自定义的openssl.cnf签发:
openssl req -new -key ./client.key -config ./openssl.cnf -out client.csr
b).用client,key签发证书请求
openssl req -new -key ./client.key -out client.csr
c).也可以设置自定义配置(该配置验证过,需要注释掉/etc/ssl/openssl.cnf的 # RANDFILE = $ENV::HOME/.rnd 否则会报Can't load /root/.rnd into RNG
140032261984704:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
错误)
openssl req -new -key ./client.key -out client.csr -subj "/C=CN/ST=Shanghai/L=Shanghai/O=EMQ/CN=mqtt-client.xxx.com"
备注:此方法在windows上无法通过,是由于环境没有做好,为少麻烦还是建议用ubuntu吧
4).用根证书ca来签发实体client的实体证书:
a).用自定义的配置openssl.cnf
openssl x509 -req -in ./client.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out client.crt -days 3650 -sha256 -extensions v3_req -extfile ./openssl.cnf
b)..用默认的配置生成
openssl x509 -req -in ./client.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out client.crt -days 3650 -sha256
5).查看证书:
openssl x509 -in ./client.crt -noout -text
内容省略
6).验证签发证书是否被根证书通过:
openssl verify -CAfile ./ca.crt ./client.crt
备注:要是失败说明验证不通过,检查生成文件失败的原因,重新生成,下面是通过的
sudo openssl verify -CAfile ./ca.crt ./client.crt
./client.crt: OK
四:用openssl单向认证测试
1).在一个终端开启server:
openssl s_server -accept 2009 -key ./emqx.key -cert ./emqx.crt
2).在另一个终端开启client:
openssl s_client -connect localhost:2009 -key ./client.key -cert ./client.crt -CAfile ./ca.crt -showcerts
出现下面说明通过:并且在此状态client 输入啥,server侧也会出现相同数据
......
0b0 - 0f cb 29 3d 6e 1a 0c 71-52 1b 36 80 4a 12 96 61 ..)=n..qR.6.J..a
Start Time: 1621504608
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
五: 用openssl 双向认证测试:
1).在一个终端开启server:
openssl s_server -accept 2009 -key ./emqx.key -cert ./emqx.crt -CAfile ./ca.crt -Verify 5
2).在另一个终端开启client:
openssl s_client -connect localhost:2009 -key ./client.key -cert ./client.crt -CAfile ./ca.crt -showcerts
出现下面说明通过:并且在此状态client 输入啥,server侧也会出现相同数据:
.....
0400 - 2f cb 98 e0 45 0b 59 d7-e5 89 f6 ab 90 3f 35 b3 /...E.Y......?5.
Start Time: 1621504956
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
六:在EMQX与MQTTX上验证:
1).将生成的ca.crt /emqx.key /emqx.crt /emqx.key /client.key /client.crt给最高权限(可读可写)
sudo chmod 777 ca.crt /emqx.key /emqx.crt /emqx.key /client.key /client.crt
**注意:这步一定要做非则在client连接的时候会一直出现ERROR: TSL相关的错误**
**注意:这步一定要做非则在client连接的时候会一直出现ERROR: TSL相关的错误**
**注意:这步一定要做非则在client连接的时候会一直出现ERROR: TSL相关的错误**
2).将ca.crt /emqx.key /emqx.crt /emqx.key 拷贝到/etc/emqx/certs下面
备注:建议将该文件下的做个备份,有备无患嘛
3).更改/etc/emqx/emqx.conf配置文件:
sudo vi /etc/emqx/emqx.conf
## MQTT/SSL - External SSL Listener for MQTT Protocol
## listener.ssl.$name is the IP address and port that the MQTT/SSL
## listener will bind.
##
## Value: IP:Port | Port
##
## Examples: 8883, 127.0.0.1:8883, ::1:8883
listener.ssl.external = 8883
....
## Value: File
listener.ssl.external.keyfile = /etc/emqx/certs/emqx.key
## Path to a file containing the user certificate.
##
## See: http://erlang.org/doc/man/ssl.html
##
## Value: File
listener.ssl.external.certfile = /etc/emqx/certs/emqx.crt
## Path to the file containing PEM-encoded CA certificates. The CA certificates
## are used during server authentication and when building the client certificate chain.
##
## Value: File
listener.ssl.external.cacertfile = /etc/emqx/certs/ca.crt
....
## Value: verify_peer | verify_none
## listener.ssl.external.verify = verify_pee
....
## Value: true | false
## listener.ssl.external.fail_if_no_peer_cert = true
备注:listener.ssl.external.verif和listener.ssl.external.fail_if_no_peer_cert用默认值
4).保存好后启动EMQX:
sudo emqx foreground 或者 sudo emqx start
5).MQTTX 客户端如下配置:
七:到此就验证完了:
如果此时还是无法连接成功,四五验证能通过,就是生成的证书文件权限没有给,不然换个EMQX的版本吧,本人用的4.2.8和4.3.1都能通过。