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

原文地址:https://blog.csdn.net/qq_37949192/article/details/105908717

emqx开启mysql插件


一、简述


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


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


在mysql中创建好插件所需要的的表用户表和acl权限表(默认用户表为‘mqtt_user’,acl权限表为‘mqtt_acl’)

建表:

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;

表字段说明   

  • 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。

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


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

ACL SQL(acl_query)


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

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


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

测试:

填写连接信息,由于我们配置得是plain  ,明文加密方式,所以直接复制数据库的即可。

点击connect:

去dashboard查看:

成功连接,告辞!

猜你喜欢

转载自blog.csdn.net/qq_21454973/article/details/115372610