Mosquitto安装
Mosquitto是一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。一个典型的应用案例就是 Andy Stanford-ClarkMosquitto(MQTT协议创始人之一)在家中实现的远程监控和自动化。并在 OggCamp 的演讲上,对MQTT协议进行详细阐述。
为每个MQTT消息头命令消息包含一个固定头,头只有两个字节,格式如下:
安装
以Centos7.x为例
如果你服务器源里是 1.4.13 版本的 Mosquitto
1 | yum install mosquitto |
如果你服务器源里是 1.4.14 版本的 Mosquitto
1 | yum install mosquitto mosquitto-clients |
Mac用户可以通过Homebrew安装
1 | brew install mosquitto |
简单测试
打开两个终端,一个模拟接收者,一个模拟发送者
接收者
1 | mosquitto_sub -t topic_test |
发送者
1 | mosquitto_pub -t topic_test -m "Hello World." |
这时候,接收者就会收到Hello World.
的消息:
[root@192 ~]# mosquitto_sub -t topic_test
Hello World.
使用客户端工具来模拟收发
这里介绍一款Chrome插件 MQTTBox
配置如下
使用
添加一个订阅者
添加一个发布者
点击发布
用户名密码认证
(1) 使用Mosquitto
自带的mosquitto_passwd
命令创建用户
1 | mosquitto_passwd -c /etc/mosquitto/pwfile test |
(2) 编辑/etc/mosquitto/mosquitto.conf
配置文件,修改如下内容
1 | allow_anonymous false |
(3) 重启mosquitto
1 | systemctl restart mosquitto |
这时候如果要测试发布和订阅,就需要设置用户名和密码了
ACL 基于Topic的访问控制
Mosquitto安装完毕,默认包含一个aclfile.example的配置文件,内容如下:
1 | # This affects access control for clients with no username. |
配置文件包含三种形式的访问配置:
- 第一段这种形式的声明,会影响到没有不含用户名的访问权限
- 第二段这种包含user的声明,会影响到具体指定用户的访问权限。这里user指令后面的用户需要是 pwfile 包含的用户。另外,topic [read|write|readwrite]
这里有读、写、读写三种权限,分别代表客户端对topic的订阅、发布、订阅和发布。如果不写中间的读写权限,则等同于readwrite权限。 - 第三段这种形式的声明,使用topic规则来验证,如果topic跟pattern里的匹配,则拥有该权限
%c
匹配客户端ID%u
匹配客户端用户名
配置ACL
1. 开启ACL
修改配置文件mosquitto.conf,添加以下内容
1 | # config topic access control |
2. 编辑acl配置
基于/etc/mosquitto/aclfile.example,复制一份,命名为/etc/mosquitto/aclfile。然后进行授权编辑。以下是我的测试配置:
1 | # admin acl |
示例解析:
- admin具有
/building/#
订阅和发布的权限 - sensor具有
/building/sensor/upload
发布的权限,以及/building/sensor/fetch
订阅的权限 - cloud具有
/building/sensor/upload
订阅的权限,以及/building/sensor/fetch
发布的权限
也就是说,admin拥有整个建筑里数据访问协议;sensor拥有上传数据,以及接受云端指令的权限;admin有接受传感器数据和发布收集传感器数据指令的权限。这样即保证了整体的工作流程不受影响,也保证了账号独立,权限独立。
3. 重新加载mosquitto,使acl配置生效
1 | systemctl reload mosquitto |
注意:
- 如果开启acl,假设用户zhangsan存在于pwfile文件中,但是在aclfile里没有进行任何授权配置,那么默认是没有任何topic的订阅和发布权限。
- 另外,有一点比较坑,如果一个账户因为acl验证不通过,那么client收不到任何关于订阅失败或者发布失败的消息