Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

python - Authenticating rabbitmq using ExternalCredentials

I have a rabbitmq server and use the pika library with Python to produce/consume messages. For development purposes, I was simply using

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

I want to change that to use pika.ExternalCredentials or TLS.

I have set up my rabbitmq server to listen for TLS on port 5671, and have configured it correctly. I am able to communicate with rabbitmq from localhost, but the moment I try to communicate with it from outside the localhost it doesn't like that. I have a feeling my "credentials" are based on the "guest" user in 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}]}
   
  ]}
].

I can confirm this works, since in my logs for rabbitmq I see:

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

Server-side everything seems to be set up, I have also generated certificates and all the .pem files required.

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()

When I run the script locally

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

When I run the script from another instance

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

When I run the script locally, and delete the guest user

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.'

It seems like SSL is configured with the user "guest" and rabbitmq doesn't allow connections to guest outside of localhost. How can I use SSL with a different user? When I delete the guest user, this is what the rabbitmq log says:

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 '/'

This also clearly means the SSL is still using the username and password to connect to rabbitmq? HELP!

References:

tls_official_example

pika_official_tls_docs

added_authentication_external

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You will have to enable the rabbitmq-auth-mechanism-ssl plugin , i think you are missing that part.

To enable the plugin do the following ( showing the example for a Windows setup)

rabbitmq-plugins.bat enable rabbitmq_auth_mechanism_ssl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...