'Can't establish SSL connection to Kafka after upgrading to python 3.7
Code I have that successfully connects to Kafka with an SSL connection in Python 3.6.7 fails when using Python 3.7.3, with error message SSL: WRONG_VERSION_NUMBER
. I would not expect code working in Python 3.6 to fail when in Python 3.7. I would like to know how to resolve this error and connect to Kafka via SSL with Python 3.7.3.
I have tried several things to troubleshoot:
- Use a different package to connect to Kafka (connection with
faust
produces basically the same error) - Use a different cipher suite (and verify that setting them incompatibly changes the error to no cipher suites in common)
- Use a different version of the Kafka container (Confluent's Kafka 5.0.0 container with python 3.7 returns a
no cipher suites in common
error, 5.1.3 does not change the error) - Use a different protocol (enabling only TLS1.1 or 1.2 does not change the error, enabling 1.1 on Kafka and 1.2 on python or vice-versa causes a failure in name resoltion)
- Use a different version of openssl (this error was originally found using openssl 1.1.1c, and reproduced on 1.1.1a; for the current reproduction both containers use 1.1.1b)
Reproducing this problem could be fairly involved. It requires running Kafka and Zookeeper alongside two different, comparable version of Python, and the complete set of SSL credentials that each of those require. Thankfully, Docker can take care of much of this for us. I have created a Github Repo that contains a minimal set of files required to reproduce the error using only Docker desktop:
https://github.com/r-archer37/python-kafka-mre
The exact steps to reproduce the error are in the README. The short version is that there are two docker-compose files where the only difference is the version of the Jupyter-provided python-based docker image. Each runs a simple script that installs pykafka
and then attempts to connect to the Kafka container. The container with python 3.6 will successfully connect to Kafka (console output looks like DEBUG:pykafka.connection:Successfully connected to b'kafka':9092
) and the container with python 3.7 will fail to connect to Kafka (console output looks like INFO:pykafka.connection:Attempt 0: failed to connect to kafka:9092 ... INFO:pykafka.connection:[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1056)
).
Fixes, and suggestions of things to try, are both welcome!
Edit: The solution appears to be to use a kafka docker image by a different organization, not Confluent.
Solution 1:[1]
This is quite weird. Based on my investigation, I suspect the python upgrade is bringing to light an issue with Kafka, you might want to file a bug report with them. I was able to reproduce it working with the python container 3.6 and the failure with the 3.7.
I captured wireshark traces of both. With 3.6, the client sends the Client Hello
tls message, and the server responds with a valid Server Hello
, completing the handshake. With 3.7, when the client sends the Client Hello
message, the server responds with 0x00
repeated. 0x00 0x00
is not a valid TLS version, hence the WRONG_VERSION_NUMBER
that openssl reports.
When trying to create a TLS connection to kafka using the openssl client from either container, the server is also responding to the client handshake with just a series of 0x00
bytes.
Openssl client command I used: openssl s_client -connect kafka:9092 -cert mre.pem -CAfile mre.pem -key mre.pem -state -debug -tls1_2
Solution 2:[2]
This can be solved by generating the certificate key with keytool -keyalg RSA
Solution 3:[3]
If you’re still having that trouble, you can use this:
!allows usage of insecure ciphers!
ctx = ssl.SSLContext(<protocol>)
ctx.set_ciphers(‘ALL:@SECLEVEL=0’)
and pass ctx
to KafkaConsumer/KafkaProducer constructor as ssl_context
argument
Worked properly for me
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Devin Bjelland |
Solution 2 | Mushfirat Mohaimin |
Solution 3 | Damir Ismakov |