我是靠谱客的博主 可耐滑板,最近开发中收集的这篇文章主要介绍EMQ百万级MQTT消息服务(ACL鉴权),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在这里插入图片描述

虽然EMQ已经搭建起来了,但是投入到业务使用中还面临着一些问题,当然MQTT设计之初也考虑了这一点,比如不是任何一个客户端都能链接到服务器和限制客户端能够对topic操作的权限

附上:

喵了个咪的博客:w-blog.cn
EMQ官方地址:http://emqtt.com/
EMQ中文文档:http://emqtt.com/docs/v2/guide.html

1.ACL鉴权

先说实际场景,我们需要监听每一台设备的链接和断开事件等EMQ的系统行为,这样的事件当然不是任何一个连接到服务器的终端,这样的限制就是ACL鉴权,官方也提供了默认的鉴权,在 /usr/local/emqttd/etc/acl.conf 下,默认值允许127.0.0.1的IP地址链接监听系统主题

复制代码
1
2
3
4
5
6
7
%% 允许'dashboard'用户订阅 '$SYS/#' {allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}. %% 允许本机用户发布订阅全部主题 {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}. %% 拒绝用户订阅'$SYS#''#'主题 {deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.

规则如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
允许|拒绝 用户|IP地址|ClientID 发布|订阅 主题列表 ## 访问控制规则采用 Erlang 元组格式,访问控制模块逐条匹配规则: --------- --------- --------- Client -> | Rule1 | --nomatch--> | Rule2 | --nomatch--> | Rule3 | --> Default --------- --------- --------- | | | match match match |/ |/ |/ allow | deny allow | deny allow | deny

这个时候如果在外网链接EMQ定于如下主题,当客户端链接的时候是无法获取消息的

复制代码
1
2
3
$SYS/brokers/+/clients/+/connected $SYS/brokers/+/clients/+/disconnected

但是只需要修改acl配置文件如下然后重启节点:(所有节点都需要修改)

复制代码
1
2
3
4
5
> vim /usr/local/emqttd/etc/acl.conf ## 修改 # {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}. {allow, {ipaddr, 你的外网IP}, pubsub, ["$SYS/#", "#"]}.

重新监听当客户端链接的时候就可以获得如下信息

复制代码
1
2
3
{"clientid":"V10115125355235","username":"cline","ipaddress":"116.192.34.23","clean_sess":true,"protocol":4,"connack":0,"ts":1521689797} {"clientid":"V10115125355235","username":"cline","reason":"normal","ts":1521689801}

2.MYSQL实时配置ACL

一般来说我们不会使用外网IP来进行限制,有限会选择用户来进行限制行为,官方提供如下方式来进行用户和ACL验证的存储:
(对应的配置方式可以参考官网文档)

  • 配置文件和命令
  • LDAP
  • HTTP
  • MySQL
  • Postgre
  • Redis
  • MongoDB

笔者这里采用大家经常用到的MYSQL作为鉴权的数据来源,首先先关闭匿名认证(默认是开启的谁都能够登录)

复制代码
1
2
3
4
5
vim /usr/local/emqttd/etc/emq.conf ## Allow Anonymous authentication mqtt.allow_anonymous = false

重启服务器之后不管是谁都会被链接拒绝,我们需要准备好用于检查用户和权限的mysql表:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
CREATE TABLE `mqtt_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(100) DEFAULT NULL, `password` varchar(100) DEFAULT NULL, `salt` varchar(20) DEFAULT NULL, `is_superuser` tinyint(1) DEFAULT 0, `created` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `mqtt_username` (`username`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `mqtt_acl` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `allow` int(1) DEFAULT NULL COMMENT '0: deny, 1: allow', `ipaddr` varchar(60) DEFAULT NULL COMMENT 'IpAddress', `username` varchar(100) DEFAULT NULL COMMENT 'Username', `clientid` varchar(100) DEFAULT NULL COMMENT 'ClientId', `access` int(2) NOT NULL COMMENT '1: subscribe, 2: publish, 3: pubsub', `topic` varchar(100) NOT NULL DEFAULT '' COMMENT 'Topic Filter', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 建立ACL默认访问控制 INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`) VALUES (1,1,NULL,'$all',NULL,2,'#'), (2,0,NULL,'$all',NULL,1,'$SYS/#'), (3,0,NULL,'$all',NULL,1,'eq #'), (5,1,'127.0.0.1',NULL,NULL,2,'$SYS/#'), (6,1,'127.0.0.1',NULL,NULL,2,'#'), (7,1,NULL,'dashboard',NULL,1,'$SYS/#');

修改mysql配置文件

复制代码
1
2
3
4
5
6
7
> vim /usr/local/emqttd/etc/plugins/emq_auth_mysql.conf auth.mysql.server = xxxxxxxxx:3306 auth.mysql.username = root auth.mysql.password = xxxxxxxx auth.mysql.database = emq

建立用户

复制代码
1
2
3
4
5
# 用户名 server 密码 server 密码默认是sha256 insert `mqtt_user`(`username`,`password`) values('server','b3eacd33433b31b5252351032c9b3e7a2e7aa7738d5decdf0dd6c62680853c06'); # 用户名 cline 密码 cline insert `mqtt_user`(`username`,`password`) values('cline','84829dbd815311888f0e3d85822e9b07d14be89a480a3c09ee67353f0e806e3b');

可以配置超级管理员(超级管理员会无视ACL规则对所有的topic都有订阅和推送的权限)

复制代码
1
2
update `mqtt_user` set `is_superuser`=1 where `id`=1;

注意:可以注释掉acl.conf的默认规则(也可以结合使用)
注意:emq任何配置文件的变动都需要重启服务(可以在UI上直接修改配置不需要重启)
注意:如果是在集群下集群中每一个节点都需要执行命令

复制代码
1
2
3
4
5
6
7
8
9
> emqttd stop ok > emqttd start emqttd 2.3.5 is started successfully! ## 打开mysql鉴权 > emqttd_ctl plugins load emq_auth_mysql Start apps: [emq_auth_mysql] Plugin emq_auth_mysql loaded successfully.

在插件中就可以看到对应的mysql鉴权插件已经打开了

3 总结

这个时候在链接的时候配置用户名和密码就可以顺利链接上了,并且ACL的配置可以动态的变更谁能做什么事情,在不同的业务需求场景下这样的功能可以让程序做到更加安全又利于编程

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

最后

以上就是可耐滑板为你收集整理的EMQ百万级MQTT消息服务(ACL鉴权)的全部内容,希望文章能够帮你解决EMQ百万级MQTT消息服务(ACL鉴权)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部