【问题标题】:Authenticating rabbitmq using ExternalCredentials使用 ExternalCredentials 对 rabbitmq 进行身份验证
【发布时间】:2019-12-26 22:58:06
【问题描述】:

我有一个 rabbitmq 服务器,并使用 pika 库和 Python 来生成/使用消息。出于开发目的,我只是在使用

credentials = pika.PlainCredentials(<user-name>, <password>)

我想将其更改为使用 pika.ExternalCredentials 或 TLS。

我已经设置了我的 rabbitmq 服务器来监听端口 5671 上的 TLS,并且已经正确配置了它。我可以从本地主机与rabbitmq 通信,但是当我尝试从本地主机外部与它通信时,它不喜欢那样。我感觉我的“凭据”是基于 rabbitmq 中的“访客”用户。

rabbitmq.config

%% -*- mode: erlang -*-

[
 {rabbit,
  [
   {ssl_listeners, [5671]},
   {auth_mechanisms, ['PLAIN', 'AMQPLAIN', 'EXTERNAL']},
   {ssl_options, [{cacertfile,"~/tls-gen/basic/result/ca_certificate.pem"},
                  {certfile,"~/tls-gen/basic/result/server_certificate.pem"},
                  {keyfile,"~/tls-gen/basic/result/server_key.pem"},
                  {verify,verify_none},
                  {ssl_cert_login_from, common_name},
                  {fail_if_no_peer_cert,false}]}
   
  ]}
].

我可以确认这是可行的,因为在我的 rabbitmq 日志中我看到:

2019-08-21 15:34:47.663 [info] <0.442.0> started TLS (SSL) listener on [::]:5671

服务器端的一切似乎都设置好了,我还生成了证书和所需的所有 .pem 文件。

test_rabbitmq.py

import pika
import ssl
from pika.credentials import ExternalCredentials

context = ssl.create_default_context(cafile="~/tls-gen/basic/result/ca_certificate.pem")
context.load_cert_chain("~/tls-gen/basic/result/client_certificate.pem",
                            "~/tls-gen/basic/result/client_key.pem")
ssl_options = pika.SSLOptions(context, "10.154.0.27")
params = pika.ConnectionParameters(port=5671,ssl_options=ssl_options, credentials = ExternalCredentials())
connection = pika.BlockingConnection(params)
channel = connection.channel()

当我在本地运行脚本时

(<Basic.GetOk(['delivery_tag=1', 'exchange=', 'message_count=0', 'redelivered=False', 'routing_key=foobar'])>, <BasicProperties>, b'Hello, world!')

当我从另一个实例运行脚本时

Traceback (most recent call last):
  File "pbbarcode.py", line 200, in <module>
    main()
  File "pbbarcode.py", line 187, in main
    connection = pika.BlockingConnection(params)
  File "/usr/local/lib/python3.7/site-packages/pika/adapters/blocking_connection.py", line 359, in __init__
    self._impl = self._create_connection(parameters, _impl_class)
  File "/usr/local/lib/python3.7/site-packages/pika/adapters/blocking_connection.py", line 450, in _create_connection
    raise self._reap_last_connection_workflow_error(error)
pika.exceptions.AMQPConnectionError

当我在本地运行脚本并删除来宾用户时

Traceback (most recent call last):
  File "test_mq.py", line 12, in <module>
    with pika.BlockingConnection(conn_params) as conn:
  File "/home/daudn/.local/lib/python3.7/site-packages/pika/adapters/blocking_connection.py", line 359, in __init__
    self._impl = self._create_connection(parameters, _impl_class)
  File "/home/daudn/.local/lib/python3.7/site-packages/pika/adapters/blocking_connection.py", line 450, in _create_connection
    raise self._reap_last_connection_workflow_error(error)
pika.exceptions.ProbableAuthenticationError: ConnectionClosedByBroker: (403) 'ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.'

似乎 SSL 配置了用户“guest”,并且 rabbitmq 不允许连接到 localhost 之外的来宾。如何将 SSL 用于其他用户? 当我删除来宾用户时,rabbitmq 日志是这样写的:

2019-08-22 10:14:40.054 [info] <0.735.0> accepting AMQP connection <0.735.0> (127.0.0.1:59192 -> 127.0.0.1:5671)
2019-08-22 10:14:40.063 [error] <0.735.0> Error on AMQP connection <0.735.0> (127.0.0.1:59192 -> 127.0.0.1:5671, state: starting):
PLAIN login refused: user 'guest' - invalid credentials
2019-08-22 10:14:40.063 [warning] <0.735.0> closing AMQP connection <0.735.0> (127.0.0.1:59192 -> 127.0.0.1:5671):
client unexpectedly closed TCP connection
2019-08-22 10:15:12.613 [info] <0.743.0> Creating user 'guest'
2019-08-22 10:15:28.370 [info] <0.750.0> Setting user tags for user 'guest' to [administrator]
2019-08-22 10:15:51.352 [info] <0.768.0> Setting permissions for 'guest' in '/' to '.*', '.*', '.*'
2019-08-22 10:15:54.237 [info] <0.774.0> accepting AMQP connection <0.774.0> (127.0.0.1:59202 -> 127.0.0.1:5671)
2019-08-22 10:15:54.243 [info] <0.774.0> connection <0.774.0> (127.0.0.1:59202 -> 127.0.0.1:5671): user 'guest' authenticated and granted access to vhost '/'

这也明明说明SSL还在用用户名和密码连接rabbitmq?帮助!

参考资料:

tls_official_example

pika_official_tls_docs

added_authentication_external

【问题讨论】:

    标签: python ssl rabbitmq tls1.2 pika


    【解决方案1】:

    您必须启用 rabbitmq-auth-mechanism-ssl 插件,我认为您缺少该部分。

    要启用插件,请执行以下操作(显示 Windows 设置示例)

    rabbitmq-plugins.bat enable rabbitmq_auth_mechanism_ssl
    

    【讨论】:

    • 我已经编辑了我的问题,问题是 SSL 配置了默认的 'guest' 用户,所以我无法从本地环境之外访问它。
    • 当从远程系统登录的用户guest被拒绝访问时,你能分享rabbitmq日志吗?
    • 因为直接抛出pika.exceptions.AMQPConnectionError,所以日志中什么也没有出现
    • ....如果您查看我的代码“test_rabbitmq.py”,我没有指定用户/密码,因为我试图通过 SSL 访问它?在本地主机上运行类似代码时,日志显示:2019-08-22 10:14:40.063 [error] &lt;0.735.0&gt; Error on AMQP connection &lt;0.735.0&gt; (127.0.0.1:59192 -&gt; 127.0.0.1:5671, state: starting): PLAIN login refused: user 'guest' - invalid credentials
    • 嗯.. 你能像这样{auth_mechanisms, ['EXTERNAL','PLAIN', 'AMQPLAIN'},
    【解决方案2】:

    将这里留下以供将来参考

    ssl_options = pika.SSLOptions(context, "rabbitmq-node-name")
    params = pika.ConnectionParameters(host="rabbitmq-node-name",port=5671,ssl_options=ssl_options, credentials = ExternalCredentials())
    

    令人困惑的是,我认为在执行 SSLOptions(context, "rabbitmq-node-name") 时,我认为我已经在此处提供了主机,而不必在 ConnectionParameters() 的 args 中再次提供它。但事实证明这是不正确的,如果没有提供主机,则默认为 localhost。这就是脚本在本地而不是在本地网络之外运行的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-31
      • 2019-02-24
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多