emqtt安全连接ssl配置 自签证书 单向认证连接 加密 ssl/tls,mosquitto客户端ssl单向认证连接测试

  • 前言
    考虑到项目通讯安全问题,决定将emqtt 服务器配置ssl/tls 加密连接,行动起来,经历了千辛万苦后终于完成,整个过程简直多灾多难! 网上相关文章本来就不多,更坑的是要么不全要么不行,吐血。当然吐槽归吐槽感谢还是需要的,至少也能做参考。
    既然我在这个过程中遇到了这么多的问题,那么后面肯定还会有很多朋友也会遇到,所以呢我就将我的整个操作流程记录下来,希望能对你们有所帮助,当然如果写的不好,哪里有问题 还请在评论指出,我会关注评论及时修改,谢谢。

  • 系统
    centos6.8

  • 术语

    • tls 和 ssl的区别
      简单来说:TLS:(Transport LayerSecurity,传输层安全协议),是IETF(工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。

    • 单向认证和双向认证
      双向认证和单向认证原理基本差不多,只是除了客户端需要认证服务端以外,增加了服务端对客户端的认证
      在这里插入图片描述
      在这里插入图片描述

      参考文章
      https://blog.csdn.net/duanbokan/article/details/50847612
      https://blog.csdn.net/ustccw/article/details/76691248

  • 关于单向认证双向认证 证书到期更新问题

    • 双向认证,之前的项目中没有遇到过双向认证连接处理过程,在此我也不太好分析什么,总之双向认证证书到期更换是一个问题。

    • 单向认证, 在客户端 可以不去认证服务端证书,也就是不需要保存任何证书,不存在更新证书的问题。这时可能就有人提问了,上面不是介绍单向认证过程中 客户端需要校验服务端的证书吗,如下图:(而且下面mosquitto客户端ssl 单向认证连接测试 也指定了要校验的服务端证书)
      在这里插入图片描述
      没错,这里确实有要验证服务端证书的步骤,但是我们可以在客户端 修改 ssl/tls 连接方法中验证服务器证书的代码,永远返回 验证成功!我的另外一篇博文有一个 java服务端、android示例代码源码: https://blog.csdn.net/a704397849/article/details/88903833
      如果是ios的话我没有验证过你可以看看这篇(我不保证是否可行,毕竟我没弄过ios ) https://blog.csdn.net/g510941365/article/details/56682720

    • 如果你有类似的问题 ‘服务端证书到期 客户端要不要更新证书’ , 相信上面的描述 应该能给你解惑。(写这句话的原因是 我之前就有过这样的疑惑,然而没有人替我解答,只能自己慢慢摸索得知. o(╥﹏╥)o)

  • 操作过程
    创建自签根证书和服务端证书
    设置 emqtt配置文件中 ssl/tls 单向连接参数
    安装mqtt客户端 mosquitto 用 ssl 单向安全连接 emqtt 服务器验证emqtt配置ssl/tls 是否成功

1 创建自签根证书和服务端证书

[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl genrsa -out MyRootCA.key 2048
Generating RSA private key, 2048 bit long modulus
.+++
.........................+++
e is 65537 (0x10001)
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl req -new -key MyRootCA.key -out MyRootCA.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname"
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# ll
total 8
-rw-r--r-- 1 root root 1013 Mar 28 20:07 MyRootCA.csr
-rw-r--r-- 1 root root 1675 Mar 28 19:58 MyRootCA.key
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey MyRootCA.key -in MyRootCA.csr -out MyRootCA.crt
Signature ok
subject=/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname
Getting Private key
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# ll
total 12
-rw-r--r-- 1 root root 1224 Mar 28 20:14 MyRootCA.crt
-rw-r--r-- 1 root root 1013 Mar 28 20:07 MyRootCA.csr
-rw-r--r-- 1 root root 1675 Mar 28 19:58 MyRootCA.key
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl genrsa -out MyServer.key 2048
Generating RSA private key, 2048 bit long modulus
.......................................................................+++
.............................................................................+++
e is 65537 (0x10001)
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl req -new -key MyServer.key -out MyServer.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname"
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# openssl x509 -req -days 365 -sha1 -extensions v3_req -CA MyRootCA.crt -CAkey MyRootCA.key -CAserial ca.srl -CAcreateserial -in MyServer.csr -out MyServer.crt
Signature ok
subject=/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname
Getting CA Private Key
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# 
[root@iZwz9alst6rugc21rx2ggtZ mycerts]# ls
ca.srl  MyRootCA.crt  MyRootCA.csr  MyRootCA.key  MyServer.crt  MyServer.csr  MyServer.key

上面生成证书过程出现的命令参数解释:

  • 生成根证书

    • 1), 根证书私钥
      openssl genrsa -out MyRootCA.key 2048

      genrsa——使用RSA算法产生私钥
      -out——输出文件的路径
      -des3 是指加密算法,当然也可以选用其他你认为安全的算法. 如有这个参数选项会提示输入密码
      2048——指定私钥长度2048

    • 2), 生成证书请求文件(csr文件)
      openssl req -new -key MyRootCA.key -out MyRootCA.csr -subj “/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname”

      req——执行证书签发命令
      -new——新证书签发请求
      -key——指定私钥路径
      -out——输出的文件的路径
      -subj——证书相关的用户信息(subject的缩写)

    • 3), 自签发 根 证书
      openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey MyRootCA.key -in MyRootCA.csr -out MyRootCA.crt

      x509——生成x509格式证书
      -req——输入csr文件
      -days——证书的有效期(天)
      -sha1——证书摘要采用sha1算法
      -extensions——按照openssl.cnf文件中配置的v3_ca项添加扩展
      -signkey——签发证书的私钥
      -in——要输入的csr文件
      -out——输出的证书文件

  • 生成 server端 证书

    • 1), 生成服务端私钥
      openssl genrsa -out MyServer.key 2048
      参数解释同上

    • 2), 生成证书请求文件(csr文件)
      openssl req -new -key MyServer.key -out MyServer.csr -subj “/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myname”
      参数解释同上

    • 3), 用 根 证书 签发 服务端 证书
      openssl x509 -req -days 365 -sha1 -extensions v3_req -CA MyRootCA.crt -CAkey MyRootCA.key -CAserial ca.srl -CAcreateserial -in MyServer.csr -out MyServer.crt

      -CA——指定CA证书的路径
      -CAkey——指定CA证书的私钥路径
      -CAserial——指定证书序列号文件的路径
      -CAcreateserial——表示创建证书序列号文件(即上方提到的serial文件),创建的序列号文件默认名称为-CA,指定的证书名称后加上.srl后缀
      其他同上

  • 客户端证书生成 …略 (我只想用单向安全连接 ,不需要客户端证书。)

参考:https://my.oschina.net/itblog/blog/651434

2 设置 emqtt配置文件中 ssl/tls 单向连接参数

  • 如果还没有安装emqtt ,可以看下我前面的博文:https://blog.csdn.net/a704397849/article/details/88533875

  • 配置ssl/tls 文件在 emq安装目录下 etc/emq.conf
    在这里插入图片描述
    将下面我所展示的配置 在emq.conf中 去掉前面的 #或## 注释,如果配置文件中没有,那就手动添加,
    keyfile 和 certfile 配置证书路径 改成 上面生成的证书所在路径

## SSL
##默认配置
listener.ssl.external = 8883
listener.ssl.external.acceptors = 16
listener.ssl.external.max_clients = 1024
listener.ssl.external.access.1 = allow all
listener.ssl.external.handshake_timeout = 15s

##
listener.ssl.external.zone = external
listener.ssl.external.tls_versions = tlsv1.2,tlsv1.1,tlsv1

##下面2行是需要 注意 的配置
listener.ssl.external.keyfile = etc/mycerts/MyServer.key

listener.ssl.external.certfile = etc/mycerts/MyServer.crt


## SSL Socket Options 这些是默认配置
listener.ssl.external.backlog = 1024
listener.ssl.external.recbuf = 4KB
listener.ssl.external.sndbuf = 4KB
listener.ssl.external.buffer = 4KB
listener.ssl.external.nodelay = true

配置文件修改保存后,重启emqtt 服务器

参考文章:
https://www.jianshu.com/p/1602f6db1aa1 (这篇仅做参考)
https://blog.csdn.net/CharlesSimonyi/article/details/88381216

3 mosquitto客户端安装, ssl单向认证连接mqtt服务器 验证mqtt服务器 ssl是否配置成功

  • mosquitto客户端安装 参考博文:https://blog.csdn.net/a704397849/article/details/88895009
    (如果不想用 mosquitto客户端验证 mqtt服务器tls是否配置成功,懂java代码的可以看下我的另一篇博文: https://blog.csdn.net/a704397849/article/details/88903833)

  • 安装成功后 ,用ssl 协议 单向认证连接mqtt服务器 并订阅 test
    在这里插入图片描述
    ./mosquitto_sub -h xxx.xx.xxx.xxx -t test -p 8883 -d --cafile /MyServer.crt --insecure
    注意:先进入mosquitto_sub所在目录,再执行./mosquitto_sub …
    我将MyServer.crt 复制到了 / 目录下,所以这里可以是 --cafile /MyServer.crt , 你们需要根据自己MyServer.crt 所放位置做修改。

    命令参数解释
    mosquitto_sub 订阅消息
    -h 访问的mqtt服务器地址
    -t 是订阅的主题 , test 就是一个主题
    -p 端口8883 ,上面ssl协议配置中端口就是8883
    –cafile 指定服务端的证书
    –insecure 用于忽略服务端证书认证 (单向认证,客户端不需要认证服务端证书)
    更多详细参数介绍:https://www.jianshu.com/p/511cc22fa700

  • 如果连接失败,确认下8883端口是不是有权限,证书是不是弄错了等等。
    也可以看下emq 服务器 log/error.log 日志信息,根据提示去找问题所在 ,如:

2019-03-28 22:00:58.987 [error] <0.1336.0> SSL: certify: ssl_alert.erl:88:Fatal error: unknown ca
2019-03-28 22:25:15.219 [error] <0.1393.0> SSL: certify: ssl_alert.erl:88:Fatal error: certificate unknown

最后
本文只是介绍了 自签的证书 配置 emqtt ssl/tls 连接,后面会介绍使用第三方权威机构签发证书 配置emqtt ssl/tls 连接,以及更多mqtt客户端 使用案例(mosquitto , eclipse paho mqtt 等).

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值