升级到 python 3.7 后无法与 Kafka 建立 SSL 连接

Can't establish SSL connection to Kafka after upgrading to python 3.7

我在 Python 3.6.7 中使用 SSL 连接成功连接到 Kafka 的代码在使用 Python 3.7.3 时失败,并显示错误消息 SSL: WRONG_VERSION_NUMBER。我不希望在 Python 3.6 中工作的代码在 Python 3.7 中失败。我想知道如何解决此错误并使用 Python 3.7.3.

通过 SSL 连接到 Kafka

我尝试了几种方法来解决问题:

重现这个问题可能相当复杂。它需要 运行 Kafka 和 Zookeeper 以及两个不同的、可比较的 Python 版本,以及每个版本都需要的完整 SSL 凭据集。值得庆幸的是,Docker 可以为我们解决大部分问题。我创建了一个 Github 存储库,其中包含仅使用 Docker 桌面重现错误所需的最少文件集:

https://github.com/r-archer37/python-kafka-mre

重现错误的具体步骤在自述文件中。简短的版本是有两个 docker-compose 文件,唯一的区别是 Jupyter 提供的基于 python 的 docker 图像的版本。每个都运行一个安装 pykafka 的简单脚本,然后尝试连接到 Kafka 容器。 python 3.6 的容器将成功连接到 Kafka(控制台输出看起来像 DEBUG:pykafka.connection:Successfully connected to b'kafka':9092)而具有 python 3.7 的容器将无法连接到 Kafka(控制台输出看起来像 INFO:pykafka.connection:Attempt 0: failed to connect to kafka:9092 ... INFO:pykafka.connection:[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1056)).

欢迎修复和建议尝试!

编辑:解决方案似乎是使用不同组织而非 Confluent 的 kafka docker 图像。

这很奇怪。根据我的调查,我怀疑 python 升级暴露了 Kafka 的问题,您可能需要向他们提交错误报告。我能够使用 python 容器 3.6 重现它,而使用 3.7.

失败

我捕获了两者的 wireshark 痕迹。使用 3.6,客户端发送 Client Hello tls 消息,服务器以有效的 Server Hello 响应,完成握手。使用 3.7,当客户端发送 Client Hello 消息时,服务器会重复响应 0x000x00 0x00 不是有效的 TLS 版本,因此 openssl 报告的 WRONG_VERSION_NUMBER

当尝试使用来自任一容器的 openssl 客户端创建与 kafka 的 TLS 连接时,服务器也仅使用一系列 0x00 字节响应客户端握手。 我使用的Openssl客户端命令:openssl s_client -connect kafka:9092 -cert mre.pem -CAfile mre.pem -key mre.pem -state -debug -tls1_2

这可以通过使用 keytool -keyalg RSA

生成证书密钥来解决

如果你仍然遇到那个问题,你可以使用这个:

!允许使用不安全的密码!

ctx = ssl.SSLContext(<protocol>)
ctx.set_ciphers(‘ALL:@SECLEVEL=0’)

并将ctx作为ssl_context参数传递给KafkaConsumer/KafkaProducer构造函数

对我来说工作正常