设置和验证 Python MySQL 连接中使用的 SSL/TLS 版本 [英] Set and verify SSL/TLS version used in Python MySQL connection

查看:152
本文介绍了设置和验证 Python MySQL 连接中使用的 SSL/TLS 版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 如何告诉 Python MySQL 连接器使用哪个 SSL/TLS 协议?特定(例如 TLS1.2)或最低要求.

  • 如何检查已建立的连接使用的是哪种协议?

我有一个使用 mysql-connector-python (8.0.18) 的应用程序.我连接这样的东西:

cnx = mysql.connector.connect(user='x', password='y', host='localhost', database='xyz')

通常这不会给我带来麻烦,但最近在网络托管提供商服务器上它停止工作.我现在得到的错误是:

mysql.connector.errors.InterfaceError: 2026 (HY000): SSL connection error: error:1408F10B:SSLroutines:ssl3_get_record:wrong version number

和(通过 Flask-SQLAlchemy 设置连接):

_mysql_connector.MySQLInterfaceError:SSL 连接错误:错误:140770FC:SSL 例程:SSL23_GET_SERVER_HELLO:未知协议

我可以确认的是,如果我改为执行 ssl_disabled=True,如下所示,它可以正确连接(但我假设没有 SSL/TLS):

cnx = mysql.connector.connect(user='x', password='y', host='localhost', database='xyz', ssl_disabled=True)

我无法更改提供者服务器,但他们说如果我指定要使用的特定版本,例如 TLS1.2,那么它应该可以正确连接.他们还提到使用 ssl.OP_NO_SSLv3 标志,但是这是 SSLContext 设置的一部分,我不确定如何将其应用于我的连接.

我看到在他们的 MySQL 实例(我无法编辑)上他们没有设置值:

  • SHOW VARIABLES LIKE 'tls_version'
  • SHOW STATUS LIKE 'Ssl_cipher'
  • SHOW STATUS LIKE 'Ssl_version'

解决方案

根据我最近的理解和来自 Andreas answer 的帮助我最终得到了以下连接:

cnx = mysql.connector.connect(user='u', password='p', host='localhost', database='db', ssl_ca='', ssl_version=ssl.PROTOCOL_TLSv1_2)

查看源代码,显然所有 kwargs 提供的也在 mysql.connector.constants.DEFAULT_CONFIGURATION 被接受.这包括文档,例如 ssl_versionssl_cipher.从 kwargs 到连接的映射似乎发生在 MySQLConnectionAbstract.connect.请注意,设置 ssl_version 可能还需要一些其他 kwargs.我需要同时提供 ssl_ca(可能会因 SHOW VARIABLES LIKE '%ssl%' 中的 MySQL 实例而异).

考虑到这一点,我有以下 MVCE 代码:

import mysql.connector导入 sslcnx = mysql.connector.connect(user='u', password='p', host='localhost', database='db', ssl_ca='', ssl_version=ssl.PROTOCOL_TLSv1_2)游标 = cnx.cursor()cursor.execute("选择 1")for (number,) 在光标中:打印('号码:',号码)打印('SSL 活动:',cnx._ssl_active)打印('连接SSL版本:',cnx._ssl.get(版本"))打印(套接字SSL版本:",cnx._socket.sock.ssl_version)游标.close()cnx.close()

对我来说输出:

编号:1SSL 活动:真连接 SSL 版本:_SSLMethod.PROTOCOL_TLSv1_2套接字 SSL 版本:_SSLMethod.PROTOCOL_TLSv1_2

如果我在没有指定 ssl_version 的情况下进行相同的连接,我会得到:

编号:1SSL 活动:真连接 SSL 版本:无套接字 SSL 版本:_SSLMethod.PROTOCOL_TLS

如果您将 ssl.PROTOCOL_TLSv1_2 替换为 ssl.PROTOCOL_SSLv23,它至少应该尝试不同的协议,但如果出现问题(例如不受支持),可能会失败.>

  • How can I tell the Python MySQL connector which SSL/TLS protocol to use? Either specific (e.g. TLS1.2) or minimum.

  • How can I check which protocol is used on an established connection?

I've got an app that uses mysql-connector-python (8.0.18). I connect something like this:

cnx = mysql.connector.connect(user='x', password='y', host='localhost', database='xyz')

Usually this gives me no trouble, but recently on a web hosting providers server it stopped working. The error I'm now getting is along the lines of:

mysql.connector.errors.InterfaceError: 2026 (HY000): SSL connection error: error:1408F10B:SSL routines:ssl3_get_record:wrong version number

And (connecting through Flask-SQLAlchemy setup):

_mysql_connector.MySQLInterfaceError: SSL connection error: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

What I can confirm is that if I instead do ssl_disabled=True, as below, it connects properly (but without SSL/TLS I assume):

cnx = mysql.connector.connect(user='x', password='y', host='localhost', database='xyz', ssl_disabled=True)

I cannot alter the providers server, but they say that if I specify a specific version to use, for example TLS1.2, then it should connect properly. They also mention using the ssl.OP_NO_SSLv3 flag, however that is part of the SSLContext setup which I'm unsure how to apply to my connection.

I see that on their MySQL instance (which I cannot edit) they have no value set for:

  • SHOW VARIABLES LIKE 'tls_version'
  • SHOW STATUS LIKE 'Ssl_cipher'
  • SHOW STATUS LIKE 'Ssl_version'

解决方案

From my recent understanding and help from Andreas answer I ended up with the following connect:

cnx = mysql.connector.connect(user='u', password='p', host='localhost', database='db', ssl_ca='', ssl_version=ssl.PROTOCOL_TLSv1_2)

Looking at the source, apparently all kwargs provided that are also in mysql.connector.constants.DEFAULT_CONFIGURATION are accepted. This includes several that are not included in the documentation, like ssl_version and ssl_cipher. This mapping from kwargs to the connection appears to happen in MySQLConnectionAbstract.connect. Note that setting ssl_version might require some other kwargs as well. I needed to provide ssl_ca along with it (might vary depending on what your MySQL instance has in SHOW VARIABLES LIKE '%ssl%').

With that in mind, I've got the following MVCE code:

import mysql.connector
import ssl

cnx = mysql.connector.connect(user='u', password='p', host='localhost', database='db', ssl_ca='', ssl_version=ssl.PROTOCOL_TLSv1_2)
cursor = cnx.cursor()
cursor.execute("SELECT 1")

for (number,) in cursor:
    print('Number:', number)
print('SSL active:', cnx._ssl_active)
print('Connection SSL version:', cnx._ssl.get("version"))
print("Socket SSL version:", cnx._socket.sock.ssl_version)

cursor.close()
cnx.close()

Which for me outputs:

Number: 1
SSL active: True
Connection SSL version: _SSLMethod.PROTOCOL_TLSv1_2
Socket SSL version: _SSLMethod.PROTOCOL_TLSv1_2

If I do the same connection without specifying ssl_version I get:

Number: 1
SSL active: True
Connection SSL version: None
Socket SSL version: _SSLMethod.PROTOCOL_TLS

If you replace ssl.PROTOCOL_TLSv1_2 with ssl.PROTOCOL_SSLv23 it should at least attempt a different protocol, but might fail if there are issues (e.g. unsupported).

这篇关于设置和验证 Python MySQL 连接中使用的 SSL/TLS 版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆