python-3.x - 升级到 python 3.7 后无法与 Kafka 建立 SSL 连接
问题描述
我在 Python 3.6.7 中通过 SSL 连接成功连接到 Kafka 的代码在使用 Python 3.7.3 时失败,并显示错误消息SSL: WRONG_VERSION_NUMBER
。我不希望在 Python 3.7 中运行的代码在 Python 3.7 中失败。我想知道如何解决此错误并使用 Python 3.7.3 通过 SSL 连接到 Kafka。
我尝试了几件事来解决问题:
- 使用不同的包连接到Kafka(连接
faust
产生基本相同的错误) - 使用不同的密码套件(并验证设置它们不兼容会将错误更改为没有共同的密码套件)
- 使用不同版本的Kafka容器(Confluent的Kafka 5.0.0容器用python 3.7返回
no cipher suites in common
错误,5.1.3不改错误) - 使用不同的协议(仅启用 TLS1.1 或 1.2 不会更改错误,在 Kafka 上启用 1.1 和在 python 上启用 1.2 或反之亦然会导致名称解析失败)
- 使用不同版本的 openssl(这个错误最初是使用 openssl 1.1.1c 发现的,并在 1.1.1a 上重现;对于当前的重现,两个容器都使用 1.1.1b)
重现这个问题可能是相当复杂的。它需要运行 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)
)。
欢迎修复和建议尝试!
编辑:解决方案似乎是使用不同组织的 kafka docker 映像,而不是 Confluent。
解决方案
这很奇怪。根据我的调查,我怀疑 python 升级暴露了 Kafka 的问题,您可能需要向他们提交错误报告。我能够使用 python 容器 3.6 和 3.7 的失败重现它。
我捕获了两者的wireshark痕迹。在 3.6 中,客户端发送Client Hello
tls 消息,服务器以 valid 响应Server Hello
,完成握手。在 3.7 中,当客户端发送Client Hello
消息时,服务器会0x00
重复响应。0x00 0x00
不是有效的 TLS 版本,因此WRONG_VERSION_NUMBER
openssl 报告。
当尝试使用来自任一容器的 openssl 客户端创建与 kafka 的 TLS 连接时,服务器也仅用一系列0x00
字节响应客户端握手。我使用的 Openssl 客户端命令:openssl s_client -connect kafka:9092 -cert mre.pem -CAfile mre.pem -key mre.pem -state -debug -tls1_2
推荐阅读
- mysql - 使用 MySQL/Presto 提取给定开始和结束模式的字符串
- cplex - CPLEX 求解器解决方案
- angular - 通过服务进行的通信不起作用Angular 8
- html - Flex Boxes 左对齐效果
- google-maps - 带有数字符号/井号/哈希标签的查询的 Google Maps Embed 调用失败
- kubernetes - 通过主机网络的 Istio 入口控制器(裸机)
- angular - Angular 6路由器导航不加载外部js文件
- python-3.x - SyntaxError: 关键字不能是表达式,这是意外错误吗?
- java - 如何将 unix 纪元微秒转换为 Java 时间戳
- javascript - 使用 Crypto-JS 在 Javascript/Typescript 中理解位长度和字符串位的问题