[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