文档章节

EMQ百万级MQTT消息服务(ACL鉴权)

喵了_个咪
 喵了_个咪
发布于 2018/04/15 10:49
字数 1235
阅读 976
收藏 9

虽然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地址链接监听系统主题

%% 允许'dashboard'用户订阅 '$SYS/#'
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
%% 允许本机用户发布订阅全部主题
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
%% 拒绝用户订阅'$SYS#'与'#'主题
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.

规则如下:

允许|拒绝  用户|IP地址|ClientID  发布|订阅  主题列表

## 访问控制规则采用 Erlang 元组格式,访问控制模块逐条匹配规则:
         ---------              ---------              ---------
Client -> | Rule1 | --nomatch--> | Rule2 | --nomatch--> | Rule3 | --> Default
          ---------              ---------              ---------
              |                      |                      |
            match                  match                  match
             \|/                    \|/                    \|/
        allow | deny           allow | deny           allow | deny

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

$SYS/brokers/+/clients/+/connected
$SYS/brokers/+/clients/+/disconnected

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

> vim /usr/local/emqttd/etc/acl.conf
## 修改
# {allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
{allow, {ipaddr, 你的外网IP}, pubsub, ["$SYS/#", "#"]}.

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

{"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作为鉴权的数据来源,首先先关闭匿名认证(默认是开启的谁都能够登录)

vim /usr/local/emqttd/etc/emq.conf 

## Allow Anonymous authentication
mqtt.allow_anonymous = false

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

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配置文件

> 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

建立用户

# 用户名 server 密码 server 密码默认是sha256
insert `mqtt_user`(`username`,`password`) values('server','b3eacd33433b31b5252351032c9b3e7a2e7aa7738d5decdf0dd6c62680853c06');
# 用户名 cline 密码 cline
insert `mqtt_user`(`username`,`password`) values('cline','84829dbd815311888f0e3d85822e9b07d14be89a480a3c09ee67353f0e806e3b');

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

update `mqtt_user` set `is_superuser`=1 where `id`=1;

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

> 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的配置可以动态的变更谁能做什么事情,在不同的业务需求场景下这样的功能可以让程序做到更加安全又利于编程

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

© 著作权归作者所有

共有 人打赏支持
喵了_个咪
粉丝 326
博文 150
码字总数 199180
作品 4
杨浦
技术主管
私信 提问
加载中

评论(2)

喵了_个咪
喵了_个咪

引用来自“sweetalin”的评论

看了你的系列emq文章,收获颇多,不知道有没有相关技术交流群,希望可以继续关注你
可以加EMQ群:196066320 一起交流
s
sweetalin
看了你的系列emq文章,收获颇多,不知道有没有相关技术交流群,希望可以继续关注你
EMQ百万级MQTT消息服务(分布式集群)

在强大的单机也比不上集群,EMQ的集群模式很粗暴,只需要把EMQ服务关联在一起然后负载均衡就可以达到集群的效果,这样就算面对1000CK问题也迎刃而解 附上: 喵了个咪的博客:w-blog.cnEMQ官方地址...

喵了_个咪
2018/04/15
0
0
EMQ 2.0.6 发布, 百万级 MQTT 消息服务器

EMQ 2.0.6 版本发布,2.0最后一个维护版本。EMQ 是采用 Erlang/OTP 平台开发,全面支持 MQTT V3.1.1 协议,支持集群和百万级连接的开源 MQTT 消息服务器。 更新内容: 升级esockd库到v4.1.1版...

emqtt
2017/01/09
2.7K
3
EMQ 2.1.0-beta.1 发布, 百万级 MQTT 消息服务器

EMQ v2.1.0-beta.1 版本正式发布。 改进Session/Inflight窗口设计,一个定时器负责全部Inflight QoS1/2消息重传。优化MQTT连接的GC机制,降低高消息吞吐情况下的CPU/内存占用。 EMQ 2.1.0版本...

emqtt
2017/02/24
1K
4
EMQ 2.2-beta.2 发布, 百万级 MQTT 消息服务器

EMQ 2.2-beta.2版本正式发布。新增'websocket_protocol_header'配置项,支持微信小程序WebSocket连接EMQ;支持Elixir语言开发EMQ插件。 问题修复 新增'websocket_protocol_header'配置项,支......

emqtt
2017/05/22
1K
2
emqttd 2.1.0 发布,Erlang 集群 MQTT 消息服务器

emqttd 2.1.0 发布了。[emqttd] (EMQ)是采用Erlang语言开发,全面支持MQTT V3.1.1协议,支持集群和大规模连接的开源MQTT消息服务器。 [emqttd]致力于发布一个基于Erlang/OTP语言平台,企业...

达尔文
2017/04/09
723
2

没有更多内容

加载失败,请刷新页面

加载更多

python精简笔记-[5]-列表[list]

1

平头哥-Enjoystudy
20分钟前
1
0
《如何做好一场技术演讲》笔记

[TOC] 1. 精心准备 1.1. 明确演讲主题 如同架构设计一样,了解需求永远是第一位的,任何脱离需求的架构设计都是耍流氓。 想要开始演讲,首先需要了解听众的诉求,确认下面这些问题: 听众组成...

whoru
23分钟前
3
0
Oracle学习日志-4(查询基础)

首先新建一张Product表格。数据如下 语法 从表名中查询希望查询出的列的名字 SELECT <列名> FROM <表名> 例如从Product表中查询商品编号,商品名称和进货单价三列。 SELECT product_id,prod...

白话
23分钟前
2
0
【重大更新】跨平台移动开发框架Altova MobileTogether v5.0发布

MobileTogether是一款对应用程序进行精心渲染的跨平台移动开发框架,从所处设备到外形因素再到屏幕方向,很大程度的为开发人员和终端用户提供了更好的功能性与灵活性。MobileTogether包括: ...

ymy_666666
32分钟前
1
0
better-scroll的使用

目的:需要在手机端实现上拉加载数据,下拉刷新页面的功能。 使用的控件:better-scroll 难点:目前的better-scroll都是和vue一起使用,公司用的是angularjs1.x,所以需要最原始的使用然后封...

Pcat
35分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部