[rabbitmq-discuss] Creating an auth plugin (Kerberos)

Simon MacMullen simon at rabbitmq.com
Tue Nov 13 11:07:34 GMT 2012


To expand on what Emile said...

On 12/11/12 11:44, Simon Lundström wrote:
> I'm trying, first time doing something serious in Erlang, to create an
> Kerberos authentication plugin for RabbitMQ

Cool!

> and this have raised a couple of questions.
>
> I've looked at the other authentication plugins available and tried to
> solve these questions but I haven't succeeded.
>
> 1, Since Kerberos is an authentication protocol, not authorization, how
> can I implement my plugin just to do authN?
> Should I look at SASL EXTERNAL? That looked very SSL client authN specific.

There are two extension points within RabbitMQ here.

The EXTERNAL plugin is an example of how to implement a SASL mechanism 
(rabbit_auth_mechanism behaviour), i.e. control the exchange of 
information on the wire within AMQP, leading to authN. By default "the 
exchange of information ion the wire" means "send username and 
password", but it doesn't have to.

The rabbit_auth_backend behaviour then does two thing:

* Determines how to do authN for a user when we've already decided how 
to do the wire level stuff (e.g. look up in internal DB, make an LDAP 
query).

* Determines how to do authZ once we have a #user{} record.

- in other words it's a "user database".

Note that all the existing rabbit_auth_mechanism implementations call 
into rabbit_access_control:check_user_pass_login/2 or similar - that's 
the entry point to go and find out which rabbit_auth_backends are 
configured and go and query them for authentication.

I suspect to do Kerberos you will need both behaviours - from a quick 
google I *think* you need to control the wire level protocol with 
rabbit_auth_mechanism, and then create a #user{} based on that.

> 1.2, If I use `-behaviour(rabbit_auth_backend).` I must implement
> check_vhost_access and check_resource_access. What is the appropriate
> way to handle this?
> * Don't use `-behaviour(rabbit_auth_backend).`?
> * Implement check_vhost_access and check_resource_access but just have
> them call rabbit_access_control:check_vhost_access?
> Later we are planning on implementing an authZ *only* plugin for
> RabbitMQ, will this break if we want to have a plugin which only
> implements check_vhost_access and check_resource_access?

Well, how do you want it to work? At the moment rabbit_auth_backend ties 
together authN and authZ, because if a backend is the authority that 
says that a user exists, it is likely to the be the only thing which can 
sensibly decide what that user is allowed to do.

You *could* decouple these by having one rabbit_auth_backend which 
implements check_user_login/2 and returns a #user{} with its 
auth_backend field set to a different rabbit_auth_backend that would 
then do authZ. We could add more support for that in RabbitMQ, but I'm 
not sure how your use case works.

> 2, I have started to create my code and the idea is to use open_port to open an
> external binary to do the actual Kerberos "talk". As a start I've made my to
> check the exit status of /bin/true. See
> <https://github.com/simmel/rabbitmq-auth-backend-kerberos>. The code compiles,
> heh, and RabbitMQ starts and "accepts" the connection but some how it fails
> anyway.

I ran your code. Check the SASL log (confusingly that's nothing to do 
with the SASL protocol, it's Erlang's "System Application Support 
Libraries". In RabbitMQ terms it's the "log of things which crashed". 
You should see:

=CRASH REPORT==== 13-Nov-2012::11:04:03 ===
   crasher:
     initial call: rabbit_reader:init/4
     pid: <0.334.0>
     registered_name: []
     exception exit: {unexpected_message,{'EXIT',#Port<0.25776>,normal}}
       in function  rabbit_reader:handle_other/3 (src/rabbit_reader.erl, 
line 363)
       in call from rabbit_reader:start_connection/7 
(src/rabbit_reader.erl, line 238)

i.e. you got a message saying the port had closed. Your plugin 
(executing in the reader process) did not handle this message, and the 
reader process is designed to crash when it receives a message it didn't 
expect.

So make sure to receive that message in your plugin...

Cheers, Simon

-- 
Simon MacMullen
RabbitMQ, VMware


More information about the rabbitmq-discuss mailing list