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

时间:2011-10-20 18:16:37

标签: security rabbitmq amqp multi-tenant

我已经阅读了RabbitMQ提供的Get Started指南,甚至将第六个例子贡献给了stormed-amqp,所以我对AMQP有了一些了解。

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

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

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

  1. 我们的服务器不会将数据传送到错误的租户程序(这很容易处理并且相关但不受质疑)。
  2. 租户程序无法从不属于他们的队列中读取数据。
  3. 租户计划无法写入不属于他们的队列。
  4. 这个问题严格关于RabbitMQ安全性。我知道RabbitMQ支持SSL,它提供端到端加密,我知道RabbitMQ支持用户名/密码验证。我不知道这些是否适用于私有化队列使用(也称为ACL),即连接可能是加密的,用户可能已经过验证,但用户可以从所有队列中读取/写入。

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

4 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:4)

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

摘要

虚拟主机

正如迈克尔·狄龙(Michael Dillon)所提到的,您应该首先使所有事情发生在vhostsvirtual hosts)内部,然后完全阻止通用vhost。通用虚拟主机简称为/,默认情况下,它是启动Rabbitmq服务器时唯一的vhost

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

仅创建与您的应用程序中的逻辑分组一样多的vhosts。请记住,一个vhost中的资源不知道并且无法与另一个vhost中的资源进行通信。通过执行以下操作来创建vhost

rabbitmqctl add_vhost vhost-name

用户

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

rabbitmqctl add_user "username"

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

User permissions

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

RabbitMQ区分对以下内容的 configure write read 操作 资源。 configure 操作会创建或销毁资源,或者 改变他们的行为。 write 操作将消息注入到 资源。然后 read 操作从资源中检索消息。

在文档的链接部分有一个漂亮的表,该表指示什么命令算作什么类型的操作,例如queue.bindwrite操作,而queue.getread操作。但是,复杂性并不仅限于此,实际上是根据管理员选择的自定义regular expression(正则表达式)为每种操作类型授予权限。

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

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

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

外卖

自由使用world将资源分组在一起,并整体上对这些资源设置权限。

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

对于OP的问题,应允许每个用户仅根据队列的唯一名称读写自己的队列。不一定需要跨多个vhost,但是如果有意义的话可以。

答案 2 :(得分:2)

我相信this教程会演示您要做的事情 回调队列是独占的,自动删除并且自动生成其名称的事实应该提供足够的安全性。

答案 3 :(得分:0)

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

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