[rabbitmq-discuss] X.509 client authentication

71 views
Skip to first unread message

Warren Smith

unread,
Jan 6, 2011, 9:36:29 AM1/6/11
to rabbitmq...@lists.rabbitmq.com

 

Hi all,

 

I’m investigating using RabbitMQ as part of a project and I’ve got a question about client authentication. Right now, the clients in this project (users, daemons, etc.) all have X.509 certificates.  It would be very useful if these identities could be used for authentication and authorization in RabbitMQ.

 

I found the SSL documentation for RabbitMQ and I’ve been working on configuring a RabbitMQ service to support SSL. However, it appears that even if the client program presents a certificate for authentication, this identity doesn’t seem to be used by RabbitMQ. The client still needs to present a username/password – this is what I’d like to avoid.

 

Is it currently possible to use the DN in the client certificate as the identity of the client? I found a thread about this on the email list (http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2009-July/004045.html) and the conclusion seemed to be that using the client DN was possible with some modifications to RabbitMQ and that someone was going to take a look at it. I don’t see it referenced anywhere else, so maybe it didn’t happen.

 

The approach of mapping the DN in a client certificate to a RabbitMQ username and then doing authorization based on that username seems like it would work fine for what I’m trying to do, btw.

 

Thanks,

 

Warren

Simon MacMullen

unread,
Jan 6, 2011, 9:56:17 AM1/6/11
to rabbitmq...@lists.rabbitmq.com
On 06/01/11 14:36, Warren Smith wrote:
> Hi all,

Hi Warren.

> I’m investigating using RabbitMQ as part of a project and I’ve got a
> question about client authentication. Right now, the clients in this
> project (users, daemons, etc.) all have X.509 certificates. It would be
> very useful if these identities could be used for authentication and
> authorization in RabbitMQ.
>
> I found the SSL documentation for RabbitMQ and I’ve been working on
> configuring a RabbitMQ service to support SSL. However, it appears that
> even if the client program presents a certificate for authentication,
> this identity doesn’t seem to be used by RabbitMQ. The client still
> needs to present a username/password – this is what I’d like to avoid.
>
> Is it currently possible to use the DN in the client certificate as the
> identity of the client?

Not in any current release.

However, we have been working on this recently and the next version will
have a much expanded view of authentication / authorisation that will
allow you to do this, using the SASL EXTERNAL authentication mechanism
(which we take to mean "take the authenticated user as being the CN from
the X509 certificate).

There will also be an authentication / authorisation backend plugin
mechanism that will mean details of which users exist do not need to be
stored in the internal Mnesia database.

This is all on the default branch today if you feel like building from
source.

To use SASL EXTERNAL, support is needed in the clients. We've added it
to the Java, .NET and Erlang clients, but if you're using a third party
client it will need a (hopefully rather small) tweak.

For your needs, would you want to store the details of users and
permissions in some database (either Mnesia or something like LDAP), or
would you want your PKI to be the entire user database (which would
require that all users have the same hard-coded permissions)? The former
will definitely be possible with the next release, the latter would need
some kind of null backend plugin which could probably be written fairly
easily.

Cheers, Simon

--
Simon MacMullen
Staff Engineer, RabbitMQ
SpringSource, a division of VMware

_______________________________________________
rabbitmq-discuss mailing list
rabbitmq...@lists.rabbitmq.com
https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss

Warren Smith

unread,
Jan 6, 2011, 11:46:45 AM1/6/11
to Simon MacMullen, rabbitmq...@lists.rabbitmq.com

Hi Simon,

Thanks for the quick response. I'll grab the latest source and see what I can do with it. One thing - you say CN, not DN. Is this customizable so that a DN can be used instead? We have enough users and accept more than one CA so it becomes possible that 2 people have the same CN (but different DNs). I don't expect to hit this for any of the use cases I want to support in the next year or so, though.

I've been using the Java client when trying out the SSL stuff so that should be fine. Ultimately I'd like to use a Python client.

I could handle storage of user details and authorization in a number of ways without any problems. I could store an external mapping of DN -> RabbitMQ username and then let RabbitMQ do its normal authorization against the username. I could store DNs and permissions externally and have RabbitMQ do authorization call outs. I'm sure there are other ways that would work fine, too. I do want different users to have different permissions, but doing this on a per-vhost level should be enough for me.

I think the main thing is how much you all want to integrate client DNs into the service vs a plugin. If you want it very integrated, DN->username mappings could be stored in the Mnesia and managed by rabbitmqctl. A user could then potentially have multiple DNs (we have this situation sometimes) and be able to authenticate using a DN or a username/password.

Thanks,


Warren


-----Original Message-----
From: rabbitmq-dis...@lists.rabbitmq.com [mailto:rabbitmq-dis...@lists.rabbitmq.com] On Behalf Of Simon MacMullen
Sent: Thursday, January 06, 2011 8:56 AM
To: rabbitmq...@lists.rabbitmq.com
Subject: Re: [rabbitmq-discuss] X.509 client authentication

On 06/01/11 14:36, Warren Smith wrote:
> Hi all,

Hi Warren.

> I'm investigating using RabbitMQ as part of a project and I've got a
> question about client authentication. Right now, the clients in this
> project (users, daemons, etc.) all have X.509 certificates. It would be
> very useful if these identities could be used for authentication and
> authorization in RabbitMQ.
>
> I found the SSL documentation for RabbitMQ and I've been working on
> configuring a RabbitMQ service to support SSL. However, it appears that
> even if the client program presents a certificate for authentication,
> this identity doesn't seem to be used by RabbitMQ. The client still

> needs to present a username/password - this is what I'd like to avoid.

Simon MacMullen

unread,
Jan 7, 2011, 6:43:49 AM1/7/11
to rabbitmq...@lists.rabbitmq.com
On 06/01/11 16:46, Warren Smith wrote:
> Thanks for the quick response. I'll grab the latest source and see
> what I can do with it. One thing - you say CN, not DN. Is this
> customizable so that a DN can be used instead? We have enough users
> and accept more than one CA so it becomes possible that 2 people have
> the same CN (but different DNs). I don't expect to hit this for any
> of the use cases I want to support in the next year or so, though.

I have to admit I picked CNs for simplicity. The problem with DNs is
that in general we assume that a username is a string, and can be
matched as such. As soon as we start using DNs as usernames we have all
sorts of problems with normalisation. I'm not a real X.509 expert, but
it doesn't seem like there's a standard normalisation for DNs as
strings. There are some conventions but they seem to get very hazy once
you look at issues like escaping.

I'll have a look at how this could be made to work though.

> I've been using the Java client when trying out the SSL stuff so that
> should be fine. Ultimately I'd like to use a Python client.
>
> I could handle storage of user details and authorization in a number
> of ways without any problems. I could store an external mapping of DN
> -> RabbitMQ username and then let RabbitMQ do its normal
> authorization against the username. I could store DNs and permissions
> externally and have RabbitMQ do authorization call outs. I'm sure
> there are other ways that would work fine, too. I do want different
> users to have different permissions, but doing this on a per-vhost
> level should be enough for me.
>
> I think the main thing is how much you all want to integrate client
> DNs into the service vs a plugin. If you want it very integrated,
> DN->username mappings could be stored in the Mnesia and managed by
> rabbitmqctl. A user could then potentially have multiple DNs (we have
> this situation sometimes) and be able to authenticate using a DN or a
> username/password.

Hmm. The idea is that SASL EXTERNAL is just another way to authenticate,
and so it provides a username. I'm not sure a DN-to-username mapping is
the best way to proceed (suppose you're not storing users in Mnesia - do
all auth backends need to support such a mapping?)

James Casey

unread,
Jan 7, 2011, 9:06:54 AM1/7/11
to Simon MacMullen, rabbitmq...@lists.rabbitmq.com
On 7 January 2011 12:43, Simon MacMullen <si...@rabbitmq.com> wrote:
> On 06/01/11 16:46, Warren Smith wrote:
>>
>> Thanks for the quick response. I'll grab the latest source and see
>> what I can do with it. One thing - you say CN, not DN. Is this
>> customizable so that a DN can be used instead? We have enough users
>> and accept more than one CA so it becomes possible that 2 people have
>> the same CN (but different DNs). I don't expect to hit this for any
>> of the use cases I want to support in the next year or so, though.
>
> I have to admit I picked CNs for simplicity. The problem with DNs is that in
> general we assume that a username is a string, and can be matched as such.

Hi Simon,

what are the restrictions you have in usernames ? Does it have to be
a non-whitespace string ? Are there length restrictions ?

We're also in the situation where we have to accept 50-60 CAs (all
with different naming structures for the DN). We implemented
something for activemq (where the username is just any Java string
that can be compared against). Here we simply did standard URI
escaping to map into a username. E.g for my DN:

'/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=jamesc/CN=380618/CN=James Casey'

I get a username of
'%2FDC%3Dch%2FDC%3Dcern%2FOU%3DOrganic%20Units%2FOU%3DUsers%2FCN%3Djamesc%2FCN%3D380618%2FCN%3DJames%20Casey'
Since these are never entered directly by a user it's not such a big
problem that they are long. Of course if you've no problems with
spaces, etc in a username you could just use the DN directly as the
username.


> As soon as we start using DNs as usernames we have all sorts of problems
> with normalisation. I'm not a real X.509 expert, but it doesn't seem like
> there's a standard normalisation for DNs as strings. There are some
> conventions but they seem to get very hazy once you look at issues like
> escaping.

I guess the 'standard' is what 'openssl x509 -subject' gives back.
Note that the java tools work differently (elements in reversed order
with comma separation instead of / separators.

>
> I'll have a look at how this could be made to work though.
>
>> I've been using the Java client when trying out the SSL stuff so that
>> should be fine. Ultimately I'd like to use a Python client.
>>
>> I could handle storage of user details and authorization in a number
>> of ways without any problems. I could store an external mapping of DN
>> ->  RabbitMQ username and then let RabbitMQ do its normal
>> authorization against the username. I could store DNs and permissions
>> externally and have RabbitMQ do authorization call outs. I'm sure
>> there are other ways that would work fine, too. I do want different
>> users to have different permissions, but doing this on a per-vhost
>> level should be enough for me.
>>
>> I think the main thing is how much you all want to integrate client
>> DNs into the service vs a plugin. If you want it very integrated,
>> DN->username mappings could be stored in the Mnesia and managed by
>> rabbitmqctl. A user could then potentially have multiple DNs (we have
>> this situation sometimes) and be able to authenticate using a DN or a
>> username/password.
>
> Hmm. The idea is that SASL EXTERNAL is just another way to authenticate, and
> so it provides a username. I'm not sure a DN-to-username mapping is the best
> way to proceed (suppose you're not storing users in Mnesia - do all auth
> backends need to support such a mapping?)
>

I think this isn't such a good idea - it's tricky mapping multiple DNs
to the same 'user'. Often a user has multiple DNs since he wants to
distinguish himself this way (an DN for admin access vs a DN for
normal access). The issue I see here is what happens when a user gets
a new DN after an old one expired and the CA has a policy of
generating a new DN string (usually by appending a random number in a
CN field. Normally you then need admin tools to change a username,
keeping the same permissions.

One question here on the implementation - with an external provider
it's only for authentication, right? Authorization is still done by
storing permissions in Mnesia against users ?

cheers,

James.

Simon MacMullen

unread,
Jan 10, 2011, 5:35:03 AM1/10/11
to rabbitmq...@lists.rabbitmq.com
On 07/01/11 14:06, James Casey wrote:
> what are the restrictions you have in usernames ? Does it have to be
> a non-whitespace string ? Are there length restrictions ?

There are no limits to the string format, and I'm not aware of any
limits to the length.

> We're also in the situation where we have to accept 50-60 CAs (all
> with different naming structures for the DN). We implemented
> something for activemq (where the username is just any Java string
> that can be compared against). Here we simply did standard URI
> escaping to map into a username. E.g for my DN:
>
> '/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=jamesc/CN=380618/CN=James Casey'
>
> I get a username of
> '%2FDC%3Dch%2FDC%3Dcern%2FOU%3DOrganic%20Units%2FOU%3DUsers%2FCN%3Djamesc%2FCN%3D380618%2FCN%3DJames%20Casey'
> Since these are never entered directly by a user it's not such a big
> problem that they are long. Of course if you've no problems with
> spaces, etc in a username you could just use the DN directly as the
> username.

Sure, we could use the un-uri-escaped version.

>> As soon as we start using DNs as usernames we have all sorts of problems
>> with normalisation. I'm not a real X.509 expert, but it doesn't seem like
>> there's a standard normalisation for DNs as strings. There are some
>> conventions but they seem to get very hazy once you look at issues like
>> escaping.
> I guess the 'standard' is what 'openssl x509 -subject' gives back.
> Note that the java tools work differently (elements in reversed order
> with comma separation instead of / separators.

I think the Java format is RFC 4514, which is more of a standard. What
'openssl x509 -subject' gives back isn't documented anywhere that I can
see. However, even if we say "use RFC 4514", that doesn't define a
normailised representation. So we'd want to answer questions like:

* Since matching for some types of RDNs is case insensitive, should we
covert these to lower case, upper case or what?

* Since there are multiple ways to escape, which is canonical?

This is all predicated on the idea that people will want to be able to
predict the exact DN representation we use.

Hmm. The trouble with mapping multiple DNs to one user (from my point of
view!) is that it makes the EXTERNAL provider stateful, and (as
mentioned below) the state can't be assumed to reside in Mnesia.

I think I need to think about this more...

> One question here on the implementation - with an external provider
> it's only for authentication, right? Authorization is still done by
> storing permissions in Mnesia against users ?

If you want. The "user database" part has also become pluggable on
default, so permissions could be held in LDAP for example.

Matthias Radestock

unread,
Jan 10, 2011, 6:02:39 AM1/10/11
to Simon MacMullen, rabbitmq...@lists.rabbitmq.com
On 10/01/11 10:35, Simon MacMullen wrote:
> I think the Java format is RFC 4514, which is more of a standard. What
> 'openssl x509 -subject' gives back isn't documented anywhere that I can
> see.

The openssl "-nameopt RFC2253" option produces standards-compliant output.

See http://www.lshift.net/blog/2007/10/30/whats-in-a-distinguished-name
for a nice little primer on DNs and DN equivalence.

> So we'd want to answer questions like:
>
> * Since matching for some types of RDNs is case insensitive, should we
> covert these to lower case, upper case or what?
>
> * Since there are multiple ways to escape, which is canonical?

+ how to deal with multi-valued RDNs.


Matthias.

Reply all
Reply to author
Forward
0 new messages