如何在多租户系统中的 RabbitMQ 中使队列私有/安全?

发布于 2024-12-11 05:23:41 字数 828 浏览 6 评论 0原文

我已阅读 RabbitMQ 提供的 入门 指南,甚至还向 stormed-amqp,所以我对AMQP。

然而,该指南并不全面,并且避免了身份验证和授权等内容。

我们正在设计一个多租户系统,该系统将在 RPC 类型的情况下使用 RabbitMQ。这种 RPC 实现的不同之处可能在于远程过程实际上是系统上的其他租户程序。

基本上,我想隔离数据总线,其中包括以下断言:

  1. 我们的服务器不会将数据传递给错误的租户程序(这很容易处理并且相关但不会受到质疑)。
  2. 租户程序无法从不属于他们的队列中读取数据。
  3. 租户程序无法写入不属于他们的队列。

这个问题严格来说是关于 RabbitMQ 安全性的。我知道 RabbitMQ 支持 SSL,它提供端到端加密,并且我知道 RabbitMQ 支持用户名/密码身份验证。我不知道这些事情是否适用于私有化队列使用(又名 ACL),即连接可能被加密,并且用户可能被验证,但用户可以从所有队列读取/写入。

有人可以启发我这个更高级的主题吗?我相信 RabbitMQ 可以支持这种系统,但并不完全肯定。我知道 RabbitMQ 中有些东西我只是不知道,例如什么是虚拟主机,它们在这种情况下会有帮助吗?我只是在我目前的知识范围内没有看到解决方案仅限于路由键、队列名称和交换。

I have read the Get Started guide provided by RabbitMQ and have even contributed the sixth example to stormed-amqp, so I have an inkling of knowledge about AMQP.

However, the guide is not comprehensive and avoids things like authentication and authorization.

We're designing a multitenancy system that will use RabbitMQ in an RPC-type of situation. What is perhaps different about this implementation of RPC is that the remote procedures will actually be other tenant programs on the system.

Basically, I want to isolate the data buses, which includes the following assertions:

  1. Our server will not deliver data to the wrong tenant program (this is handled easily and is relevant but not questioned).
  2. Tenant programs are not be able to read data from queues that aren't theirs.
  3. Tenant programs are not be able to write to queues that aren't theirs.

This question is strictly about RabbitMQ security. I know that RabbitMQ supports SSL, which provides end-to-end encryption, and I know RabbitMQ supports username/password authentication. I don't know if these things apply to privatizing queue usage (aka ACL), i.e. the connection may be encrypted, and the user may be verified, but the user can read to / write from all the queues.

Can anybody enlighten me on this more advanced topic? I'm confident that RabbitMQ can support this sort of system but not exactly positive. I know there are things in RabbitMQ that I just don't know about, e.g. what are vhosts and will they help in this situation? I just don't see the solution in my current knowledge limited to routing keys, queue names and exchanges.

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

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

发布评论

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

评论(4

゛时过境迁 2024-12-18 05:23:41

TLDR:相关信息可以在这里找到:https://www.rabbitmq.com/access-control .html。然而,由于rabbitmq文档非常冗长,下面我将描述似乎是锁定资源访问的唯一解决方案。

摘要

虚拟主机

正如 Michael Dillon 提到的,您应该首先让一切发生在 vhosts 中 (虚拟主机)并完全阻止通用vhost。通用虚拟主机简称为/,默认情况下是启动rabbitmq 服务器时唯一的vhost

给定资源(即队列或交换)必须仅存在于一个vhost 和一个vhost 中。一个rabbitmq连接还必须专门连接到一个vhost(这可以通过将vhost名称附加到rabbitmq URL来指定,例如amqp://username:密码@myserver:5672/vhost)。因此,rabbitmq 连接只能访问位于其所连接的虚拟主机中的队列和交换器。

只需创建与应用程序中的逻辑分组一样多的虚拟主机即可。请记住,一个vhost 中的资源不知道并且无法与另一vhost 中的资源进行通信。通过以下操作创建vhost

rabbitmqctl add_vhost vhost-name

用户

下一步是创建用户并删除默认的guest 用户。每个用户都应该有自己的用户名和密码,并且只能由他们使用。不用说,只有实际管理员才应该拥有管理员权限。这使他们能够管理其他用户、虚拟主机及其权限。通过执行以下操作创建用户:

rabbitmqctl add_user "username"

用户可以使用其凭据创建rabbitmq连接,从而连接到vhost。但是,只有当这是用户有权访问的虚拟主机时,连接才会被批准。只有管​​理员可以授予和修改用户对虚拟主机的访问权限。用户可以被授予对多个vhosts的访问权限,并使用其凭据同时连接到多个vhosts(但不能在同一连接中连接到不同的vhosts) 。

用户权限

但是,用户对虚拟主机的访问权限并不是简单的二进制。

RabbitMQ 区分配置写入读取操作
一种资源。 配置操作创建或销毁资源,或者
改变他们的行为。 写入操作将消息注入到
资源。 读取操作从资源中检索消息。

文档的链接部分中有一个很好的表格,它表示什么命令算作什么类型的操作,例如 queue.bind 是一个 write 操作,而 queue.bind 是一个 write 操作。 get 是一个read 操作。然而复杂性并不止于此,实际上是根据自定义正则表达式(正则表达式)管理员选择的。

例如,正则表达式 '.*' '.*' '.*' 允许用户分别在该 vhost 中的任何资源上进行配置、写入和读取。这将被授予像这样

rabbitmqctl set_permissions -p "vhost-name" "username" ".*" ".*" ".*"

而正则表达式'^$' '^(hello).*$' '^(hello|world).*$' 不会向用户授予任何配置权限,但允许他们写入名称以 hello< 开头的任何资源/代码> 和从名称以 helloworld 开头的任何资源中读取。

要点

自由地使用vhosts 将资源分组在一起,并对这些资源作为一个整体设置权限。

资源命名非常重要,因为这是在给定虚拟主机内配置对该资源的访问的唯一方法。

对于OP的问题,每个用户都应该被授予只能根据队列的唯一名称读取和写入自己的队列的权限。这不一定需要跨越多个虚拟主机,但如果有意义的话也可以。

TLDR: The relevant information can be found here: https://www.rabbitmq.com/access-control.html. However, since the rabbitmq documentation is very verbose, below I will describe what seems like the only solution to locking down access to resources.

Summary

Virtual hosts

As Michael Dillon mentions, you should start by making everything happen inside vhosts (virtual hosts) and block the generic vhost entirely. The generic vhost is simply called / and is by default the only vhost when you start a rabbitmq server.

A given resource (i.e. queue or exchange) must live in one vhost and one vhost only. A rabbitmq connection must also specifically connect to a single vhost (this can just be specified by appending the vhost name to the rabbitmq URL e.g. amqp://username:password@myserver:5672/vhost). Therefore a rabbitmq connection can only access queues and exchanges that live in the vhost it has connected to.

Simply create as many vhosts as there are logical groupings in your application. Remember that resources in one vhost are not aware of and cannot communicate with resources in another vhost. Create a vhost by doing:

rabbitmqctl add_vhost vhost-name

Users

The next step is to create users and remove the default guest user. Each user should have their own username and password which should be used only by them. Needless to say, only the actual administrator should have administrator privileges. This allows them to manage other users, vhosts and their permissions. Create a user by doing:

rabbitmqctl add_user "username"

Users can use their credentials to create a rabbitmq connection and thereby connect to a vhost. However, the connection is only approved if this is a vhost the user has access to. Only an adminstrator can grant and modify a user's access permissions to a vhost. A user can be granted access to multiple vhosts and use their credentials to connect to multiple vhosts simultaneously (but not different vhosts within the same connection).

User permissions

However, a user's access to a vhost is not simply binary.

RabbitMQ distinguishes between configure, write and read operations on
a resource. The configure operations create or destroy resources, or
alter their behaviour. The write operations inject messages into a
resource. And the read operations retrieve messages from a resource.

There is a nice table in the linked section of the docs which denotes what command counts as what kind of operation e.g. queue.bind is a write operation whereas queue.get is a read operation. However the complexity doesn't end there, permissions are actually granted to each operation type based on a custom regular expression (regex) of the administrator's choosing.

For instance the regex '.*' '.*' '.*' allows the user to configure, write and read respectively on any resource in that vhost. This would be granted like so:

rabbitmqctl set_permissions -p "vhost-name" "username" ".*" ".*" ".*"

Whereas the regex '^$' '^(hello).*$' '^(hello|world).*$' would not give the user any configuration permissions but would allow them to write to any resource whose name began with hello and read from any resource whose name began with either hello or world.

Takeaways

Use vhosts liberally to group resources together and set permissions on these resources as a whole.

Naming of resources is very important as this is the only way to configure access to that resource within a given vhost.

In the case of the OP's question, each user should be permissioned to only read and write to their own queue based on the queue's unique name. This does not necessarily need to be across multiple vhosts but can be if it makes sense for it to be.

云朵有点甜 2024-12-18 05:23:41

在多租户系统中,您可以通过定义用户拥有的权限来确保队列的安全。请在此处阅读 RabbitMQ 管理指南的访问控制部分 http://www.rabbitmq.com/admin-guide.html

首先让所有事情发生在虚拟主机内并完全阻止通用虚拟主机,即不要让任何人在虚拟主机“/”上声明队列和交换。

In a multitenancy system you would make queues secure by defining the permissions that users have. Read the access control section of the RabbitMQ admin guide here http://www.rabbitmq.com/admin-guide.html

Start by making everything happen inside vhosts and block the generic vhost entirely, i.e. don't let anyone declare queues and exchanges on vhost "/".

半岛未凉 2024-12-18 05:23:41

我相信教程演示了您正在尝试做的事情。
事实上,回调队列是独占的、自动删除的,并且其名称是自动生成的,这应该提供足够的安全性。

I believe this tutorial demonstrates what you are trying to do.
The fact that the callback queue is exclusive, auto-deletes, and has its name auto-generated should provide enough security.

哭了丶谁疼 2024-12-18 05:23:41

为了 Rabbitmq 服务器的安全性,RabbitMQ 中有一些安全机制:

  1. 访问控制
  2. SASL 身份验证
  3. SSL 支持

For security in Rabbitmq server, there are some security mechanism in RabbitMQ:

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