EMQX 4.4 加mysql认证
一、完整流程示例(含代码和配置)
1. 环境准备
- EMQ X 版本:5.x(支持 MySQL 插件)
- MySQL 版本:5.7+(推荐 8.0)
- 工具:MySQL 客户端、MQTT 客户端(如 MQTTX 或 Mosquitto)
2. 创建 MySQL 数据库和表
-- 创建数据库
CREATE DATABASE IF NOT EXISTS mqtt_auth;
USE mqtt_auth;-- 创建用户表(关键字段)
CREATE TABLE mqtt_user (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(100) NOT NULL UNIQUE, -- 用户名(唯一)password_hash VARCHAR(255) NOT NULL, -- 加密后的密码salt VARCHAR(35) DEFAULT NULL, -- 盐值(用于加密)is_superuser TINYINT DEFAULT 0 -- 是否超级用户(跳过 ACL)
);-- 插入测试用户(密码为 `test123`,盐值 `salt_abc`)
-- 使用 SHA256 加密(盐值拼接在密码前)
INSERT INTO mqtt_user (username, password_hash, salt)
VALUES ('device_001',SHA2(CONCAT('salt_abc', 'test123'), 256), -- 生成密文'salt_abc'
);
3. 配置 EMQX MySQL 插件
修改 etc/plugins/emqx_auth_mysql.conf
:
## 数据库连接配置
auth.mysql.server = 127.0.0.1:3306
auth.mysql.username = root
auth.mysql.password = root_password
auth.mysql.database = mqtt_auth## 认证查询语句(关键!)
auth.mysql.auth_query = SELECT password_hash AS password, salt FROM mqtt_user WHERE username = '%u' LIMIT 1## 加密方式(必须与数据库生成方式一致)
auth.mysql.password_hash = sha256,salt # 盐值前缀 + SHA256
4. 启用插件并测试
# 重启插件
./bin/emqx_ctl plugins reload emqx_auth_mysql# 关闭匿名认证(etc/emqx.conf)
allow_anonymous = false
5. 客户端连接测试
使用 MQTTX 或 Mosquitto 工具:
# 连接命令(密码为明文 `test123`)
mosquitto_sub -h 127.0.0.1 -p 1883 \-u device_001 -P test123 \-t 'test/topic' -d
二、关键问题解析
1. 密码加密逻辑
- 盐值(Salt):随机字符串,用于防止彩虹表攻击。
- 加密方式:
sha256,salt
:SHA256(盐值 + 密码)
→ 存储到password_hash
。md5,salt
:MD5(盐值 + 密码)
。
- 验证流程:
EMQX 用配置的加密方式对客户端输入的密码 + 盐值加密,与数据库中的password_hash
比对。
2. ACL 权限控制(可选)
创建 mqtt_acl
表控制主题访问:
CREATE TABLE mqtt_acl (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(100),clientid VARCHAR(100),topic VARCHAR(255) NOT NULL,access INT CHECK (access IN (1,2,3)), -- 1=订阅, 2=发布, 3=全部action INT CHECK (action IN (1,2)) -- 1=允许, 2=拒绝
);-- 示例:允许 device_001 订阅 `test/#`
INSERT INTO mqtt_acl (username, topic, access, action)
VALUES ('device_001', 'test/#', 1, 3);
三、查看详细日志
这是最直接有效的排查方法。通过日志可以明确看到认证失败的具体原因。
# 开启调试日志并实时查看
./bin/emqx_ctl log set-level debug
tail -f log/emqx.log | grep -E "auth_mysql|superuser|device_001"