在Vernemq中启用多个身份验证/授权插件
在Vernemq中的身份验证/授权方面,我希望将检查多个启用插件,以确定是否允许连接/pub/sub。
但是,我在部署中经历了不同的结果。
如果只有一个auth插件 - vmq.acl
或vmq.viversity
- 启用,则可以按预期工作。 但是,在启用了两个插件时,仅vmq.diversity
似乎正在工作。
我想问的是:
这是
vernemq
的预期行为?如果没有,如何启用多个auth插件?
启用了多个auth插件,以什么顺序检查?
vernemq服务通过Docker组成
,如下所述。
# docker-compose.yaml
services:
vernemq:
image: vernemq/vernemq
container_name: vernemq_broker
environment:
- DOCKER_VERNEMQ_ACCEPT_EULA=yes
- DOCKER_VERNEMQ_ALLOW_ANONYMOUS=off
- DOCKER_VERNEMQ_PLUGINS__VMQ_PASSWD=on
- DOCKER_VERNEMQ_PLUGINS__VMQ_ACL=on
- DOCKER_VERNEMQ_VMQ_ACL__ACL_RELOAD_INTERVAL=10
- DOCKER_VERNEMQ_PLUGINS__VMQ_DIVERSITY=on
- DOCKER_VERNEMQ_VMQ_DIVERSITY__AUTH_POSTGRES__ENABLED=on
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__HOST=auth_db
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PORT=5432
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__USER=postgres
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PASSWORD=password
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__DATABASE=postgres
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PASSWORD_HASH_METHOD=crypt
# insecure approach to setting password - for testing/development only
- DOCKER_VERNEMQ_USER_file_user1=file_user1_password
- DOCKER_VERNEMQ_USER_file_user2=file_user2_password
- DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL=debuga
volumes:
- ./vernemq/vmq.acl:/etc/vernemq/vmq.acl
ports:
- 1883:1883
depends_on:
- auth_db
auth_db:
image: postgres:latest
container_name: vernemq_auth_db
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
volumes:
- ./auth_db/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
ports:
- 5432:5432
expose:
- 5432
# vmq.acl
user file-user1
topic private/file/#
topic public/#
user file-user2
topic private/file/#
topic public/#
身份验证数据库用脚本初始化:
-- init-db.sql
CREATE EXTENSION pgcrypto;
CREATE TABLE IF NOT EXISTS vmq_auth_acl (
mountpoint character varying(10) NOT NULL,
client_id character varying(128) NOT NULL,
username character varying(128) NOT NULL,
password character varying(128),
publish_acl json,
subscribe_acl json,
CONSTRAINT vmq_auth_acl_primary_key PRIMARY KEY (mountpoint, client_id, username)
);
CREATE OR REPLACE PROCEDURE insert_user(user_ref text)
LANGUAGE SQL AS
$$
WITH x AS (
SELECT ''::text AS mountpoint,
CONCAT('db-', user_ref, '-client-id')::text AS client_id, -- eg: 'db-user1-client-id'
CONCAT('db-', user_ref)::text AS username, -- eg: 'db-user1'
CONCAT('db-', user_ref, '-password')::text AS password, -- eg: 'db-user1-password'
gen_salt('bf')::text AS salt,
'[{"pattern": "private/db/#"}, {"pattern": "public/#"}]'::json AS publish_acl,
'[{"pattern": "private/db/#"}, {"pattern": "public/#"}]'::json AS subscribe_acl
)
INSERT INTO vmq_auth_acl (
mountpoint,
client_id,
username,
password,
publish_acl,
subscribe_acl
)
SELECT
x.mountpoint,
x.client_id,
x.username,
crypt(x.password, x.salt),
publish_acl,
subscribe_acl
FROM x ON CONFLICT (mountpoint, client_id, username) DO NOTHING;
$$;
--
--
CALL insert_user('user1'); -- inserts row for user 'db-user1'
CALL insert_user('user2'); -- inserts row for user 'db-user2'
使用上述配置和文件,以下插件下定义了以下用户。
基于文件的身份验证 -
vmq.passwd
插件file-user1
file-user2
通过Postgres数据库身份验证 -
vmq.diversity
插件db-user1
db-user2
当启用两个插件时,仅数据库中定义的用户是能够身份验证并连接。
When it comes to authentication/authorization in Vernemq, I expected that multiple enabled plugins would be checked in order to determine if a connect/pub/sub is permitted or not.
However, I am experiencing different results in my deployment.
If only one of the auth plugins - either vmq.acl
or vmq.diversity
- is enabled, it works as expected.
But, with both plugins enabled, only vmq.diversity
seems to be working.
What I would like to ask is:
Is this the expected behaviour of
vernemq
?If not, how can multiple auth plugins be enabled?
With multiple auth plugins enabled, in what order are they checked?
The vernemq service is run via docker compose
as described below.
# docker-compose.yaml
services:
vernemq:
image: vernemq/vernemq
container_name: vernemq_broker
environment:
- DOCKER_VERNEMQ_ACCEPT_EULA=yes
- DOCKER_VERNEMQ_ALLOW_ANONYMOUS=off
- DOCKER_VERNEMQ_PLUGINS__VMQ_PASSWD=on
- DOCKER_VERNEMQ_PLUGINS__VMQ_ACL=on
- DOCKER_VERNEMQ_VMQ_ACL__ACL_RELOAD_INTERVAL=10
- DOCKER_VERNEMQ_PLUGINS__VMQ_DIVERSITY=on
- DOCKER_VERNEMQ_VMQ_DIVERSITY__AUTH_POSTGRES__ENABLED=on
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__HOST=auth_db
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PORT=5432
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__USER=postgres
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PASSWORD=password
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__DATABASE=postgres
- DOCKER_VERNEMQ_VMQ_DIVERSITY__POSTGRES__PASSWORD_HASH_METHOD=crypt
# insecure approach to setting password - for testing/development only
- DOCKER_VERNEMQ_USER_file_user1=file_user1_password
- DOCKER_VERNEMQ_USER_file_user2=file_user2_password
- DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL=debuga
volumes:
- ./vernemq/vmq.acl:/etc/vernemq/vmq.acl
ports:
- 1883:1883
depends_on:
- auth_db
auth_db:
image: postgres:latest
container_name: vernemq_auth_db
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
volumes:
- ./auth_db/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
ports:
- 5432:5432
expose:
- 5432
# vmq.acl
user file-user1
topic private/file/#
topic public/#
user file-user2
topic private/file/#
topic public/#
The authentication database is initialised with the script:
-- init-db.sql
CREATE EXTENSION pgcrypto;
CREATE TABLE IF NOT EXISTS vmq_auth_acl (
mountpoint character varying(10) NOT NULL,
client_id character varying(128) NOT NULL,
username character varying(128) NOT NULL,
password character varying(128),
publish_acl json,
subscribe_acl json,
CONSTRAINT vmq_auth_acl_primary_key PRIMARY KEY (mountpoint, client_id, username)
);
CREATE OR REPLACE PROCEDURE insert_user(user_ref text)
LANGUAGE SQL AS
$
WITH x AS (
SELECT ''::text AS mountpoint,
CONCAT('db-', user_ref, '-client-id')::text AS client_id, -- eg: 'db-user1-client-id'
CONCAT('db-', user_ref)::text AS username, -- eg: 'db-user1'
CONCAT('db-', user_ref, '-password')::text AS password, -- eg: 'db-user1-password'
gen_salt('bf')::text AS salt,
'[{"pattern": "private/db/#"}, {"pattern": "public/#"}]'::json AS publish_acl,
'[{"pattern": "private/db/#"}, {"pattern": "public/#"}]'::json AS subscribe_acl
)
INSERT INTO vmq_auth_acl (
mountpoint,
client_id,
username,
password,
publish_acl,
subscribe_acl
)
SELECT
x.mountpoint,
x.client_id,
x.username,
crypt(x.password, x.salt),
publish_acl,
subscribe_acl
FROM x ON CONFLICT (mountpoint, client_id, username) DO NOTHING;
$;
--
--
CALL insert_user('user1'); -- inserts row for user 'db-user1'
CALL insert_user('user2'); -- inserts row for user 'db-user2'
With the above configuration and files, there are the following users defined under the following plugins.
file-based authentication -
vmq.passwd
pluginfile-user1
file-user2
authentication via postgres database -
vmq.diversity
plugindb-user1
db-user2
When both plugins are enabled, only the user defined in the database are able to authenticate and connect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,身份验证插件(实现
auth_on_register
-hook)将对经纪人提供内部响应。如果插件对客户端进行身份验证,则响应将为ok
。响应也可以是下一个
告诉代理当前插件无法验证客户端,因此代理应该只需检查next
插件即可。这主要是一种允许用户链接自己的插件的方法。由于与蚊子格式兼容的原因,它没有针对基于文件的插件实现。
但是,您可以轻松地在
vmq_diversity
插件中实现链条,因为您可以调整LUA脚本。现在,是的,请参见上述说明
通过使插件返回
下一个
而不是身份验证错误。然后,Verne将只需遍历所有插件,直到它用尽插件来询问。您将始终看到典型的plugin_chain_exhausted
记录为被拒绝客户端的原因。让我知道您何时需要更多帮助。按负载顺序检查它们(无论是通过
vernemq.conf
文件内部加载插件,还是通过插件启用命令在外部加载插件)。该顺序也应在vmq-admin插件show
命令中可见。In general, an authentication plugin (implementing the
auth_on_register
-hook) will give an internal response to the broker. If the plugin authenticates the client, the response will beok
. The response can also benext
to tell the broker that the current plugin cannot authenticate the client, so the broker should just go check thenext
plugin.This was mostly intended a way to allow users to chain their own plugins. It was not implemented for the file-based plugin, for reasons of compatibility to the Mosquitto format.
You can easily implement a chain in a
vmq_diversity
plugin, though, as you can adapt the Lua scripts.Right now, yes, see above explanation
By making the plugins return
next
instead of an authentication error. Verne will then just go through all the plugins until it runs out of plugins to ask. You will always see the typicalplugin_chain_exhausted
logged as a reason for a rejected client. Let me know when you need more help with that.They are checked in load order (whether you load the plugins internally via
vernemq.conf
file or externally via the plugin enable command). The order should be visible in thevmq-admin plugin show
command too.