Rabbit MQ Access Control

57 views
Skip to first unread message

Willem Jan

unread,
Jul 5, 2015, 6:58:41 PM7/5/15
to rabbitm...@googlegroups.com
Hello,

I am still a bit unclear about the Rabbit MQ Access control and how this works and have a bit of problem understanding the explanation on https://www.rabbitmq.com/access-control.html. However I seem to have been able to manage a scenario I needed for an project but am still a bit unsure if this how it should work or if there are better solutions.

First I will explain what I tried to to achieve and how I have solved it, I want to publish information for a specific user account and prevent any intended or unintended abuse by clients as much as possible. By limiting the ability to create new resources and restricting access to other resources as much as possible.

 I want to allow user1 only to subscribe to a topic and get the results in user1.private and consume the data. Also I dont want him to be able to create any other queues or abuse this queue in any way. I also want user1 only to be able to read data published for this specific user.

I have come up with the following solution that works but I am not really clear if this can be achieved by simpler method or if read regex can be improved by only allowing acces to limited services for instance Read regexp "^user1.service1.*$"

Please let me know if this method is approriate or if there are any security issues with this (besides SSL)

The listener for topic service1
User:User1
Virtual hostConfigure regexpWrite regexpRead regexp
vhost1^user1.private$^user1.private$^user1.*$



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.IO;


namespace RabbitListen
{
    class Program
    {
        private const string EXCHANGE_NAME = "user1";
 
        private static void Main(string[] args)
        {
           var factory = new ConnectionFactory() { HostName = "localhost", UserName = "user1", Password = "changeme", VirtualHost = "vhost1", Protocol = Protocols.DefaultProtocol, Port =  AmqpTcpEndpoint.UseDefaultPort };
           using(IConnection connection = factory.CreateConnection())
            {
                using(IModel channel = connection.CreateModel())
                {
                    //channel.ExchangeDeclare(EXCHANGE_NAME, "topic");
                    Dictionary<string, object> dictionary = new Dictionary<string, object>();
                    string queueName = channel.QueueDeclare(EXCHANGE_NAME + ".private", false, true, true, dictionary);// + Guid.NewGuid().ToString ()/EXCHANGE_NAME +
                    channel.QueueBind(queueName, EXCHANGE_NAME, EXCHANGE_NAME +".service1.*");
                    Console.WriteLine("Waiting for messages");
                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    channel.BasicConsume(queueName, true, consumer);
 
                    while (true)
                    {
                        BasicDeliverEventArgs e = (BasicDeliverEventArgs) consumer.Queue.Dequeue();
                        Console.WriteLine(Encoding.ASCII.GetString(e.Body));
                    }
                }
            }
        }
    }
}


Publisher for sample messages1 user1 and user2 in service1
User:Vhost1Admin
Virtual hostConfigure regexpWrite regexpRead regexp
vhost1.*.*.*



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RabbitMQ.Client;
using System.Threading;

namespace RabbitSend
{
    class Program
    {
        private const string EXCHANGE_NAME1 = "user1";
        private const string EXCHANGE_NAME2 = "user2";
        public static void Main(string[] args)
        {
            var factory = new ConnectionFactory() { HostName = "localhost", UserName = "vhost1admin", Password = "changeme", VirtualHost = "vhost1", Protocol = Protocols.DefaultProtocol, Port =  AmqpTcpEndpoint.UseDefaultPort };
            using(IConnection connection = factory.CreateConnection())
            {
                using(IModel channel = connection.CreateModel())
                {
                    Dictionary<string,object> dict = new Dictionary<string, object>();
                    dict.Add("expires", 60000);
                    channel.ExchangeDeclare(EXCHANGE_NAME1, "topic", false,false, dict);
                    channel.ExchangeDeclare(EXCHANGE_NAME2, "topic", false, false, dict);
                    for (int i = 0; i < 10000000; i++)
                    {
                        byte[] payload = Encoding.ASCII.GetBytes(EXCHANGE_NAME1 + ":"  + i);
                        channel.BasicPublish(EXCHANGE_NAME1, EXCHANGE_NAME1 + ".service1.key1", null, payload);
                        payload = Encoding.ASCII.GetBytes(EXCHANGE_NAME2 + ":" + i);
                        channel.BasicPublish(EXCHANGE_NAME2, EXCHANGE_NAME1 +".service1.key1", null, payload);
                        Console.WriteLine("Sent Message " + i);
                        Thread.Sleep(1000);
                    }
                }
            }
        }
    }
}

Michael Klishin

unread,
Jul 5, 2015, 7:45:11 PM7/5/15
to rabbitm...@googlegroups.com, Willem Jan
On 6 Jul 2015 at 01:58:45, Willem Jan (wj.sch...@gmail.com) wrote:
> I want to allow user1 only to subscribe to a topic and get the results
> in user1.private and consume the data. Also I dont want him to
> be able to create any other queues or abuse this queue in any way.
> I also want user1 only to be able to read data published for this
> specific user.
>
> I have come up with the following solution that works but I am not
> really clear if this can be achieved by simpler method or if read
> regex can be improved by only allowing acces to limited services
> for instance Read regexp "^user1.service1.*$”

Your solution looks good to me. Some consider disable publishing
over default exchange but it will be fairly annoying to do without
exchange and queue permission separation, which we don’t currently provide. 
--
MK

Staff Software Engineer, Pivotal/RabbitMQ


Reply all
Reply to author
Forward
0 new messages