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

Bri*_*ian 30 security amqp rabbitmq multi-tenant

我已经阅读了RabbitMQ提供的入门指南,甚至为stormed-amqp贡献了第六个例子,所以我对AMQP有了一些了解.

但是,该指南并不全面,可以避免身份验证和授权等问题.

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

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

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

这个问题严格关于RabbitMQ安全性.我知道RabbitMQ支持SSL,它提供端到端加密,我知道RabbitMQ支持用户名/密码验证.我不知道这些内容是否适用于私有化队列使用(也称为ACL),即连接可能是加密的,用户可能已经过验证,但用户可以从所有队列读取/写入.

有人可以在这个更高级的主题上启发我吗?我相信RabbitMQ可以支持这种系统但不完全正面.我知道RabbitMQ中有些东西我不知道,例如什么是虚拟主机,他们会在这种情况下帮助吗?我只是没有看到当前知识中的解决方案仅限于路由密钥,队列名称和交换.

ami*_*jad 7

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

概括

虚拟主机

正如 Michael Dillon 所提到的,您应该首先让一切都发生在内部vhosts虚拟主机)并vhost完全阻止泛型。通用 vhost 被简单地调用,/并且默认情况下只有vhost在您启动 rabbitmq 服务器时才会调用。

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

只需vhosts在您的应用程序中创建尽可能多的逻辑分组。请记住,一个vhost中的资源不知道并且无法与另一个中的资源进行通信vhostvhost通过执行创建一个:

rabbitmqctl add_vhost vhost-name
Run Code Online (Sandbox Code Playgroud)

用户

下一步是创建用户并删除默认guest用户。每个用户都应该有自己的用户名和密码,仅供他们使用。不用说,只有实际的管理员才应该拥有管理员权限。这允许他们管理其他用户vhosts及其权限。通过执行以下操作创建用户:

rabbitmqctl add_user "username"
Run Code Online (Sandbox Code Playgroud)

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

用户权限

但是,用户对 a 的访问vhost不仅仅是二进制的。

RabbitMQ 区分了对资源的配置写入读取操作。在配置操作创建或破坏资源,或者改变他们的行为。在操作注入的消息到资源。而操作检索资源的消息。

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

例如,正则表达式'.*' '.*' '.*'允许用户分别配置、写入和读取vhost. 这将被授予如下

rabbitmqctl set_permissions -p "vhost-name" "username" ".*" ".*" ".*"
Run Code Online (Sandbox Code Playgroud)

而正则表达式'^$' '^(hello).*$' '^(hello|world).*$'不会授予用户任何配置权限,但允许他们写入hello名称以hello或开头的任何资源,并从名称以或开头的任何资源读取world

外卖

vhosts自由使用将资源组合在一起并设置对这些资源的整体权限。

资源的命名非常重要,因为这是在给定vhost.

在 OP 问题的情况下,每个用户都应该被允许仅根据队列的唯一名称读取和写入他们自己的队列。这不一定需要跨越多个,vhosts但如果有意义的话就可以。


Mic*_*lon 6

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

首先让一切都在vhosts内部发生并完全阻止通用vhost,即不要让任何人在vhost"/"上声明队列和交换.


dah*_*ron 2

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