2
votes

I set up RabbitMq v3.6.6 and I'm trying to achieve topic authentication after a successful client ssl authentication. The Client connecting is using mqtt.

The configuration so far

#/etc/rabbitmq/rabbitmq.config
[
  {rabbit, [
    {ssl_cert_login_from, common_name},
    {auth_mechanisms, ['EXTERNAL']},
    {tcp_listeners, [{"127.0.0.1", 5672}]},
    {ssl_listeners, [{"0.0.0.0", 5671}]},
    {ssl_options, [
      {cacertfile,          "/path_to/CA.crt"},
      {certfile,            "/path_to/certfile.crt"},
      {keyfile,             "/path_to/keyfile.key"},
      {verify, verify_peer},
      {fail_if_no_peer_cert, true}
      ]},
    {auth_backends, [rabbit_auth_backend_http]},
    {rabbitmq_auth_backend_http, [
      {http_method,          post },
      {user_path,            "https://127.0.0.1/auth/user"},
      {vhost_path,             "https://127.0.0.1/auth/vhost"},
      {resource_path, "https://127.0.0.1/auth/resource"},
      {topic_path, "https://127.0.0.1/auth/topic"}
      ]}
  ]},
  {rabbitmq_mqtt, [
                  {default_user,     <<"user">>},
                  {default_pass,     <<"pass">>},
                  {allow_anonymous,  true},
                  {vhost,            <<"/">>},
                  {exchange,         <<"amq.topic">>},
                  {subscription_ttl, 86400000},
                  {tcp_listeners,    [{"127.0.0.1", 1883}]},
                  {ssl_listeners,    [8883]},
                  {ssl_cert_login, true}
  ]}
].

I have installed the plugins rabbitmq_auth_backend_http (https://bintray.com/rabbitmq/community-plugins/download_file?file_path=rabbitmq_auth_backend_http-3.6.x-1b27d722.ez) and rabbitmq_topic_authorization(https://github.com/airboxlab/rabbitmq-topic-authorization/releases/download/v3.6.6/rabbitmq_topic_authorization.ez) and enabled them.

$ sudo rabbitmq-plugins list -e
[e*] amqp_client                  3.6.6
[e*] mochiweb                     2.13.1
[E*] rabbitmq_auth_backend_http   
[E*] rabbitmq_auth_mechanism_ssl  3.6.6
[E*] rabbitmq_management          3.6.6
[e*] rabbitmq_management_agent    3.6.6
[E*] rabbitmq_mqtt                3.6.6
[E*] rabbitmq_topic_authorization 
[e*] rabbitmq_web_dispatch        3.6.6
[e*] webmachine                   1.10.3

Why I configured like this

At https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl there is a note:

Note that the authenticated user will then be looked up in the configured authentication / authorisation backend(s) - this will be the mnesia-based user database by default, but could include other backends if so configured.

I did this by including and enabling plugins and configured auth_mechanisms to EXTERNAL. And auth_backends to rabbit_auth_backend_http

In the mqtt pluging documentation (https://www.rabbitmq.com/mqtt.html) there is a section Authentication with SSL client certificates, which is i want to achieve. I styled the important part in bold:

Authentication with SSL client certificates The MQTT adapter can authenticate SSL-based connections by extracting a name from the client's SSL certificate, without using a password.

For safety the server must be configured with the SSL options fail_if_no_peer_cert set to true and verify set to verify_peer, to force all SSL clients to have a verifiable client certificate.

To switch this feature on, set ssl_cert_login to true for the rabbitmq_mqtt application. For example: [ {rabbitmq_mqtt, [{ssl_cert_login, true}]} ].

To use the Common Name instead, add: {rabbit, [{ssl_cert_login_from, common_name}]} to your configuration.

Note that: The authenticated user must exist in the configured authentication / authorisation backend(s). Clients must not supply username and password.

The Problem

When I want to subscribe via sudo mosquitto_sub -h my-backend --cafile ca.crt --key client_keyfile.key --cert client_certfile.crt -t '#' -p 8883 I get the Error Connection Refused: bad user name or password.

The RabbitMq logs show the following output:

=ERROR REPORT==== 6-Mar-2017::15:01:51 ===
MQTT login failed for "my-hostname" auth_failure: Refused

At this point I expected RabbitMq to ask the backend for authentication instead of refusing right away. But there is no request at all to my backend-server. Furthermore, there shouldn't be an error complaining about name or password as im using client certifcates. I tested the backend-server with curl and i get allow response as expected. I could also verify the access in the nginx logs. So i guess the rabbitmq_auth_backend_http does not work properly or something else is misconfigured.

Has anyone an idea why the backend-server is not requested?

2

2 Answers

0
votes

=ERROR REPORT==== 6-Mar-2017::15:01:51 === MQTT login failed for "my-hostname" auth_failure: Refused

For above problem, you need to add user 'my-hostname' first: sudo rabbitmqctl add_user my-hostname my-hostname

Then set permission: sudo rabbitmqctl set_permissions -p / my-hostname ".*" ".*" ".*"

OR, you can add user through rabbitmq management GUI.

0
votes

According to the documentation here : https://www.rabbitmq.com/access-control.html#topic-authorisation the auth mechanism 'EXTERNAL' is not available.

The following aliases are available:

internal, ldap, http, amqp, dummy

However

External

is allowed in a plugin that you must include if you use it.