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?