1 前言

MQTT(MQ Telemetry Transport, MQ 遥测传输)。它是一种发布/订阅、极其简单和轻量级的消息传递协议,旨在用于受限设备和低带宽,高延迟或不可靠的网络。设计原则是使网络带宽和设备资源要求最小化,同时还要尝试确保可靠性和一定程度的交付保证。这些原则也使该协议成为新兴的“M2M”或“物联网”连接设备世界的理想选择,并且适用于带宽和电池电量极为宝贵的移动应用。

物联网的前景变得越来越大,尤其是 5G 的到来,各领域如车联网、车载娱乐(AR 等)、智能电网、移动和协作机器人、智能视频监控、智慧城市等等。

5G 物联网用例图

IOT ANALYTICS机构预测到 2025 年全世界运行的物联网设备能达到 342 亿(34.2billion)。各互联网大头公司,如亚马逊、微软、阿里巴巴、腾讯、IBM 等等都推出了物联网云平台。而每个云平台都对 MQTT 协议支持,支持直接将设备通过 MQTT 协议与他们的云平台对接起来。MQTT 是一个开放的协议,我们可以自己去搭建自己的云平台,实现定制化开发,那么在实现 MQTT 安全上有什么需要注意的地方呢?本文从实现了 MQTT 协议的 mosquitto broker 具体示例来讲述。

IOT ANALYTICS物联网激活设备趋势预测图

2 安全实现方式

  • MQTT 协议本身支持用户名和密码实现客户端的身份校验
  • 使用 SSL(升级版本 TLS)对网络数据进行加密(这与 MQTT 协议本身是无关的,会增加网络开销)
  • 通过 Broker 配置对 Topic 的读写权限
  • 使用授权管理插件,实现批量级用户权限和 topic 的读写权限管理

2.1 使用用户名和密码限制连接

通过使用用户名和密码限制连接的方式,客户端连接 broker 时需要设置与 broker 要求的用户名密码才能够连接成功。

mosquitto.conf:

# 指定用户名和密码才能连接brokerallow_anonymous falsepassword_file {your password path}/passwdfile

密码文件的生成:

mosquitto_passwd [ -c | -D ] passwordfile usernamemosquitto_passwd -b passwordfile username passwordmosquitto_passwd -U passwordfile-b    以批处理模式运行。这允许在命令行提供密码,这可以很方便,但应小心使用,因为密码将在命令行和命令历史记录中可见-c    创建一个新的密码文件,如果文件已经存在,则会覆盖。输入命令后,控制台会提示输入新建用户的密码,连续输入两次密码后,则密码文件创建完成-D    从密码文件中删除指定的用户-U    此选项可用于使用哈希密码将带有纯文本密码的密码文件升级/转换为一个密码文件

2.2 使用 SSL(升级版本 TLS)对网络数据进行加密

使用 TLS 对网络数据加密,需要在配置文件中指定认证文件、密钥文件。

mosquitto.conf:

cafile {your file path}/m2mqtt_ca.crtcertfile {your file path}/m2mqtt_srv.crtkeyfile {your file path}/m2mqtt_srv.key

如何签发证书,查看另一篇文章“使用 TLS 和 Mosquitto Broker 实现安全通信之密钥和证书生成”;

2.3 配置 Broker ACL

通过设置 Broker ACL,可以限制指定用户对指定 Topic 的数据读写权限。

mosquitto.conf:

# 配置acl_file参数为指定acl文件acl_file {your file path}/aclfile

aclfile 文件内容示例:

# 如下配置会影响没有用户名的客户端的访问控制# topic [read|write|readwrite] topic read $SYS/## 如下配置会影响用户名为 "roger" 的访问控制.user rogertopic foo/bar# 如下配置会影响所有客户端# pattern [read|write|readwrite] pattern write $SYS/broker/connection/%c/state

2.4 使用授权管理插件,实现批量级用户权限和 topic 的读写权限管理

使用授权管理插件 https://github.com/jpmens/mosquitto-auth-plug

该插件可以执行身份验证(检查用户名/密码)和授权(通过 ACL 授予订阅和/或发布特定主题的许可),通过与数据库绑定,将身份验证和 ACL 管理录入数据库,从而很方便的实现用户身份验证管理。该插件对数据库 mysql 及 mongodb 支持很友好。具体怎么使用可以参考 README。这里仅给出 mysql 配置示例。

mosquitto.conf:

# 指定插件所需动态库auth_plugin /usr/mosquitto/bin/auth-plug.so# 指定后端数据库auth_opt_backends mysql# 指定数据库主机地址auth_opt_host localhost# 指定数据库访问端口auth_opt_port 3306# 指定数据库名auth_opt_dbname your_database# 指定数据库访问用户名auth_opt_user your_username# 指定数据库访问密码auth_opt_pass your_passwd# 配置身份验证查询语句auth_opt_userquery select (case password_syncstatus when 'sync' then user_passwd else old_password end) as user_passwd from tbl_mqttuser where user_name='%s'# 配置ACL验证查询语句auth_opt_aclquery SELECT topic FROM tbl_mqttacls WHERE (user_name = '%s') AND (rw >= %d)# 匿名MQTT连接时插件配置的用户名auth_opt_anonusername anonymouS

mysql 中 tbl_mqttuser 及 tbl_mqttacls 两个表数据示例:

mysql> select * from  tbl_mqttacls;+--------+--------------+--------+----+| acl_id | user_name    | topic  | rw |+--------+--------------+--------+----+|      1 | user_1 | #      |  6 ||      2 | user_2 | $SYS/# |  4 |+--------+--------------+--------+----+4 rows in set (0.00 sec)mysql> select * from  tbl_mqttuser;+---------+--------------+---------------------------------------------------------------------+---------------------------------------------------------------------+---------------------+---------------------+| user_id | user_name    | user_passwd                                                         | old_password

⚠️ 注意:对$SYS系统主题的权限设置需要注意读写权限,一般来说是不会开放写数据权限的,否则系统主题得到的数据就不是正确的统计数据了,可能是篡改掉了的。在生产环境中一般系统主题是不会开放的。

3 总结

  • 物联网的安全尤为重要,MQTT 作为广泛使用的轻量级协议,实现安全的方式有多种
  • MQTT 协议本身支持用户名和密码实现客户端的身份校验
  • 使用 SSL(升级版本 TLS)可以对网络数据进行加密(这与 MQTT 协议本身是无关的,会增加网络开销)
  • 通过 Broker 可以配置对 Topic 的读写权限
  • 使用授权管理插件,实现批量级用户权限和 topic 的读写权限管理
  • 对$SYS系统主题的权限设置需要注意读写权限,一般来说是不会开放写数据权限

4 扩展之 MQTT SYS 主题

MQTT v3.1.1 是较旧的 ISO 和 OASIS 标准,MQTT v5.0 是 OASIS 标准,该协议定义了静态主题、必须实现的SYS主题和非必须实现的主题。

静态 SYS 主题: 不需要在每个$SYS主题更新时间间隔上发送有关静态$SYS主题的消息,只有在订阅了之后才发送一次。**必选主题:**每个声称支持$SYS主题的代理(broker,如 mosquitto)都应支持这些主题,是每个 broker 都需要支持的。**可选主题:**代理可以选择性实现这些主题。

必选主题和可选主题中包含静态主题。

必选主题:

  • $SYS/broker/load/bytes/received : 自代理启动以来收到的字节总数。
  • $SYS/broker/load/bytes/sent : 自代理启动以来发送的字节总数。
  • $SYS/broker/clients/connected : 当前连接的客户端数
  • $SYS/broker/clients/disconnected : 在代理上注册但当前已断开连接的持久客户端总数(禁用了 clean session)。
  • $SYS/broker/clients/maximum : 已连接到代理的最大活动客户端数。仅在更新$SYS主题树时才计算此值,因此可能不计算短暂的客户端连接。
  • $SYS/broker/clients/total : 当前已在代理上连接并注册的持久会话的已连接和已断开连接的客户端总数。
  • $SYS/broker/messages/received : 自代理启动以来收到的任何类型的消息总数。
  • $SYS/broker/messages/sent : 自代理启动以来发送的任何类型的消息总数。
  • $SYS/broker/messages/publish/dropped : 由于运行中/排队限制而删除的发布消息总数。
  • $SYS/broker/messages/publish/received : 自代理启动以来收到的 PUBLISH 消息总数。
  • $SYS/broker/messages/publish/sent : 自代理启动以来发送的 PUBLISH 消息总数。
  • $SYS/broker/messages/retained/count: 代理上活动的保留消息总数。
  • $SYS/broker/subscriptions/count: 代理上活动的订阅总数。
  • $SYS/broker/uptime: 代理已联机的时间(以秒为单位)
  • $SYS/broker/version: broker 的版本。静态主题

可选主题:

  • $SYS/broker/time: 服务器上的当前时间
  • $SYS/broker/timestamp: 生成此特定版本的代理的时间戳。静态主题。
  • ......

5 参考链接

  • https://github.com/mqtt/mqtt.github.io/wiki/SYS-Topics
  • https://docs.vernemq.com/configuration/bridge
  • https://www.hivemq.com/blog/why-you-shouldnt-use-sys-topics-for-monitoring/
  • https://mosquitto.org/man/mosquitto-8.html
  • http://mqtt.org/faq
  • https://iot-analytics.com/state-of-the-iot-update-q1-q2-2018-number-of-iot-devices-now-7b/
  • https://blog.teserakt.io/2019/02/25/securing-the-mosquitto-mqtt-broker/
  • https://github.com/jpmens/mosquitto-auth-plug

本文分享自微信公众号 - 小白AI(gh_c002f3b12bc2)

c++ mqtt客户端_MQTT安全性设计详解相关推荐

  1. 分布式 | Dubbo 架构设计详解

    转载自   分布式 | Dubbo 架构设计详解 Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务 ...

  2. 【转】Dubbo架构设计详解

    本文转自:Dubbo架构设计详解,原作者是:时延军 Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服 ...

  3. ueditor上传组件显示乱码_最全面的移动端 UI组件设计详解:中篇

    上一期给大家讲解了<最全面的移动端UI组件设计详解:上篇>,主要分享了:布局组件和导航组件2个部分:这次给大家带来:基础组件.表单组件和反馈组件详解,希望你在设计APP.小程序.H5页面中 ...

  4. java 重启线程_java 可重启线程及线程池类的设计(详解)

    了解JAVA多线程编程的人都知道,要产生一个线程有两种方法,一是类直接继承Thread类并实现其run()方法:二是类实现Runnable接口并实现其run()方法,然后新建一个以该类为构造方法参数的 ...

  5. HDL输入设计详解攻略

    Altera公司的Quartus为设计者提供了多种设计输入方法,包括原理图输入.状态图输入.HDL语言描述.网络表文件等,所不同的是,Quartus可以在一个工程中同时使用VHDL.Verilog语言 ...

  6. Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载)

    Java开源生鲜电商平台-Java分布式以及负载均衡架构与设计详解(源码可下载) 说明:主要是针对一些中大型的项目需要进行分布式以及负载均衡的架构提一些思路与建议. 面对大量用户访问.高并发请求,海量 ...

  7. 架构设计-支付宝、京东、美团、去哪儿的支付系统架构整体设计详解!!!

    架构设计-支付宝.京东.美团.去哪儿的支付系统架构整体设计详解!!! 支付产品模块是按照支付场景来为业务方提供支付服务.这个模块一般位于支付网关之后,支付渠道之前. 它根据支付能力将不同的支付渠道封装 ...

  8. 单片机控制两个步进电机画圆_基于单片机的步进电机转速控制设计详解(附程序)...

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角.这 ...

  9. sketch如何做设计稿交互_《动静之美——Sketch移动UI与交互动效设计详解》历程...

    随着移动互联网的迅速崛起,对移动产品界面的设计质量和迭代速度都有了更高的要求,市面上开始涌现出一批专门针对移动UI设计的软件,Sketch便是其中的佼佼者.Sketch因其强大的功能以及极低的入门门槛 ...

最新文章

  1. java里锛是什么意思,java实验总结
  2. 部署项目到阿里云服务器上遇到的问题
  3. datagrid出现相同两组数据_stata 数据操作基础知识:以一篇论文数据操作为例
  4. hanlp是开源的吗_自然语言处理之:搭建基于HanLP的开发环境(转)
  5. Android中垃圾回收日志信息
  6. 项目管理最佳实践方法_项目管理最佳实践,企业如何进行有效的项目管理
  7. PaddlePaddle顶会论文复现 | ECO视频动作识别网络
  8. count(*)效率提高_2020年最新整理财务统计函数,学会让你财务统计效率提升95%以上...
  9. 《Android开发卷——HTTP网络通信,HTTP网络连接》
  10. idea设置主题路径
  11. QT - 实例 - Qt实现局域网聊天工具软件
  12. EDA工具对芯片产业的重要性知识科普
  13. excel单元格格式设置
  14. 土木工程材料——混凝土
  15. 文件上传漏洞揭密剖析(一)-文件上传漏洞原理
  16. Mongodb本机部署副本集
  17. 网站访问速度诊断工具汇总
  18. 13.定时器/计数器
  19. 【C++】C++资料整理(持续更新)
  20. 机器码中的原码,反码,补码计算规则

热门文章

  1. java 多线程 同步 观察者 并发集合的一个例子
  2. 计算机基础-计算机硬件
  3. Nodejs--querystring (URL 查询字符串)
  4. 【SpringMVC】与权限拦截器冲突导致的Cors跨域设置失效问题
  5. Laravel之Eloquent ORM访问器调整器及属性转换
  6. 开启Mac充电提示音
  7. ubuntu下关于 undefined reference to 'pcap_flex'错误 以及 无法导入/找到libpcap.so.1错误...
  8. Linux日志选项详解及日志服务器的实现
  9. [导入]ASP.NET AJAX 说明文档-客户端引用-全局命名空间-JavaScript 基础类型扩展-Array 类型扩展-add 函数...
  10. dubbo接口测试_Django测试工具平台之Dubbo接口请求 + 前端