作为基于现代密码学公钥算法的安全协议,TLS/SSL能在计算机通讯网络上保证传输安全,EMQ的MQTT broker支持TLS,也可以用这种方式来确保传输安全。

参考官网:https://www.emqx.io/cn/blog/emqx-server-ssl-tls-secure-connection-configuration-guide

TLS/SSL带来的安全优势

  • 强认证。 用TLS建立连接的时候,通讯双方可以互相检查对方的身份。在实践中,很常见的一种身份检查方式是检查对方持有的X.509数字证书。这样的数字证书通常是由一个受信机构办法的,不可伪造。
  • 保证机密性 TLS通讯的每次会话都会由会话密钥加密,会话密钥有通讯双方协商产生。任何第三方都无法知晓通讯内容。即使一次会话的密钥泄露,并不影响其他会话的安全性。
  • 完整性。 加密通讯中的数据很难被篡改而不被发现。

接下来EMQ君将介绍TLS/SSL协议以及如何在EMQ上启用。

TLS/SSL协议

TLS/SSL协议下的通讯过程分为两部分,第一部分是握手协议。握手协议的目的是鉴别对方身份并建立一个安全的通讯通道。握手完成之后双方会协商出接下来使用的密码套件和会话密钥;第二部分是record协议,redord和其他数据传输协议非常类似,会携带内容类型,版本,长度和荷载等信息,不同的是它所携带的信息是加密了的。

下面的图片描述了TLS/SSL握手协议的过程,从客户端的“hello”一直到服务器的“finished”完成握手。有兴趣的同学可以放狗找更详细的资料看。对这个过程不了解也并不影响我们在EMQ中启用这个功能。

在EMQ中启用TLS/SSL的准备工作

通常来说,我们会需要数字证书来保证TLS通讯的强认证。数字证书的试用本身是一个三方协议,除了通讯双方,还有一个颁发证书的受信第三方,有时候这个受信第三方就是一个CA。和CA的通讯,一般是以预先发行证书的方式进行的。也就是在开始TLS通讯的时候,我们需要至少有2个证书,一个CA的,一个EMQ的,EMQ的证书由CA颁发,并用CA的证书验证。如果要做双向认证,还会用到一个客户端证书。

获得一个真正受外界信任的证书会有一定的开销。在实验室环境,我们可以用自己生成的证书来模拟这个过程。接下来的演示,EMQ君就是用的这个方法。

在这里,我们假设您的系统已经安装了OpenSSL。试用OpenSSL附带的工具集就可以生成我们需要的证书了。

首先,我们需要一个自签名的CA证书。生成这个证书需要有一个私钥为它签名,如果还没有合适的私钥的话,可以在命令行上执行以下命令来生成一个:

openssl genrsa -out MyRootCA.key 2048

这个命令将生成一个密钥长度2048的密钥并保存在MyRootCA.key,有了这个密钥,就可以用它来生成EMQ broker的根证书了,请求中需要填写一些信息,尽量和下面新建的openssl.cnf文件中的信息一样:

 openssl req -x509 -new -nodes -key MyRootCA.key -sha256 -days 3650 -out MyRootCA.pem 

根证书是整个信任链的起点,如果一个证书的每一级签发者向上一直到根证书都是可信的,那个我们就可以认为这个证书也是可信的。有了这个根证书,我们就可以用它来给其他实体签发实体证书了。

生成server端秘钥和证书

实体(在这里就是EMQ Broker)也需要一个自己的私钥对来保证它对自己证书的控制权。生成这个密钥的过程和上面类似:

openssl genrsa -out MyEMQ.key 2048

新建 openssl.cnf 文件,

  • req_distinguished_name :根据情况进行修改,
  • alt_names: BROKER_ADDRESS 修改为 EMQ X 服务器实际的 IP 或 DNS 地址,例如:IP.1 = 127.0.0.1,或 DNS.1 = broker.xxx.com
[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 = Jiangsu
localityName = Suzhou
organizationName = test.io
commonName = www.test.com
[req_ext]
subjectAltName = @alt_names
[v3_req]
subjectAltName = @alt_names
[alt_names]
## IP.1 = BROKER_ADDRESS
DNS.1 = www.test.com

然后以这个密钥签发一个证书请求,请求中需要填写一些信息,尽量和上面新建的openssl.cnf文件中的信息一样:

openssl req -new -key ./MyEMQ.key -config openssl.cnf -out MyEMQ.csr
然后以根证书来签发EMQ Broker的实体证书了:

openssl x509 -req -in ./MyEMQ.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAcreateserial -out MyEMQ.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf

现在,我们可以启用EMQ的TLS/SSL连接了

在EMQ Broker上启用TLS/SSL

启用TLS/SSL的过程是比较简单的,只需要修改emq.conf文件中的一些配置就可以了:

listener.ssl.external = 8883

#private key for emq cert:
listener.ssl.external.keyfile = etc/certs/MyEMQ.key #emq cert:
listener.ssl.external.certfile = etc/certs/MyEMQ.pem #CA cert:
listener.ssl.external.cacertfile = etc/certs/MyRootCA.pem

重启EMQ后,用mosquittu_sub来验证TLS是否正常启动:

然后以根证书来签发EMQ Broker的实体证书了:

mosquitto_sub -t abc -h 192.168.238.132 -p 8883 -d --cafile ~/test_certs/MyRootCA.pem  --insecure

Client mosqsub|10617-Zhengyus- sending CONNECT
Client mosqsub|10617-Zhengyus- received CONNACK
Client mosqsub|10617-Zhengyus- sending SUBSCRIBE (Mid: 1, Topic: abc, QoS: 0)
Client mosqsub|10617-Zhengyus- received SUBACK
Subscribed (mid: 1): 0

这个结果和我们期待的一样。moqsuitto客户端通过TLS/ssl正常连接并订阅主题。

如果我们从EMQ的Dashboard上看的话,可以看到在8883端口上有一个mqtt:ssl连接:

启用TLS/SSL的双向验证

在一些对于身份验证要求比较严格的场景,也会要求EMQ对客户端的身份用证书进行验证。这时候就需要启动双向验证了。

emq.conf中启动对对端的证书验证:

#enable the client side certificates
listener.ssl.external.verify = verify_peer

emq.conf中强制对对端的证书验证:

#set it to 'true' to allow the ssl with client side certificate only
listener.ssl.external.fail_if_no_peer_cert = true

完成上面的步骤后,如果我们再想用之前的方式连接EMQ,客户端就会被拒绝:

mosquitto_sub -t abc -h emq1 -p 8883 -d --cafile ~/test_certs/MyRootCA.pem  --insecure
Client mosqsub|10738-Zhengyus- sending CONNECT
Error: A TLS error occurred.

生成client端秘钥和证书

现在我们试用和生成服务器端证书一样的方法来生成客户端证书:

openssl genrsa -out MyClient.key 2048
openssl req -new -key ./MyClient.key -config openssl.cnf -out MyClient.csr
openssl x509 -req -in ./MyClient.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAcreateserial -out MyClient.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf

修改mosquitto_sub的命令行启动客户端证书验证:

mosquitto_sub -t abc -h 192.168.238.132 -p 8883 -d --key ~/test_certs/MyClient.key --cert ~/test_certs/MyClient.pem --cafile ~/test_certs/MyRootCA.pem  --insecure
Client mosqsub|10796-Zhengyus- sending CONNECT
Client mosqsub|10796-Zhengyus- received CONNACK
Client mosqsub|10796-Zhengyus- sending SUBSCRIBE (Mid: 1, Topic: abc, QoS: 0)
Client mosqsub|10796-Zhengyus- received SUBACK
Subscribed (mid: 1): 0

也可以尝试python客户端:

import paho.mqtt.client as mqtt
import json, os

sub_list = [("abc", 0), ('pub', 2)]

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    # 连接成功回调
    result, mid = client.subscribe(sub_list)
    # print('result:', result)
    # print('mid:', mid)

# 接收到消息的回调方法
def on_message(client, userdata, msg):
    payload = msg.payload.decode()
    print(msg.topic)
    print(payload)
    # print(msg.topic + ":" + payload)

if __name__ == '__main__':
    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_message = on_message
    # client.username_pw_set("username", "pwd")
    crtPath = os.path.dirname(os.path.abspath(__file__)) + r"\crt"
    ca_certs = "%s\ca\MyRootCA.pem" % crtPath
    certfile = "%s\client\MyClient.pem" % crtPath
    keyfile = "%s\client\MyClient.key" % crtPath
    print(ca_certs)
    client.tls_set(ca_certs=ca_certs,
                   certfile=certfile,
                   keyfile=keyfile,
                   )
    client.tls_insecure_set(True)

   
    HOST = "192.168.238.132"

    client.connect(HOST, 8883, 30)
    # client.loop_forever()

    client.loop_start()

    while True:
        str = input()
        if str:
            client.publish("abc", str, 0)
 


 

用TLS/SSL保证EMQ的网络传输安全的更多相关文章

  1. TLS / SSL密码强化的建议

    TLS / SSL密码强化的建议 传输层安全性(TLS)及其前身安全套接字层(SSL)是广泛使用的协议,旨在通过身份验证,加密和完整性来保护客户端和服务器之间的数据传输安全. 与常见假设相反,TLS ...

  2. x-pack 功能介绍及配置传输层安全性(TLS / SSL)

    x-pack 功能介绍及配置传输层安全性(TLS / SSL) 学习了:https://blog.csdn.net/wfs1994/article/details/80411047

  3. 在SuperSocket中启用TLS/SSL传输层加密

    关键字: TLS, SSL, 传输层加密, 传输层安全, 证书使用, X509Certificate SuperSocket 支持传输层加密(TLS/SSL) SuperSocket 有自动的对TLS ...

  4. 网络传输中的各种加密算法+SSL+CA证书详解

    1. 数据传输分类 在互联网上数据传输有两种:明文传输和加密传输.明文传输的协议有:ftp.http.smtp.telnet.但是为了数据的完整性和安全性,所以后来引用了加密等相关手段来保证数据的安全 ...

  5. Android : 关于HTTPS、TLS/SSL认证以及客户端证书导入方法

    一.HTTPS 简介 HTTPS 全称 HTTP over TLS/SSL(TLS就是SSL的新版本3.1).TLS/SSL是在传输层上层的协议,应用层的下层,作为一个安全层而存在,翻译过来一般叫做传 ...

  6. [转帖]技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

    技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解    http://www.52im.net/thread-1309-1-1.html   本文来自腾讯资深研发工程师罗成的技术分享, ...

  7. TCP和TLS/SSL会话细节

    TCP数据段格式说明TCP建立连接和断开连接细节Https如何保证通信安全一次Https网络请求通信细节网络数据包分析工具wireshark的使用问题:SYN.ACK.FIN具体含义是什么?TCP建立 ...

  8. TLS/SSL 梳理

    数据加密通篇都是为了防止第三方的劫持伪造,保证连接安全, 毫无遮掩的明文传输只有民风淳朴的时候才是安全的. 先是一些基础的内容: 对称加密 最开始为了对数据进行加密,使用的是对称加密算法,即双方协商好 ...

  9. 深入TLS/SSL协议

    总体 TLS/SSL协议是为了解决网络通讯中的信息安全问题而诞生的. 它的设计目的主要有三个: 身份验证--搞清楚与我通讯的人是不是我所想的那个. 保密性--就算第三方拿到了通讯内容,也搞不清楚其中所 ...

随机推荐

  1. 提名者周训,misc消失的文件

    下载附件是一个没有后缀的文件,一般这种东西,根据我这个菜狗的经验,直接就是丢进kali的binwalk一顿操作,最后果不其然,是发现了东西的 这里面可以看到一个小细节,就是在binwalk进行分离的时 ...

  2. kali主机探测命令与工具集

    实验目的 熟悉ping.arping.fping.hping3.nbtscan.nping.p0f.xprobe2工具对目标主机的探测方法. 实验原理 目标识别工具发送特殊构造的数据包,根据返回的应答 ...

  3. windev的Trigger触发器,能秒SQL吗?

    有朋友问,"你是不是在写论文?" (此处请想象个表情)"好吧,论文继续!" SQL中,触发器可以看成是一种特殊的存储过程,使用inserted临时表来建立数据关 ...

  4. Oracle之非关系数据库

    什么是非关系型数据库? 非关系型数据库它的全称是Not Only SQL(简称 NoSQL数据库)是用于存储和检索数据的非关系数据库系统.在当今世界,我们不应该只以没有预定义固定模式的表格式存储所有数 ...

  5. jvm添加jmx远程监控

    调JVM监控的时候需要远程连接机器,所以服务器需要开放JMX协议,配置如下. 现在我的项目是jboot-jfinal项目,用的是undertow容器,在启动脚本里面加入 JAVA_OPTS=" ...

  6. Windows原理深入学习系列-访问控制列表-关于安全描述符的补充

    这是[信安成长计划]的第 20 篇文章 0x00 目录 0x01 安全描述符的结构 0x02 两个结构的不同点 0x03 真正的查询方案 0x04 参考文章 0x01 安全描述符的结构 在上一篇文章中 ...

  7. Pycharm新建Python项目

    关于新建项目时配置项目环境(最好是每个项目单独的虚拟Python环境): Python为什么要使用虚拟环境-Python虚拟环境的安装和配置-virtualenv Pycharm创建Python项目 ...

  8. Solon 1.6.30 发布,更现代感的应用开发框架

    相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...

  9. Windows原理深入学习系列-Windows内核提权

    这是[信安成长计划]的第 22 篇文章 0x00 目录 0x01 介绍 0x02 替换 Token 0x03 编辑 ACL 0x04 修改 Privileges 0x05 参考文章 继续纠正网上文章中 ...

  10. Lua中如何实现类似gdb的断点调试—08支持通过包名称添加断点

    在前一篇中我们支持了通过函数名称来添加断点,我们同时也提到了在Lua中一个函数的名称的并不是确定的.准确的说,Lua中的函数并没有名称,所谓名称其实是保存这个函数值的变量的名称. 于是通过函数名称添加 ...