我尝试使用SSL证书将celery与rabbitMQ代理连接起来。
这是代码:
from celery import Celery
import ssl
broker_uri = 'amqp://user:pwd@server:5672/vhost'
certs_conf = {
"ca_certs": "/certs/serverca/cacert.pem",
"certfile": "/certs/client/rabbit-cert.pem",
"keyfile": "/certs/client/rabbit-key.pem",
"cert_reqs": ssl.CERT_REQUIRED
}
app = Celery('tasks', broker=broker_uri)
app.conf.update(BROKER_USE_SSL=certs_conf)
app.send_task('task.name', [{'a': 1}])
当我尝试执行此代码时,我得到以下异常:
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\kombu\utils\functional.py", line 36, in __call__
return self.__value__
AttributeError: 'ChannelPromise' object has no attribute '__value__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test_send_task.py", line 44, in <module>
app.send_task('task.name', [message])
File "C:\Python36\lib\site-packages\celery\app\base.py", line 737, in send_task
amqp.send_task_message(P, name, message, **options)
File "C:\Python36\lib\site-packages\celery\app\amqp.py", line 558, in send_task_message
**properties
File "C:\Python36\lib\site-packages\kombu\messaging.py", line 181, in publish
exchange_name, declare,
File "C:\Python36\lib\site-packages\kombu\connection.py", line 494, in _ensured
return fun(*args, **kwargs)
File "C:\Python36\lib\site-packages\kombu\messaging.py", line 187, in _publish
channel = self.channel
File "C:\Python36\lib\site-packages\kombu\messaging.py", line 209, in _get_channel
channel = self._channel = channel()
File "C:\Python36\lib\site-packages\kombu\utils\functional.py", line 38, in __call__
value = self.__value__ = self.__contract__()
File "C:\Python36\lib\site-packages\kombu\messaging.py", line 224, in <lambda>
channel = ChannelPromise(lambda: connection.default_channel)
File "C:\Python36\lib\site-packages\kombu\connection.py", line 819, in default_channel
self.ensure_connection()
File "C:\Python36\lib\site-packages\kombu\connection.py", line 405, in ensure_connection
callback)
File "C:\Python36\lib\site-packages\kombu\utils\functional.py", line 333, in retry_over_time
return fun(*args, **kwargs)
File "C:\Python36\lib\site-packages\kombu\connection.py", line 261, in connect
return self.connection
File "C:\Python36\lib\site-packages\kombu\connection.py", line 802, in connection
self._connection = self._establish_connection()
File "C:\Python36\lib\site-packages\kombu\connection.py", line 757, in _establish_connection
conn = self.transport.establish_connection()
File "C:\Python36\lib\site-packages\kombu\transport\pyamqp.py", line 130, in establish_connection
conn.connect()
File "C:\Python36\lib\site-packages\amqp\connection.py", line 288, in connect
self.drain_events(timeout=self.connect_timeout)
File "C:\Python36\lib\site-packages\amqp\connection.py", line 471, in drain_events
while not self.blocking_read(timeout):
File "C:\Python36\lib\site-packages\amqp\connection.py", line 477, in blocking_read
return self.on_inbound_frame(frame)
File "C:\Python36\lib\site-packages\amqp\method_framing.py", line 55, in on_frame
callback(channel, method_sig, buf, None)
File "C:\Python36\lib\site-packages\amqp\connection.py", line 481, in on_inbound_method
method_sig, payload, content,
File "C:\Python36\lib\site-packages\amqp\abstract_channel.py", line 128, in dispatch_method
listener(*args)
File "C:\Python36\lib\site-packages\amqp\connection.py", line 368, in _on_start
b", ".join(self.mechanisms).decode()))
amqp.exceptions.ConnectionError: Couldn't find appropriate auth mechanism (can offer: AMQPLAIN, PLAIN; available: EXTERNAL)
在没有ssl配置的情况下执行相同的代码效果很好。我错过了什么?
我可以使用配置了SSL的pika向代理发送消息,但我无法正确配置Celery以使用SSL向同一代理发送消息。
提前致谢。
答案 0 :(得分:0)
尝试使用以下设置:
broker_use_ssl=True
您还可以使用以 amqps:// ...
开头的代理网址答案 1 :(得分:0)
您需要启用此插件:https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl 并将以下配置添加到/etc/rabbitmq/rabbitmq.conf
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = EXTERNAL
如果仅需要ssl连接,则仅添加EXTERNAL。
答案 2 :(得分:0)
如果您的服务器提供了EXTERNAL身份验证机制,则它可能已经支持SSL客户端身份验证。但是对于Celery客户端,您需要一个附加的配置选项才能使用EXTERNAL(即SSL)身份验证:
app.conf.broker_login_method = 'EXTERNAL'
为完整起见,有效的celery配置代码段如下所示:
...
import ssl
app = Celery("some_name")
app.conf.broker_url = 'amqps://rabbitmq.example.com:5671/vhostname'
app.conf.broker_use_ssl = {
'keyfile': r'C:\path\to\private\box1-nopass.key.pem',
'certfile': r'C:\path\to\certs\box1.cert.pem',
'ca_certs': r'C:\path\to\ca-chain.cert.pem',
'cert_reqs': ssl.CERT_REQUIRED
}
app.conf.broker_login_method = 'EXTERNAL'
...
请注意,broker_url
中没有用户名:密码,因为用户名由客户端证书的属性决定(并且该用户必须预先存在于RabbitMQ服务器上,并配置为“无密码”),并且默认的SSL端口是5671(不是5672)。