目录
连接MQTT服务端
MQTT客户端要想连接服务端,首先要向服务端发送CONNECT报文。如果此CONNECT报文的格式或内容不符合MQTT规范,则服务器会拒绝客户端的连接请求。
Clean Session – 清除会话,属于MQTT3.1/3.11协议,在MQTT5.0变更为Clean Start
如果cleanSession 被设置为“true”。那么服务端不需要客户端确认收到报文,也不会保存任何报文,如果被设置为“false”,则需要客户端确认收到报文。详解下面链接:
MQTT 持久会话与 Clean Session 详解 | EMQ
Clean Start 与 Session Expiry Interval 介绍与示例 | MQTT 5.0 特性详解 | EMQ
发布、订阅
MQTT客户端发布消息时,会向服务端发送PUBLISH报文。以下是PUBLISH报文的详细信息
Topic 主题
注意:主题是区分大小写的,主题可以使用空格(但不建议),以$开始的主题是MQTT服务端系统保留的特殊主题,我们不能随意订阅或者向其发布信息,不要用 “/” 作为主题开头(允许但不建议),单级通配符“+”仅可代替一个主题级别,而多级通配符”#”可以涵盖任意数量的主题级别。如下示例所示, 多级通配符必须是主题中的最后一个字符。
home/sensor/+/temperature home/sensor/#
通配符
单层通配符:加号 “+” 是用于单个主题层级匹配的通配符
+ 有效 sensor/+ 有效 sensor/+/temperature 有效 sensor+ 无效(没有占据整个层级)
多层通配符:井号“#” 是用于匹配主题中任意层级的通配符。多层通配符表示它的父级和任意数量的子层级,使用多层通配符时,它必须占据整个层级并且必须是主题的最后一个字符
# 有效,匹配所有主题 sensor/# 有效 sensor/bedroom# 无效(没有占据整个层级) sensor/#/temperature 无效(不是主题最后一个字符)
QoS 服务质量
MQTT 中的 QoS (服务质量)指的是发布者与订阅者之间消息传递的保证级别。QoS 等级从低到高,意味着消息可靠性的提升,也意味着传输复杂程度的提升。
- QoS 0 – 最多交付一次
- QoS 1 – 至少交付一次
- QoS 2 – 只交付一次(有且仅有,不会丢消息)
注意:QoS等级不仅在发布方指定,也在订阅方指定。当发布方和订阅方指定的QoS等级不同时,服务端会选择发布消息和订阅消息中较低的QoS来实现消息传输,这也被称作”服务降级"。
MQTT QoS 0、1、2 解析:快速入门指南 | EMQ
2-1 QoS 服务质量等级 – 太极创客
MQTT的数据内容及服务质量QoS设置_mqtt qos怎么设置-优快云博客
Retain 保留消息
发布者发布消息时,如果Retained标记被设置为true,则该消息即是MQTT中的保留消息(Retained Message)。MQTT服务器会为每个主题存储最新一条保留消息,以方便消息发布后才上线的客户端在订阅主题时仍可以接收到该消息。
借助保留消息,新的订阅者能够立即获取最近的状态,而不需要等待无法预期的时间。
应用场景:假设某智能家居系统,客户端A每个整点向服务器主题X发送传感器数据,客户端B订阅服务器X主题显示传感器数据,某天中午12点客户端A已经将最新的数据上报服务器,而客户端B在12点10分断了一次网,网络恢复后客户端B会自动订阅服务器上的主题X,但下一次数据的发布时间在13点,13点前客户端B无法获知数据进行显示。
为了避免以上情况出现,我们可以让客户端A在每次向X主题发布消息时都使用“保留消息”这一模式将传感器数据发布到服务端。这样无论显示客户端B在任何时间订阅室温主题,都会马上收到该主题中的“保留消息”,也就是客户端A发布的最新消息。
删除保留消息的方法:向该主题发布一条空的保留消息,或者在服务器后台删除。
Will Message 遗嘱消息
MQTT协议中的遗嘱机制允许客户端在连接时指定一条遗嘱消息
当客户端意外断线时服务端会发布这条遗嘱消息,订阅该主题的客户端都会收到这个消息
遗嘱机制的目的是在客户端意外断线时通知其他设备客户端的状态变化。遗嘱消息在客户端发起连接时指定,它和 Client ID、Clean Start 这些字段一起包含在客户端发送的 CONNECT 报文中。与普通消息一样,可以为遗嘱消息设置主题(Will Topic)、保留消息标识位(Will Retain)、属性(Will Properties)、QoS(Will QoS)和有效载荷(Will Payload)
应用场景:假设我们有一个传感器监控一个很少变化的值,普通的实现是定期发布最新数值,但更好的实现是仅在数值发生变化时以保留消息的形式发送它。这使得任何新的订阅者总能立即获得当前值,而不必等待传感器再一次发布。不过订阅者也因此没有办法根据是否及时收到消息来判断传感器是否离线。借助遗嘱消息,我们可以立即得知传感器保持活动超时,而且不必总是获取传感器发布的值。
如果客户端在连接时指定了遗嘱消息,那么服务端就会将该遗嘱消息存储在相应的会话中,直到以下任一条件满足时发布它:
- 服务端检测到了一个 I/O 错误或者网络故障
- 客户端在 Keep Alive 时间内未能通讯
- 客户端在没有发送 Reason Code 为 0x00(正常关闭)的 DISCONNECT 报文的情况下关闭了网络连接
- 服务端在没有收到 Reason Code 为 0x00(正常关闭)的 DISCONNECT 报文的情况下关闭了网络连接,例如客户端的报文或行为不符合协议要求而被服务端关闭连接。
简单起见,我们可以直接概括为,只要网络连接在服务端没有收到 Reason Code 为 0x00 的 DISCONNECT 报文的情况下关闭,那么服务端都需要发送遗嘱消息。
进阶:Will Delay Interval 延时发布等,详解下面链接
遗嘱消息(Will Message)介绍与示例 | MQTT 5.0 特性详解 | EMQ
2-6 MQTT遗嘱 – 太极创客
MQTT认证
在使用MQTT协议时,安全认证是非常重要的环节。以下是几个核心概念的介绍:
SSL/TLS
SSL (Secure Sockets Layer) 和 TLS (Transport Layer Security) 是加密协议,用于在网络通信中提供安全保障:
- SSL:早期的安全协议,现已逐渐被TLS取代
- TLS:SSL的继任者,目前广泛使用的安全协议(如TLS 1.2、TLS 1.3)
- 作用:提供加密通信、数据完整性验证和服务器身份认证
- 在MQTT中:通常使用TLS来加密MQTT通信(MQTT over TLS,端口通常为8883)
MQTT TLS认证类型
-
单向TLS认证:客户端验证服务器证书
- 服务器提供CA签发的证书
- 客户端需要CA的根证书来验证服务器证书
-
双向TLS认证(mTLS):客户端和服务器互相验证证书
- 服务器和客户端都提供CA签发的证书
- 双方都需要对方的CA证书来验证身份
认证方式 | 说明 | 验证方式 | 优缺点 |
---|---|---|---|
单向认证 | 客户端验证服务器身份,但服务器不验证客户端的身份 | 客户端通常不需要提供证书,仅需验证服务器的证书是否由受信任的证书颁发机构(CA)签发 | 只能实现通信数据的机密性和完整性,但无法保证通信双方的身份 |
双向认证 | 服务器和客户端彼此验证对方的身份 | 需要为每个设备签发证书,服务器验证客户端的证书以确认其身份的合法性 | 可以确保服务器和客户端之间的互信关系,并防止中间人攻击 |
数字证书、CA、X.509证书
数字证书
数字证书是互联网通讯中标志通讯各方身份信息的一串数字,一般是由权威的第三方机构——CA机构发行的(也有自签名证书情况),用于在互联网上验证通信实体的身份。数字证书包含了公钥、持有者身份信息和CA的数字签名等关键内容,具有安全、唯一性的特点。
数字证书的基本原理涉及非对称加密、信任链和数字签名。每个参与者都有一对公钥和私钥,公钥可以公开分享,而私钥必须保密。数字签名则是用私钥对数据(如证书、文件或消息)进行加密产生的,可以用对应的公钥进行验证,以确保信息是由持有私钥的实体签发,并且没有被篡改。
数字证书有多种类型,根据应用场景和用途的不同,可以分为SSL/TLS证书、代码签名证书、邮件签名证书和客户端证书等。每种证书在PKI(公钥基础设施)中扮演不同的角色,如SSL/TLS证书有助于客户端浏览器与Web服务器之间进行安全的加密连接,代码签名证书则用于确认软件的出版者身份和代码未被篡改。
CA
CA(Certificate Authority)机构,即证书颁发机构,是负责签发证书、认证证书、管理已颁发证书的权威第三方机构。CA机构通过验证实体的身份并为其颁发数字证书,从而建立起互联网上的信任机制。
CA机构的主要功能包括:
- 验证:当一个网站或组织向CA申请数字证书时,CA会根据申请的证书类型完成其验证过程。这包括域名验证、企业验证和扩展验证等不同级别的验证,以确保申请者身份的真实性和合法性。
- 颁发:在验证通过后,CA会为申请者颁发数字证书。该证书包含了申请者的身份信息、公钥以及CA的数字签名等信息,可以用于在互联网上验证申请者的身份。
- 管理:CA还需要维护证书吊销列表(CRL),这些列表是指证书在到期之前何时失效。客户端可以联系CA检查这个吊销列表,以确保所使用的证书仍然有效。
CA 证书就是CA颁发的证书。 CA证书也就我们常说的数字证书,包含证书拥有者的身份信息,CA机构的签名,公钥和私钥。身份信息用于证明证书持有者的身份;CA签名用于保证身份的真实性;公钥和私钥用于通信过程中加解密,从而保证通讯信息的安全性。
X.509证书
X.509证书和CA证书是标准与实现的关系。
对比项 | X.509证书 | CA证书 |
---|---|---|
本质 | 国际电信联盟(ITU)制定的证书格式标准 | 符合X.509标准的特殊用途证书 |
内容要求 | 规定证书包含的字段(版本号、序列号、公钥等) | 必须包含Basic Constraints: CA=TRUE 扩展 |
密钥用途 | 取决于证书类型 | 必须包含keyCertSign (证书签名权限) |
典型文件扩展名 | .crt, .pem, .der | 同左,但通常命名为ca.crt 等 |
参考:https://zhuanlan.zhihu.com/p/351481196
数字证书与CA权威机构全解析-百度开发者中心
百度安全验证
在EMQX中开启TLS认证
在EMQX中开启TLS认证,这个官方文档描述的很清楚:开启 SSL/TLS 连接 | EMQX文档
我的默认证书位于D:\EMQX\emqx5.3.2\etc\certs\
在MQTTX上如何配置TLS认证相关内容,这个官方文档描述的很清楚:开始使用 - MQTTX 文档
这里面说明几点:
开启这个之后,服务器会验证客户端的证书
开启这个之后,客户端会验证服务器的证书
在实际测试中,服务器成功验证了客户端证书,但客户端在验证服务器证书时出现了下面报错
意思是不能通过IP地址,要通过域名,因此更换为localhost,又报下面错误
想来可能是域名不对(毕竟是自己本地搭的服务器),或者证书的问题,但是整体流程大概是对的,后续有时间再自己生成一个证书,或者使用明确已知域名的服务器尝试。
参考:百度安全验证
[MQTT]服务器EMQX搭建SSL/TLS连接过程(wss://)_emqx wss-优快云博客
https://zhuanlan.zhihu.com/p/159099319
EMQX遗留的bug:
使用保留消息时,无论是broker.emqx.io还是自己搭建的EMQX服务器,都仅在保留消息QoS设置为0或1时可行,为0时不行
使用保持会话时,使用broker.emqx.io,客户端重新上线后可以立即收到服务器缓存的消息,使用自己搭建的EMQX只能在客户端上线并且关闭客户端时收到
可能和服务器有关系,最新版本:下载 EMQX 开源版