aio-pika
aio-pika copied to clipboard
Unable to use tls protected connection
Hi all, I am trying to connect to rabbitmq server with aio_pika
and use tls to protect the connection, but I am encountering and ConnectionResetError
with no other explanation. I was wondering if anyone can help me with some error fix tips.
I ubuntu system and created my rabbitmq service using docker
. The certificate generation and image configuration files are as follows:
Dockerfile:
FROM rabbitmq:3.13-management
# copy rabbitmq.config to container
COPY rabbitmq.config /etc/rabbitmq/rabbitmq.config
# copy tls certificates and key to container
COPY rabbitmq-server-cert.pem /etc/rabbitmq/certs/rabbitmq-server-cert.pem
COPY rabbitmq-server-key.pem /etc/rabbitmq/certs/rabbitmq-server-key.pem
COPY ca-certificate.pem /etc/rabbitmq/certs/ca-certificate.pem
# expose ports for RabbitMQ server
EXPOSE 5671 5672 15672
# Start RabbitMQ server
CMD ["rabbitmq-server"]
create_image.sh
# 1. Generate or obtain a CA certificate (ca_certificate.pem)
openssl genpkey -algorithm RSA -out ca-key.pem -pkeyopt rsa_keygen_bits:2048
openssl req -x509 -new -key ca-key.pem -days 3650 -out ca-certificate.pem -subj "/CN=MyCA"
# 2. Generate a RabbitMQ Server Private Key and Certificate Signing Request (CSR)
openssl genpkey -algorithm RSA -out rabbitmq-server-key.pem -pkeyopt rsa_keygen_bits:2048
openssl req -new -key rabbitmq-server-key.pem -out rabbitmq-server-csr.pem -subj "/CN=rabbitmq-server"
# 3. Sign the RabbitMQ Server Certificate with a CA Certificate
openssl x509 -req -in rabbitmq-server-csr.pem -CA ca-certificate.pem -CAkey ca-key.pem -CAcreateserial -out rabbitmq-server-cert.pem -days 3650
# Remove unnecessary files
rm ca-key.pem && rm rabbitmq-server-csr.pem
cat <<EOF > rabbitmq.config
[
{rabbit, [
{tcp_listeners, [{"0.0.0.0", 5672}]},
{ssl_listeners, [{"0.0.0.0", 5671}]},
{ssl_options, [{cacertfile, "/etc/rabbitmq/certs/ca-certificate.pem"},
{certfile, "/etc/rabbitmq/certs/rabbitmq-server-cert.pem"},
{keyfile, "/etc/rabbitmq/certs/rabbitmq-server-key.pem"},
{verify, verify_peer},
{fail_if_no_peer_cert, true}]}
]}
].
EOF
docker build -t my-rabbitmq .
docker run -d --name my-rabbitmq -p 5672:5672 -p 5671:5671 -p 15672:15672 \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=123456 \
my-rabbitmq
As with the image booting smoothly, I currently have normal access to the control panel via port 15672 and normal activity via port 5672.
Executing rabbitmq-diagnostics listeners
command yields the following result, which according to my understanding means that port 5671 has been successfully loaded and protected by tls.
root@82029c15869e:/# rabbitmq-diagnostics listeners
Asking node rabbit@82029c15869e to report its protocol listeners ...
Interface: [::], port: 15672, protocol: http, purpose: HTTP API
Interface: [::], port: 15692, protocol: http/prometheus, purpose: Prometheus exporter API over HTTP
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: 0.0.0.0, port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: 0.0.0.0, port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS
Use nc localhost 5671
command to check that port 5671 is listening for connections.
On this basis, I would like to make a basic connection test using aio_pika
# -*- coding: utf-8 -*-
# File name: client.py
import asyncio
import aio_pika
from aio_pika.abc import SSLOptions
import ssl
async def main():
connection = await aio_pika.connect(
host='localhost',
port=5671,
login='admin',
password='123456',
ssl=True,
ssl_options=SSLOptions(
cafile="ca-certificate.pem",
certfile="rabbitmq-server-cert.pem",
keyfile="rabbitmq-server-key.pem",
no_verify_ssl=ssl.CERT_REQUIRED,
),
client_properties={"connection_name": "aio-pika external credentials"},
)
print(connection)
await connection.close()
asyncio.run(main())
Got the following trace log:
Traceback (most recent call last):
File "C:\Program Files\Python\Python310\lib\site-packages\aiormq\connection.py", line 455, in connect
reader, writer = await asyncio.open_connection(
File "C:\Program Files\Python\Python310\lib\asyncio\streams.py", line 48, in open_connection
transport, _ = await loop.create_connection(
File "C:\Program Files\Python\Python310\lib\asyncio\base_events.py", line 1103, in create_connection
transport, protocol = await self._create_connection_transport(
File "C:\Program Files\Python\Python310\lib\asyncio\base_events.py", line 1133, in _create_connection_transport
await waiter
ConnectionResetError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\USER\Downloads\Tesging\test2.py", line 44, in <module>
asyncio.run(main())
File "C:\Program Files\Python\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Program Files\Python\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
return future.result()
File "C:\Users\USER\Downloads\Tesging\test2.py", line 24, in main
connection = await aio_pika.connect(
File "C:\Program Files\Python\Python310\lib\site-packages\aio_pika\connection.py", line 388, in connect
await connection.connect(timeout=timeout)
File "C:\Program Files\Python\Python310\lib\site-packages\aio_pika\connection.py", line 118, in connect
self.transport = await UnderlayConnection.connect(
File "C:\Program Files\Python\Python310\lib\site-packages\aio_pika\abc.py", line 671, in connect
connection = await cls.make_connection(
File "C:\Program Files\Python\Python310\lib\site-packages\aio_pika\abc.py", line 659, in make_connection
connection: aiormq.abc.AbstractConnection = await asyncio.wait_for(
File "C:\Program Files\Python\Python310\lib\asyncio\tasks.py", line 408, in wait_for
return await fut
File "C:\Program Files\Python\Python310\lib\site-packages\aiormq\connection.py", line 918, in connect
await connection.connect(client_properties or {})
File "C:\Program Files\Python\Python310\lib\site-packages\aiormq\base.py", line 164, in wrap
return await self.create_task(func(self, *args, **kwargs))
File "C:\Program Files\Python\Python310\lib\site-packages\aiormq\abc.py", line 44, in __inner
return await self.task
File "C:\Program Files\Python\Python310\lib\site-packages\aiormq\connection.py", line 462, in connect
raise AMQPConnectionError(*e.args) from e
aiormq.exceptions.AMQPConnectionError
[Finished in 3.5s]
I tried to load the tls certificate using the ssl
module that comes with python stl, and it didn't report an error, so maybe that means there's nothing wrong with the connection part of the code. Does anyone know the cause of the problem?
===
Upd:
I tried to follow the checking procedure in the rabbitmq documentation to test the availability of the certificate using the openssl self-composition loop, and got a result that showed that the certificate itself works fine.
server side command:
openssl s_server -accept 8443 \
-cert rabbitmq-server-cert.pem -key rabbitmq-server-key.pem -CAfile ca-certificate.pem
client side command:
openssl s_client -connect localhost:8443 \
-cert rabbitmq-server-cert.pem -key rabbitmq-server-key.pem -CAfile ca-certificate.pem \
-verify 8 -verify_hostname rabbitmq-server
stdout:
Using default temp DH parameters
ACCEPT
-----BEGIN SSL SESSION PARAMETERS-----
MIGDAgEBAgIDBAQCEwIEIMIT2QGuxJ1lZ3G02EYPlfGv5WF1wG+NcxixxX8E9V7E
BDCeBYDvjBp/FSh5KQCDngt3KQ2+ecCN73jtn2xMgGaSnoMF4DLzgmrdJl1X84z2
3BmhBgIEZluW+KIEAgIcIKQGBAQBAAAArgcCBQDjfD8cswMCAR0=
-----END SSL SESSION PARAMETERS-----
Shared ciphers:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA
Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Supported groups: x25519:secp256r1:x448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
Shared groups: x25519:secp256r1:x448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
CIPHER is TLS_AES_256_GCM_SHA384
Secure Renegotiation IS supported
Start Time: 1717278872
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
=== Upd:
Trying to connect directly to port 5671 using s_client. Observing the information returned from the port, the connection seems to be established successfully. However, the connection fails immediately and does not reflect in the logs that a connection was attempted, as described in the official documentation.
client stdout
root@user-ubuntu:~/RabiBridge/config# openssl s_client -connect localhost:5671 -cert rabbitmq-server-cert.pem -key rabbitmq-server-key.pem -CAfile ca-certificate.pem
CONNECTED(00000003)
405726C2087D0000:error:0A000126:SSL routines:ssl3_read_n:unexpected eof while reading:../ssl/record/rec_layer_s3.c:308:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 300 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---