星期三, 十二月 25日 2019, 2:42 下午

本文作者:[wangwenhai] # 概要:本文主要介绍一下EMQX的Mysql认证插件

1.概述

EMQX默认是全开放的,也就是没有安全审核机制.我们的设备会经常涉及到安全认证,比如不允许某些非法设备连接进来.

如果有安全认证需求,只需要关闭匿名连接即可,具体配置大概在emqx.conf的447行左右:

## Allow anonymous authentication by default if no auth plugins loaded.
## Notice: Disable the option in production deployment!
##
## Value: true | false
allow_anonymous = false

把true改成false即可.这样我们就可以实现从Mysql数据库中进行连接认证了.

2.数据表解读

首先我们看看官方插件给出的数据表结构:

  1. 客户端表结构

    CREATE TABLE `mqtt_user` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `username` varchar(100) DEFAULT NULL,
      `password` varchar(100) DEFAULT NULL,
      `salt` varchar(35) 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;

    此表有几个关键列:username,password.这两个字段便是MQTT协议的连接口令.其中salt表示密码加盐,一般是自定义字符串,is_superuser表示是否是特殊权限的客户端.对应的是插件的一个SQL查询:

    auth.mysql.auth_query = select password from ez_module where client_id = '%c' limit 1
  2. ACL表结构

    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;

    这里表示的是查询客户端能订阅哪些topic,查询的SQL如下:

    auth.mysql.acl_query = select allow, ip AS ipaddr, username,client_id AS clientid, access, topic from ez_mqtt_topic where ip = '%a' or username = '%u' or username = '$all' or client_id = '%c'

3.自定义

官方给出的数据表的字段是最基础的,我们在业务之上可进行扩展,针对EZLinker的业务,我对客户端表进行如下扩展:

CREATE TABLE `ez_module` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'PK',
  `device_id` int(11) NOT NULL COMMENT '设备ID',
  `protocol` int(11) NOT NULL COMMENT '协议',
  `client_id` varchar(64) DEFAULT NULL COMMENT 'MQTT的clientID',
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL,
  `type` int(4) NOT NULL DEFAULT '0' COMMENT '类型',
  `status` tinyint(4) unsigned DEFAULT '0' COMMENT '状态:0离线,1在线',
  `name` varchar(20) NOT NULL COMMENT '名称',
  `model` varchar(50) DEFAULT NULL COMMENT '型号',
  `last_active_time` datetime DEFAULT NULL,
  `sn` varchar(64) DEFAULT NULL COMMENT '序列号',
  `token` varchar(200) DEFAULT NULL COMMENT '密钥,基于计算生成的一个Base64字符串',
  `is_superuser` int(4) DEFAULT '0' COMMENT '是否是超级管理员',
  `data_areas` json DEFAULT NULL COMMENT '数据域',
  `description` varchar(200) DEFAULT NULL COMMENT '描述',
  `record_version` int(11) NOT NULL DEFAULT '0' COMMENT '记录版本',
  `x` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '删除',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='设备上面的模块,和设备是多对一关系';

对ACL表进行如下扩展:

CREATE TABLE `ez_mqtt_topic` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `module_id` int(11) DEFAULT NULL COMMENT '设备',
  `client_id` varchar(64) DEFAULT NULL COMMENT 'MQTT客户端ID',
  `allow` int(4) DEFAULT '1' COMMENT '是否允许连接: 0=拒绝1=允许',
  `type` tinyint(4) DEFAULT '0' COMMENT '类型 1:S2C;2:C2S;3:STATUS;4:GROUP',
  `access` int(4) DEFAULT '1' COMMENT '行为类型: 1=订阅2=发布3=订阅+发布',
  `ip` varchar(16) DEFAULT NULL COMMENT 'IP',
  `username` varchar(255) DEFAULT NULL COMMENT 'MQTT用户名',
  `topic` varchar(200) DEFAULT NULL COMMENT '路由',
  `record_version` int(11) NOT NULL DEFAULT '0' COMMENT '记录版本',
  `x` tinyint(1) unsigned zerofill DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='MQTT的TOPIC记录';

最后,注意一个问题:我们必须要实现官方插件里面的三哥变量:

## Variables:
##  - %a: ipaddr
##  - %u: username
##  - %c: clientid

4.认证测试

接下来试试连接认证情况:

1.首先在数据库里面写入一行记录:

image-20191225150056795

2.用一个客户端去测试

这里我用的是Mqtt.fx.

image-20191225150020888

测试连接成功:

image-20191225150345287

5.总结

本文主要写了如何使用EMQX的Mysql认证插件和自定义数据表结构.



Erlang  

emqx

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

 目录

物联网技术开发交流QQ群

友情链接

TTalk.im
MAIN.RUN