emqx开启mysql插件进行动态认证鉴权

 

                                        emqx开启mysql插件

一、简述

  1. 采用emqx搭建mqtt服务器,基于主题(topic)的发布订阅模式。在线上项目中使用,肯定要进行动态的认证和topic权限鉴权,动态管理连接emqx的用户名和密码,以及用户对应的主题权限,本文采用外接mysql形式进行用户管理。

二、开启插件前准备好数据库

  1. 在mysql中创建好插件所需要的的表用户表和acl权限表(默认用户表为‘mqtt_user’,acl权限表为‘mqtt_acl’)
    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=InnoDB DEFAULT CHARSET=utf8mb4;
      
      
      CREATE TABLE `mqtt_acl` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `allow` int(1) DEFAULT 1 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=utf8mb4;
  2. 表字段说明   
  • allow:禁止(0),允许(1)
  • ipaddr:设置 IP 地址
  • username:连接客户端的用户名,此处的值如果设置为 $all 表示该规则适用于所有的用户
  • clientid:连接客户端的 Client ID
  • access:允许的操作:订阅(1),发布(2),订阅发布都可以(3)
  • topic:控制的主题,可以使用通配符,并且可以在主题中加入占位符来匹配客户端信息,例如 t/%c则在匹配时主题将会替换为当前客户端的 Client ID
    • %u:用户名
    • %c:Client ID

三、mysql插件修改

1、首先把emqx安装目录下的etc/emqx.conf中配置修改:

## 将匿名访问禁止掉,默认是开启的,无需用户名和密码即可连接emqx。
allow_anonymous = false

## 如果没有匹配的ACL规则,则拒绝;默认是允许的。
acl_nomatch = deny

 

2、修改mysql插件配置里面的信息(位于emqx的etc/plugins/emqx_auth_mysql.conf):

第一步:修改mysql连接信息,

# etc/plugins/emqx_auth_mysql.conf

## mysql所在服务器地址和ip端口号
auth.mysql.server = 127.0.0.1:3306

## 连接池大小
auth.mysql.pool = 8

## 连接mysql数据库的用户名
auth.mysql.username = emqx

## 连接mysql数据库的密码
auth.mysql.password = public

## mqtt_user和mqtt_acl这两张表所属的数据库
auth.mysql.database = mqtt

auth.mysql.query_timeout = 5s

第二步:设置密码加密方式和认证sql查询语句

##    根据用户名查询用户密码的sql。
auth.mysql.auth_query = select password from mqtt_user where username = '%u' limit 1


##    plain使用明文连接,不加密,即连接emqx的密码和数据库中的密码一致
auth.mysql.password_hash = plain

可以在认证 SQL 中使用以下占位符,执行时 EMQ X 将自动填充为客户端信息:

  • %u:用户名
  • %c:Client ID
  • %C:TLS 证书公用名(证书的域名或子域名),仅当 TLS 连接时有效
  • %d:TLS 证书 subject,仅当 TLS 连接时有效

也可以根据自己的业务需要调整认证sql,如添加多个查询条件、使用数据库预处理函数,以实现更多业务相关的功能。

注: 查询结果只能有一条,多条结果时只取第一条作为有效数据。

如果启用了加盐配置,查询结果中必须包含 salt 字段,EMQ X 使用该字段作为 salt(盐)值。

查询结果必须包含password,若表中密码字段为pwd则此处查询的password使用as语法;例如pwd as password。

若不想使用mqtt_user这个表名,则需要这个地方查询语句中的表名和数据库中表名保持一致即可。

第三步:acl鉴权查询语句开启(默认是开启状态,则无需改动)

 超级用户SQL(super_query)

进行 ACL 鉴权时,EMQ X 将使用当前客户端信息填充并执行用户配置的超级用户 SQL,查询客户端是否为超级用户。客户端为超级用户时将跳过 ACL SQL。

  1. 查询结果中必须包含 is_superuser 字段,is_superuser 应该显式的为 true
  2. 查询结果只能有一条,多条结果时只取第一条作为有效数据

注:如果不需要超级用户功能,注释并禁用该选项能有效提高效率。

ACL SQL(acl_query)

进行 ACL 鉴权时,EMQ X 将使用当前客户端信息填充并执行用户配置的超级用户 SQL,如果没有启用超级用户 SQL 或客户端不是超级用户,则使用 ACL SQL 查询出该客户端在数据库中的 ACL 规则。

  1. 查询结果中必须包含 allow、access、topic、clientid、username、ipaddr 字段,如果字段不想参与比对则使用 $all 字符串或者数据库 NULL 值
  2. 查询结果可以有多条,多条结果时按照从上到下的顺序进行匹配

注:可以在 SQL 中调整查询条件、指定排序方式实现更高效率的查询。

以上操作均在Linux环境下,Windows环境下可能会存在异常(PS:本人遇到过)

四、若有不明之处,随时留言(15670600690)                                                         

你的鼓励是我接下来努力的动力
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页