How can queues be made private/secure in RabbitMQ in a multitenancy system?
Asked Answered
D

4

43

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.

Dentoid answered 20/10, 2011 at 18:16 Comment(0)
N
21

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.

Nigritude answered 5/8, 2020 at 18:52 Comment(0)
C
9

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 "/".

Compliancy answered 11/11, 2011 at 7:27 Comment(0)
A
2

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.

Aligarh answered 24/10, 2011 at 19:1 Comment(1)
I actually wrote the implementation of that example in the stormed-amqp library (as linked above). I wasn't sure that the exclusive directive was enough security, but I'll experiment with it to see if it is. Thanks.Dentoid
S
0

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

  1. Access control
  2. SASL authentication
  3. SSL support
Selfsatisfied answered 18/4, 2018 at 20:32 Comment(1)
Are Access control and SASL authentication means the same?Filip

© 2022 - 2024 — McMap. All rights reserved.