[rabbitmq-discuss] OpenLDAP-based auth with 'other_bind' option: no DN attribute?

Jan Kaliszewski jan.kaliszewski at nask.pl
Thu Dec 5 13:53:45 GMT 2013


Hello,

First, I'd like to express my gratitude to the authors of RabbitMQ for
producing such a useful piece of software!

Now, the problem I encountered (and the solution, or workaround, I
found)...

I am trying to configure RabbitMQ for passwordless (SSL client
certificate-based) and OpenLDAP-based authentication (with the
rabbitmq_auth_mechanism_ssl and rabbitmq_auth_backend_ldap plugins
enabled).

I carefully read the https://www.rabbitmq.com/ldap.html and
http://www.rabbitmq.com/ssl.html tutorials and created the following
rabbitmq.config:

[ 
  {rabbit, [
    {auth_backends, [rabbit_auth_backend_ldap]},
    {ssl_listeners, [{"127.0.0.1", 5671},
                     {"rabbit.example.com", 5671}
    ]},
    {ssl_options, [
      {cacertfile, "/etc/rabbitmq/certs/cacert-all.pem"},
      {certfile, "/etc/rabbitmq/certs/cert-server.pem"},
      {keyfile, "/etc/rabbitmq/certs/key-server.pem"},
      {verify, verify_peer},
      {fail_if_no_peer_cert, true}
    ]},
    {auth_mechanisms, ['EXTERNAL']},
    {ssl_cert_login_from, common_name}
  ]},
  {rabbitmq_auth_backend_ldap, [
    {servers,               ["localhost"]},
    {dn_lookup_attribute,   "myLoginName"},
    {dn_lookup_base,        "dc=example,dc=com"},
    {other_bind, {
      "myLoginName=rabbit-component,ou=it-components,dc=example,dc=com",
      "my-secret-password"}},
    {use_ssl,               true},
    {port,                  636},
    {log,                   true},
    {resource_access_query,
      {equals,
        {string, "${user_dn}"},
        {string, "myLoginName=bob,ou=our-users,dc=example,dc=com"}
      }
    }
  ]}
].


The expected sequence of events is as the following:

1. A client connects and shows its TLS/SSL client certificate and the
   RabbitMQ server verifies it (see `ssl_options` above).

2. RabbitMQ binds to OpenLDAP server using fixed rabbit-specific
   credentials (see `other_bind` above).

3. The common name (CN) from the certificate becomes the ${username}
   (see `ssl_cert_login_from` above). RabbitMQ searches in OpenLDAP
   for entry whose myLoginName is equal to the ${username} (see
   `dn_lookup_attribute` and `dn_lookup_base`).

4. The entry's becomes the ${user_dn}. Then RabbitMQ can check ACLs
   (`resource_access_query` etc.)...


Everything works fine, except point #4.  A fragment from logs:

 ** {{badmatch,undefined},
     [{rabbit_auth_backend_ldap,username_to_dn,3,[]},
      {rabbit_auth_backend_ldap,do_login,4,[]},
      {rabbit_auth_backend_ldap,with_ldap,3,[]},
      {rabbit_auth_backend_ldap,handle_call,3,[]},
      {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
      {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,227}]}]}


I investigated the problem and learned that the list of entries
returned from the search triggered in the following function is empty
(no entries are returned).

From rabbitmq-auth-backend-ldap/src/rabbit_auth_backend_ldap.erl:

 username_to_dn(Username, LDAP, Attr) ->
     Filled = fill_user_dn_pattern(Username),
     case eldap:search(LDAP,
                       [{base, env(dn_lookup_base)},
                        {filter, eldap:equalityMatch(Attr, Filled)},
                        {attributes, ["distinguishedName"]}]) of
         {ok, #eldap_search_result{entries = [#eldap_entry{attributes = A}]}} ->
             [DN] = pget("distinguishedName", A),
             DN;
         {ok, #eldap_search_result{entries = Entries}} ->
             rabbit_log:warning("Searching for DN for ~s, got back ~p~n",
                                [Filled, Entries]), Filled;
         {error, _} = E ->
             exit(E) end.


It seems that 'distinguishedName' (DN) is not treated (by OpenLDAP?) as
a real LDAP attribute.

When I patched that function by replacing the lines:

         {ok, #eldap_search_result{entries = [#eldap_entry{attributes = A}]}} ->
             [DN] = pget("distinguishedName", A),
with:
         {ok, #eldap_search_result{entries = [#eldap_entry{object_name = DN}]}} ->

...everything started working.


Am I missing something or is it the only way to make the stuff work, at
least with OpenLDAP 2.4.31?

I tried all that stuff both with RabbitMQ (+ plugins):
* in version 2.8.4, and
* in version 3.2.1.


Cheers,
*j

-- 
Jan Kaliszewski <jan.kaliszewski at nask.pl>


More information about the rabbitmq-discuss mailing list