在Vernemq中启用多个身份验证/授权插件

发布于 2025-02-12 10:18:58 字数 4069 浏览 0 评论 0原文

在Vernemq中的身份验证/授权方面,我希望将检查多个启用插件,以确定是否允许连接/pub/sub。

但是,我在部署中经历了不同的结果。

如果只有一个auth插件 - vmq.aclvmq.viversity - 启用,则可以按预期工作。 但是,在启用了两个插件时,仅vmq.diversity似乎正在工作。

我想问的是:

  1. 这是vernemq的预期行为?

  2. 如果没有,如何启用多个auth插件?

  3. 启用了多个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'

使用上述配置和文件,以下插件下定义了以下用户。

  1. 基于文件的身份验证 - vmq.passwd插件

    • file-user1
    • file-user2
  2. 通过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:

  1. Is this the expected behaviour of vernemq?

  2. If not, how can multiple auth plugins be enabled?

  3. 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.

  1. file-based authentication - vmq.passwd plugin

    • file-user1
    • file-user2
  2. authentication via postgres database - vmq.diversity plugin

    • db-user1
    • db-user2

When both plugins are enabled, only the user defined in the database are able to authenticate and connect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凑诗 2025-02-19 10:18:58

通常,身份验证插件(实现auth_on_register -hook)将对经纪人提供内部响应。如果插件对客户端进行身份验证,则响应将为ok。响应也可以是下一个告诉代理当前插件无法验证客户端,因此代理应该只需检查next插件即可。

这主要是一种允许用户链接自己的插件的方法。由于与蚊子格式兼容的原因,它没有针对基于文件的插件实现。
但是,您可以轻松地在vmq_diversity插件中实现链条,因为您可以调整LUA脚本。

  1。这是Vernemq的预期行为吗?
 

现在,是的,请参见上述说明

  2。如果没有,如何启用多个auth插件?
 

通过使插件返回下一个而不是身份验证错误。然后,Verne将只需遍历所有插件,直到它用尽插件来询问。您将始终看到典型的plugin_chain_exhausted记录为被拒绝客户端的原因。让我知道您何时需要更多帮助。

  3。启用了多个auth插件,他们以什么顺序进行检查?
 

按负载顺序检查它们(无论是通过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 be ok. The response can also be next to tell the broker that the current plugin cannot authenticate the client, so the broker should just go check the next 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.

1. Is this the expected behaviour of vernemq?

Right now, yes, see above explanation

2. If not, how can multiple auth plugins be enabled?

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 typical plugin_chain_exhausted logged as a reason for a rejected client. Let me know when you need more help with that.

3. With multiple auth plugins enabled, in what order are they checked?

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 the vmq-admin plugin show command too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文