EMQX开启MongoDB接入认证与订阅发布鉴权

这篇具有很好参考价值的文章主要介绍了EMQX开启MongoDB接入认证与订阅发布鉴权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

关于物联网平台设计一个最佳实践是:对接入平台的设备进行认证,并且对设备可以发布和订阅的主题进行权限控制
MQTT Broker 开启对接入设备的认证与订阅发布鉴权的意义在于增强系统的安全性。通过认证,可以确保只有经过授权的设备可以连接到Broker,从而防止未经授权的设备访问系统。而订阅发布鉴权则可以确保只有经过授权的设备可以发布和订阅特定的主题,从而控制数据的访问权限,保护敏感信息不被未授权的设备获取。这些安全措施有助于防止恶意攻击和数据泄露。

下面基于国产的 MQTT BrokerEMQX 以及它提供的 MongoDB 数据库认证与 ACL 插件: emqx_auth_mongo 实现对设备接入认证、订阅发布鉴权的功能。

启动EMQX,建立匿名客户端连接

[root@iot1 ~]# cd /usr/local/
[root@iot1 local]# cd emqx
[root@iot1 emqx]# ./bin/emqx_ctl status
Node 'emqx@127.0.0.1' not responding to pings.

# 以默认配置启动EMQX
[root@iot1 emqx]# ./bin/emqx start
There seem to be missing dynamic libs from the OS.
Using libs from /usr/local/emqx/dynlibs instead.
EMQ X Broker 4.4.2 is started successfully!

# 验证状态
[root@iot1 emqx]# ./bin/emqx_ctl status
Node 'emqx@127.0.0.1' 4.4.2 is started

# 查看防火墙状态
[root@iot1 emqx]# firewall-cmd --state
running

# 后面要通过远程客户端连接,这里直接关闭防火墙
[root@iot1 emqx]# systemctl stop firewalld.service
[root@iot1 emqx]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

EMQX 默认配置下,与认证有关的插件都没有启动。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

以默认配置启动 EMQX 后,通过远程客户端工具进行匿名连接(即未输入用户名与密码),成功。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

修改MongoDB认证插件配置开启接入认证

[root@iot1 emqx]# vi ./etc/plugins/emqx_auth_mongo.conf
## MongoDB server list.
##
## Value: String
##
## Examples: 127.0.0.1:27017,127.0.0.2:27017...
auth.mongo.server = 127.0.0.1:27017

## MongoDB login user.
##
## Value: String
auth.mongo.username = you

## MongoDB password.
##
## Value: String
auth.mongo.password = guess

## MongoDB AuthSource
##
## Value: String
## Default: mqtt
auth.mongo.auth_source = device_access

## MongoDB database
##
## Value: String
auth.mongo.database = device_access

## -------------------------------------------------
## Auth Query
## -------------------------------------------------
## Password hash.
##
## Value: plain | md5 | sha | sha256 | bcrypt
auth.mongo.auth_query.password_hash = plain

## Authentication query.
auth.mongo.auth_query.collection = device

## Password mainly fields
##
## Value:  password | password,salt
auth.mongo.auth_query.password_field = secret

## Authentication Selector.
##
## Variables:
##  - %u: username
##  - %c: clientid
##  - %C: common name of client TLS cert
##  - %d: subject of client TLS cert
##
## auth.mongo.auth_query.selector = {Field}={Placeholder}
auth.mongo.auth_query.selector = access_name=%u

最后加载 ./bin/emqx_ctl plugins load emqx_auth_mongo ,如果是修改,则进行reload: ./bin/emqx_ctl plugins reload emqx_auth_mongo ;此时,通过 EMQX 自带的 Web 控制台 Dashboard ,可以看到 MongoDB 认证插件已启用。
需要注意的是,确保配置的 MongoDB 可以连接成功,否则 emqx_auth_mongo 插件无法加载。

通过 MQTT 客户端进行无密码接入,发现依然可以连接成功!这是因为我们虽然开启了 MongoDB 数据库的认证,但是 EMQX 默认还开启了匿名接入,我们需要到 EMQX 的全局配置文件中关闭匿名配置。

[root@iot1 emqx]# vi ./etc/emqx.conf
##--------------------------------------------------------------------
## Authentication/Access Control
##--------------------------------------------------------------------
## Allow anonymous authentication by default if no auth plugins loaded.
## Notice: Disable the option in production deployment!
##
## Value: true | false
allow_anonymous = false

## Allow or deny if no ACL rules matched.
##
## Value: allow | deny
acl_nomatch = deny

# 这个需要重启EMQX服务
[root@iot1 emqx]# ./bin/emqx restart

再次尝试通过远程客户端工具进行匿名连接,失败~

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

生成设备接入秘钥信息

基于 Express 框架创建 Node.js 后端项目,实现一个新增接口,返回设备信息三元组:产品名称,设备名称,设备秘钥。

数据模型

  • device.model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// mongoose表名会自动增加s,通过指定collection名称进行覆盖
const deviceSchema = new Schema({
    //ProductName
    product_name: {
        type: String,
        required: true
    },
    //DeviceName
    device_name: {
        type: String,
        required: true,
    },
    //接入EMQX时使用的username
    access_name: {
        type: String,
        required: true
    },
    //secret
    secret: {
        type: String,
        required: true,
    },
    // 可接入状态
    status: String,
    // 上次状态更新时间
    last_status_update: Number,
}, {
    collection: "device"
});

//定义 device.toJSONObject
deviceSchema.methods.toJSONObject = function() {
    return {
        product_name: this.product_name,
        device_name: this.device_name,
        secret: this.secret
    }
}

deviceSchema.methods.getACLRule = function() {
    const publish = [
        `report_data/${this.product_name}/${this.device_name}/+/+`,
        `update_status/${this.product_name}/${this.device_name}/+`,
    ];
    const subscribe = [];
    const pubsub = [];
    return {
        publish: publish,
        subscribe: subscribe,
        pubsub: pubsub
    }
}

const Device = mongoose.model("Device", deviceSchema);
module.exports = Device;
  • device_acl.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const deviceACLSchema = new Schema({
    //接入EMQX时使用的username
    access_name: {
        type: String,
        required: true
    },
    publish: Array,
    subscribe: Array,
    pubsub: Array
}, {
    collection: "device_acl"
});

const DeviceACL = mongoose.model("DeviceACL", deviceACLSchema);
module.exports = DeviceACL;

路由接口

  • devices.js
const express = require('express');
const Device = require("../models/device");
const shortid = require("shortid");
const router = express.Router();
let DeviceACL = require('../models/device_acl');

router.post("/", function(req, res) {
    console.log(`body: ${req.body.product_name}`);
    let productName = req.body.product_name;
    let deviceName = shortid.generate();
    let secret = shortid.generate();
    let accessName = `${productName}/${deviceName}`;

    let device = new Device({
        product_name: productName,
        device_name: deviceName,
        secret: secret,
        access_name: accessName,
        status: "active"
    });

    device.save(function(err) {
        if (err) {
            res.status(500).send(err);
        } else {
            let aclRule = device.getACLRule();
            let deviceACL = new DeviceACL({
                access_name: device.access_name,
                publish: aclRule.publish,
                subscribe: aclRule.subscribe,
                pubsub: aclRule.pubsub
            });
            deviceACL.save(function() {
                res.json({
                    product_name: productName,
                    device_name: deviceName,
                    secret: secret
                })
            });
        }
    })
});

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

执行生成设备三元组信息后,数据成功写入 MongoDB ,当然,这里包括设备的认证信息,以及发布订阅权限信息。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

使用生成的设备接入信息,作为用户名与密码,连接 MQTT Broker ,成功。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

修改MongoDB认证插件配置开启发布订阅鉴权

## ACL Selector.
##
## Multiple selectors could be combined with '$or'
##   when query acl from mongo.
##
## e.g.
##
## With following 2 selectors configured:
##
## auth.mongo.acl_query.selector.1 = username=%u
## auth.mongo.acl_query.selector.2 = username=$all
##
## And if a client connected using username 'ilyas',
##   then the following mongo command will be used to
##   retrieve acl entries:
##
## db.mqtt_acl.find({$or: [{username: "ilyas"},  {username: "$all"}]});
##
## Variables:
##  - %u: username
##  - %c: clientid
##
## Examples:
##
## auth.mongo.acl_query.selector.1 = username=%u,clientid=%c
## auth.mongo.acl_query.selector.2 = username=$all
## auth.mongo.acl_query.selector.3 = clientid=$all
auth.mongo.acl_query.collection = device_acl
auth.mongo.acl_query.selector = access_name=%u

设备的 ACL 存储到了 MongoDBdevice_acl 表中,进行匹配时查询 access_name 与客户端发来的 username 进行匹配。

发布数据到任意一个主题,失败,没有权限。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

根据 ACL 表里写入的主题信息进行发布,成功。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

其他API

除了生成设备接入信息三元组的接口外,还实现了获取设备三元组信息,以及设备的启用、禁用、删除接口,方便物联网平台对设备进行管理。

EMQX开启MongoDB接入认证与订阅发布鉴权,IIoT,EMQX,Mongodb,EMQX,MQTT,MongoDB,EMQX开启接入认证,emqx_auth_mongo,ACL

小总结

以上记录了基于 EMQX 与它提供的 MongoDB 数据库认证与 ACL 插件: emqx_auth_mongo 实现对设备接入认证、订阅发布鉴权的功能, MQTT Broker 开启对接入设备的认证、订阅发布鉴权:

  1. 安全性:认证可以确保只有经过授权的设备可以连接到Broker,防止未经授权的设备访问和篡改数据。
  2. 控制权限:通过认证可以对不同的设备设置不同的权限,例如读取、发布或订阅特定主题的权限,从而实现更精细的访问控制。
  3. 跟踪和监控:认证可以帮助跟踪和监控连接到Broker的设备,记录设备的活动和行为,有助于排查问题和进行安全审计。

因此,开启对接入设备的认证可以提高系统的安全性和可控性。


If you have any questions or any bugs are found, please feel free to contact me.

Your comments and suggestions are welcome!文章来源地址https://www.toymoban.com/news/detail-773218.html

到了这里,关于EMQX开启MongoDB接入认证与订阅发布鉴权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信公众号订阅号(未认证)接入Chatgpt实现AI聊天(代码已开源)

    众说周知,微信未经过认证的订阅号在接口权限上面有非常大的限制,这里主要做的事是:用户通过关注订阅号发送消息到后台,处理调用chatgpt接口,缓存到redis中。因为chatgpt接口延迟问题,如果微信三次回调均没有收到chatgpt回复,就将数据存到redis通过openid 和msgid绑定用户

    2024年04月17日
    浏览(38)
  • 开启物联网的魔法之门 - 深入探索发布/订阅模式

    发布订阅模式(Publish-Subscribe Pattern)是一种 消息传递模式 ,它将发送消息的客户端(发布者)与接收消息的客户端(订阅者)解耦,使得两者不需要建立直接的联系也不需要知道对方的存在。 MQTT 发布/订阅模式的精髓在于由一个被称为 代理 (Broker)的中间角色负责所有消

    2024年02月03日
    浏览(45)
  • Ubantu安装mongodb,开启远程访问和认证

    最近因为项目原因需要在阿里云服务器上部署MongoDB,操作系统为Ubuntu,网上查阅了一些资料,特此记录一下步骤。 1.运行apt-get install mongodb命令安装MongoDB服务(如果提示找不到该package,说明apt-get的资源库版本比较旧,运行apt-get update来更新资源库) 2.安装好后输入mongo测试

    2024年02月11日
    浏览(37)
  • Docker 安装 MongoDB开启认证,创建只读用户权限。

    docker run -itd --name mongo -p 27017:27017 mongo --auth --auth 就是开启mongodb权限认证。如果不加 --auth 则是无权限认证,连接成功后任何用户都可以对数据库进行读写操作。 docker run -itd  --name mongo -p 27017:27017 mongo --auth   docker exec -it mongo mongo admin   db.createUser({ user:\\\'admin\\\',pwd:\\\'123456\\\',roles:[

    2024年02月17日
    浏览(61)
  • 一键式开启:IDaaS 日志接入 SLS日志审计发布

    应用身份服务 IDaaS (Identity as a Service)是阿里云原生身份管理系统,可以统一管理 各应用 中分散的账号,并集中分配 应用 访问控制权限,降低低效、重复的账号访问配置和运维工作。IDaaS 旗下的EIAM(Enterprise IAM)面向政企内部身份管理,其服务对象为企业员工、实习生、合作

    2023年04月26日
    浏览(47)
  • ESP32的MQTT AT固件烧录+STM32以ESP32的MQTT AT固件的AT指令连接EMQX下mqtt服务器实现消息订阅和发布

    目录 写在前面 三种方案(利用ESP32连接EMQX下的MQTT) 步骤 ESP32烧录固件并AT指令进行测试。 下载固件  烧录工具下载 烧录固件(选择ESP32)  关于AT 指令与MQTT服务器断开后自动重连MQTT服务器 关于AT指令设置上电自动连接WIFI 关于AT指令设置断开后自动重新连接WIFI STM32对接E

    2023年04月12日
    浏览(49)
  • EMQX的JWT认证

    对于大量设备需要接入EMQX,并且一个设备一个密码,就需要使用JWT认证,批量签发秘钥,配置到各个设备当中。 1、开启JWT认证 在模块菜单下,选择添加模块,在认证鉴权中找到JWT认证,选择进入到JWT的配置界面。 2、配置JWT 认证来源默认选择password,表示用户在客户端中密

    2024年02月16日
    浏览(39)
  • EMQX HTTP Auth认证

    系统的安全性需要从身份认证、操作授权、黑名单机制、数据安全传输等几个方面去考虑,EMQX Broker的安全也是从这几方面考虑,下面分别介绍下EMQX安全特性。 身份验证是大多数应用程序的重要组成部分。MQTT 协议支持用户名/密码认证以及增强认证,例如 SASL/SCRAM 身份验证。

    2023年04月12日
    浏览(56)
  • 开启EMQX的SSL模式及SSL证书生成流程

    首先:需要安装Openssl 以下是openssl命令 生成CA证书 生成服务端证书 生成client证书 生成如下文件: 将生成的CA证书,Server证书,Server私钥放到etc/certs目录 证书存放地址 listener.ssl.external.keyfile = etc/certs/yunding/IoTServerEmq.key listener.ssl.external.certfile = etc/certs/yunding/IoTServerEmq.crt list

    2024年02月10日
    浏览(47)
  • EMQX配置 用户名和密码认证方式连接

    1, 找到mqtt 的 /etc/plugins/ 文件夹下的emqx_auth_mnesia.conf 文件 2 ,vim打开编辑该文件 根据例子添加账号密码 并保存 3, 打开EMQX后台, 找到插件 ,启动该插件, 随后就可以了 4,修改etc/emqx.conf 配置文件 如下 下面是禁用匿名连接,禁用之后, 配置的 账号密码才能生效 vim 查找 /allow_anonymo

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包