Pythonにmysql_connector_pythonライブラリをimportして、MySQLへデータベースを作成しようとしたところ、以下のエラーメッセージが表示された。
mysql.connector.errors.InterfaceError: 2026 (HY000): SSL connection error: SSL_CTX_set_tmp_dh failed
色々調べた結果から書くと、MySQLの認証プラグインだったmysql_native_passwordから、Ver.8.0以降caching_sha2_passwordに変更され、その関係でmy.cnfファイルに書いたdefault_authentication_pluginが従来のmysql_native_passwordに設定されている場合、上記のエラーが発生してしまうようだ。
この文章を書いている2019年以降、少し前のMySQLのVer.5系で書かれた技術書で勉強している人はハマるかもしれない罠なのでお気をつけください。
根本的な解決にはならないのですが、取り急ぎ学習を進めたい場合、以下の方法で乗り切れると考えます。
MySQLの接続に利用しているユーザーの使っている認証プラグインを調べる。
mysql> select User, Plugin from mysql.user
これで表示されるユーザーリスト上の認証プラグインを確認
対応する認証プラグインがcaching_sha2_passwordだった場合、これを従来のmysql_native_passwordへ変更してしまうと良い。
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘P@ssw0rd’;
例えば、上のように利用しているユーザーが「root」だった場合、このようにしてmysql_native_passwordへ変更してしまおう。
この時、もう一つ罠があって、mysql_secure_installation使って認証プラグインの設定を行った際、初期パスワードの設定ポリシーをLOWに設定しても、いつの間にか設定はMEDIUMに変更されているので注意。上記で設定する’P@ssw0rd’をLOWのつもりで設定すると
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
というエラーが出て、パスワードを強化しろと怒られる。
mysql> show variables like ‘validate_password%’;
+————————————–+——–+
| Variable_name | Value |
+————————————–+——–+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 1 |
+————————————–+——–+
7 rows in set (0.00 sec)
調べてみると、いつの間にかパスワードのポリシーがMEDIUMになっている。
この場合、LOWヘ戻したければ
mysql> set global validate_password.policy=LOW;
として
Query OK, 0 rows affected (0.00 sec)
と表示されれば変更に成功です。
mysql> show variables like ‘validate_password%’;
+————————————–+——-+
| Variable_name | Value |
+————————————–+——-+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | LOW |
| validate_password.special_char_count | 1 |
+————————————–+——-+
7 rows in set (0.01 sec)
改めて
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘P@ssw0rd’;
今度はパスワードの強化を求められず、無事に認証プラグインをmysql_native_passwordへ変更できたはずです。
以下の要領で確認
mysql> select User, Plugin from mysql.user where User = ‘root’;
+——+———————–+
| User | Plugin |
+——+———————–+
| root | mysql_native_password |
+——+———————–+
1 row in set (0.00 sec)
念の為、MySQLサーバを再起動し
改めて、Pythonでconnect()をテストしてみてください。
conn = mysql.connector.connect(host=’127.0.0.1′, user=’root’, password=’P@ssw0rd’, ssl_disabled=True)
この時、ssl_disabled=Trueを引数に加えておくことで、SSL認証せず、続くSQL文がエラーなく実行されるはずです。
Tips書くの結構大変!
今日のところはこれまで
追記:
以下のサイトに、もっと詳しく情報が記載されていました!感謝!
https://tech.bita.jp/article/32