web-dev-qa-db-ja.com

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')

通常、これで問題は発生しませんが、最近、Webホスティングプロバイダーサーバーで機能しなくなりました。私が今得ているエラーは次の線に沿っています:

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

そして(Flask-SQLAlchemyセットアップを介して接続):

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

私が確認できるのは、代わりに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'

私の最近の理解と アンドレアスの答え からの助けから私は次の接続に行き着きました:

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

ソースを見ると、 mysql.connector.constants.DEFAULT_CONFIGURATION にあるすべてのkwargsが受け入れられているようです。これには、ssl_versionssl_cipherなど、 ドキュメント に含まれていないものがいくつか含まれます。 kwargsから接続へのこのマッピングは、 MySQLConnectionAbstract.connect で発生するようです。 ssl_versionを設定すると、他のkwargも必要になる場合があることに注意してください。 ssl_caを一緒に提供する必要がありました(MySQLインスタンスのSHOW VARIABLES LIKE '%ssl%'の内容によって異なる場合があります)。

それを念頭に置いて、私は次のMVCEコードを持っています:

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()

私にとってどれが出力しますか:

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

ssl_versionを指定せずに同じ接続を行うと、次のようになります。

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

ssl.PROTOCOL_TLSv1_2ssl.PROTOCOL_SSLv23に置き換えると、少なくとも別のプロトコルを試行する必要がありますが、問題がある場合(サポートされていないなど)は失敗する可能性があります。

私の実験によると、インポートの順序が問題です。次の作品:

import mysql.connector
import ssl

以下は機能しません。

import ssl
import mysql.connector

ssl_ca='', ssl_version=ssl.PROTOCOL_TLSv1_2を設定するかどうかは関係ありません。

また、import requestsの代わりにimport sslを使用しても同じ結果が得られます。

1
daN4cat

現在の構成を確認しました:

テスト環境:

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.7.27                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| tls_version             | TLSv1,TLSv1.1                |
| version                 | 5.7.27                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
8 rows in set (0.04 sec)

prodcut env:

mysql> SHOW VARIABLES LIKE "%version%";

+----------------------------------+-----------------------+
| Variable_name                    | Value                 |
+----------------------------------+-----------------------+
| innodb_polar_restore_old_version | OFF                   |
| innodb_version                   | 8.0.13                |
| protocol_version                 | 10                    |
| rds_audit_log_version            | MYSQL_V1              |
| rds_version                      | 13                    |
| slave_type_conversions           |                       |
| tls_version                      | TLSv1,TLSv1.1,TLSv1.2 |
| version                          | 8.0.13                |
| version_comment                  | Source distribution   |
| version_compile_machine          | x86_64                |
| version_compile_os               | Linux                 |
| version_compile_zlib             | 1.2.11                |
+----------------------------------+-----------------------+
12 rows in set (0.98 sec)

使用されていた以前のバージョンは8.0.16で、リリースは正しいです。 8.0.19への自動更新後、テスト環境で上記のエラーが表示され始めますが、本番環境は問題ありません。

したがって、上記の操作に従ってssl_disabled = Trueを追加しました

ssl_disabled=True

しかし、それがそれらにどのように影響するかはわかりません。

これは、8.0.19バージョンがデフォルトでTLSv1.2を使用しているため、テスト環境でエラーが発生したためだと思いますが、関連するドキュメントが見つかりませんでした

0
hu wentao