Python stompest 无法通过 SSL 连接到 ActiveMQ

Posted

技术标签:

【中文标题】Python stompest 无法通过 SSL 连接到 ActiveMQ【英文标题】:Python stompest unable to connect to ActiveMQ over SSL 【发布时间】:2016-04-17 02:32:18 【问题描述】:

我正在尝试连接到使用 SSL 的 ActiveMQ 消息代理。我收到错误:

invalid uri: ssl://myserver.com:61613 [invalid broker(s): 'NoneType' object has no attribute 'groupdict']

来自 stompest 文档的示例代码:我只更改了服务器、用户和密码:

import time
from stompest.config import StompConfig
from stompest.sync import Stomp

while True:
    try:
        client = Stomp(StompConfig("ssl://myserver.com:61613", login = 'me', passcode = 'me', version = "1.2" ))
        client.connect(versions = ["1.2"], host = vhost, heartBeats = (0, 60000))   #CONNECT
        subscription = client.subscribe(destination, "ack": "client", "id": "0")  #SUBSCRIBE
        while True:
            frame = client.receiveFrame()
            try:
                print frame.body
                client.ack(frame)   #ACK
            except:
                print "Error: Can't handle message received, NACKing"
                client.nack(frame)  #NACK
    except Exception, e:
        # Reconnect on exception
        print "Exception handled, reconnecting...\nDetail:\n%s" % e
        try:
            client.disconnect()
        except:
            pass
        time.sleep(5)

我相信 Stompest 可以处理 SSL,但我在文档中找不到任何参考。

谢谢

【问题讨论】:

【参考方案1】:

您的StompConfig 必须提供一个SSLContext 并配置SSL 连接。具体应该如何看取决于您的设置的具体情况,所以让我们来看看其中的一些选项。

有关如何设置 ActiveMQ 以使用 SSL 的更多信息,请参阅 this Apache guide 和 this *** question,它们解决了相同的问题,但针对的是 stomp.py

无验证

如果您只需要一个快速而肮脏的连接,而无需验证代理或客户端——也就是说,一个容易受到来自活跃攻击者的 MITM 攻击的连接——那么您可以提供一个带有验证的SSLContext禁用:

import ssl
sslContext = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
# Let's at least disable some of the older SSL protocols
sslContext.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_SSLv3
sslContext.check_hostname = False
sslContext.verify_mode = ssl.CERT_NONE

有了这个,您只需将sslContext 提供给您的StompConfig

client = Stomp(StompConfig('ssl://myserver.com:61613', login='me', passcode='me', version='1.2', sslContext=sslContext))

代理证书验证

对此的第一个改进是验证服务器提供的证书。假设您使用的是自签名证书(而不是由证书颁发机构签名的证书),您可以直接向您的 SSLContext 提供证书:

首先,在代理上,从其密钥库中导出证书,我们假设通过使用 Java keytool 将其存储在名为 broker.ks 的文件中

keytool -exportcert -rfc -alias broker -keystore broker.ks -file broker.pem

现在,将 broker.pem 移动到 Python 客户端并更改 sslContext 配置,如下所示:

sslContext = ssl.create_default_context(cafile='broker.pem')
sslContext.check_hostname = True
sslContext.verify_mode = ssl.CERT_REQUIRED

客户端证书验证

ActiveMQ 服务器也可以设置为只允许来自具有预定义证书的客户端的连接。假设您在client.pem 中有一个 PEM 编码的客户端证书,已将私钥存储在 client.key 中(参见例如 this answer 的第一部分),并设置 ApacheMQ 以验证该证书(参见第三部分相同的答案),那么您需要做的就是让stompest 使用该对进行连接就是调用

sslContext.load_cert_chain('client.pem', 'client.key')

作为配置的一部分。

【讨论】:

以上是关于Python stompest 无法通过 SSL 连接到 ActiveMQ的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 通过 SSL 连接到远程 PostgreSQL 数据库

为啥 python SSL 模块无法验证 graph.facebook.com 证书?

Python 3 和 Slack 客户端:ssl.SSLCertVerificationError

Python 无法导入 ssl 模块

Python - [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1091)

python2和python3 在windows下公用 导致python2 pip无法使用 报ssl的错误