ssl客户端认证后如何通过rabbitmq结合mqtt和后端进行认证实现主题认证?

Posted

技术标签:

【中文标题】ssl客户端认证后如何通过rabbitmq结合mqtt和后端进行认证实现主题认证?【英文标题】:How to achieve topic authentication after ssl client authentication with rabbitmq in conjunction with mqtt and a backend for authentification? 【发布时间】:2017-03-06 15:03:39 【问题描述】:

我设置了 RabbitMq v3.6.6,并尝试在客户端 ssl 身份验证成功后实现主题身份验证。正在连接的客户端正在使用 mqtt。

目前的配置

#/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
  ]
].

我已经安装了插件rabbitmq_auth_backend_http (https://bintray.com/rabbitmq/community-plugins/download_file?file_path=rabbitmq_auth_backend_http-3.6.x-1b27d722.ez) 和rabbitmq_topic_authorization(https://github.com/airboxlab/rabbitmq-topic-authorization/releases/download/v3.6.6/rabbitmq_topic_authorization.ez) 并启用了它们。

$ 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

为什么我这样配置

https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl 有一条说明:

请注意,经过身份验证的用户将在配置的身份验证/授权后端中查找 - 默认情况下,这将是基于 mnesia 的用户数据库,但如果这样配置,可能包括其他后端。

我通过包含和启用插件并将auth_mechanisms 配置为EXTERNAL 来做到这一点。和auth_backendsrabbit_auth_backend_http

在 mqtt 插件文档 (https://www.rabbitmq.com/mqtt.html) 中有一个部分使用 SSL 客户端证书进行身份验证,这是我想要实现的。我用粗体设计了重要部分:

使用 SSL 客户端证书进行身份验证 MQTT 适配器可以通过从客户端的 SSL 证书中提取名称来验证基于 SSL 的连接,而无需使用密码。

为安全起见,服务器必须配置 SSL 选项 fail_if_no_peer_cert 设置为 true,verify 设置为 verify_peer,以强制所有 SSL 客户端具有可验证的客户端证书。

要打开此功能,将 rabbitmq_mqtt 应用程序的 ssl_cert_login 设置为 true。例如: [ rabbitmq_mqtt, [ssl_cert_login, true] ].

要改用通用名称,请添加: rabbit, [ssl_cert_login_from, common_name] 到你的配置。

请注意: 经过身份验证的用户必须存在于配置的身份验证/授权后端。 客户不得提供用户名和密码。

问题

当我想通过sudo mosquitto_sub -h my-backend --cafile ca.crt --key client_keyfile.key --cert client_certfile.crt -t '#' -p 8883订阅时 我收到错误Connection Refused: bad user name or password.

RabbitMq 日志显示以下输出:

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

此时我希望 RabbitMq 请求后端进行身份验证,而不是立即拒绝。但是我的后端服务器根本没有请求。此外,当我使用客户端证书时,不应该出现抱怨名称或密码的错误。 我用 curl 测试了后端服务器,我得到了allow 预期的响应。我还可以验证 nginx 日志中的访问权限。所以我猜rabbitmq_auth_backend_http 不能正常工作或其他配置错误。

有人知道为什么不请求后端服务器吗?

【问题讨论】:

【参考方案1】:

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

对于上述问题,您需要先添加用户'my-hostname': sudo rabbitmqctl add_user my-hostname my-hostname

然后设置权限: sudo rabbitmqctl set_permissions -p / my-hostname ".*" ".*" ".*"

或者,您可以通过rabbitmq管理GUI添加用户。

【讨论】:

【参考方案2】:

根据此处的文档:https://www.rabbitmq.com/access-control.html#topic-authorisation 身份验证机制“EXTERNAL”不可用。

以下别名可用:

内部、ldap、http、amqp、虚拟

然而

外部

允许在使用时必须包含的插件中。

【讨论】:

以上是关于ssl客户端认证后如何通过rabbitmq结合mqtt和后端进行认证实现主题认证?的主要内容,如果未能解决你的问题,请参考以下文章

Bluemix结合RabbitMq实现消息发送与接收实例

C++ 客户端通过 SSL 连接到 IBM MQ

5-2 客户端操作MQ集群

RabbitMQ

Kafka创建SSL证书

如何集成rabbit mq客户端库