升级到 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(与
faust
的连接产生基本相同的错误)
- 使用不同的密码套件(并验证将它们设置为不兼容会将错误更改为没有共同的密码套件)
- 使用不同版本的Kafka容器(Confluent的Kafka 5.0.0容器有python3.7returns一个
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)
).
欢迎修复和建议尝试!
编辑:解决方案似乎是使用不同组织而非 Confluent 的 kafka docker 图像。
这很奇怪。根据我的调查,我怀疑 python 升级暴露了 Kafka 的问题,您可能需要向他们提交错误报告。我能够使用 python 容器 3.6 重现它,而使用 3.7.
失败
我捕获了两者的 wireshark 痕迹。使用 3.6,客户端发送 Client Hello
tls 消息,服务器以有效的 Server Hello
响应,完成握手。使用 3.7,当客户端发送 Client Hello
消息时,服务器会重复响应 0x00
。 0x00 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构造函数
对我来说工作正常
我在 Python 3.6.7 中使用 SSL 连接成功连接到 Kafka 的代码在使用 Python 3.7.3 时失败,并显示错误消息 SSL: WRONG_VERSION_NUMBER
。我不希望在 Python 3.6 中工作的代码在 Python 3.7 中失败。我想知道如何解决此错误并使用 Python 3.7.3.
我尝试了几种方法来解决问题:
- 使用不同的包连接到 Kafka(与
faust
的连接产生基本相同的错误) - 使用不同的密码套件(并验证将它们设置为不兼容会将错误更改为没有共同的密码套件)
- 使用不同版本的Kafka容器(Confluent的Kafka 5.0.0容器有python3.7returns一个
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)
).
欢迎修复和建议尝试!
编辑:解决方案似乎是使用不同组织而非 Confluent 的 kafka docker 图像。
这很奇怪。根据我的调查,我怀疑 python 升级暴露了 Kafka 的问题,您可能需要向他们提交错误报告。我能够使用 python 容器 3.6 重现它,而使用 3.7.
失败我捕获了两者的 wireshark 痕迹。使用 3.6,客户端发送 Client Hello
tls 消息,服务器以有效的 Server Hello
响应,完成握手。使用 3.7,当客户端发送 Client Hello
消息时,服务器会重复响应 0x00
。 0x00 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构造函数
对我来说工作正常