はじめに
MySQL においてユーザーのパスワード入力を省略したいとき、たとえばスクリプトを実行したりパスワードをいちいち入力するのが面倒である場合、--login-path
オプションを指定することで実現することができます。そしてこのオプションは、mysql_config_editor コマンドからユーザーのログイン情報を登録することで、使用できるようになります。
今回は、このコマンドにおけるいくつかの注意点やその回避方法について確認していきます。
内容
今回検証した環境は以下の通りです。
- CentOS 7.5
- MySQL 8.0.17
mysql_config_editor について
4.6.7 mysql_config_editor — MySQL Configuration Utility
The mysql_config_editor utility enables you to store authentication credentials in an obfuscated login path file named .mylogin.cnf.
mysql_config_editor を使用することで、.mylogin.cnf
という名前の難読(暗号)化されたファイルに認証情報を保存することができます。そして、その情報をクライアントプログラムから --login-path
オプションを指定して読み取ることで、パスワードを平文で保存することなくパスワードの自動入力を実現することが可能となります。
なお、.mylogin.cnf
は Windows であれば %APPDATA%\MySQL
に、それ以外ではホームディレクトリ配下(~/
)に保存されます。したがって、 作成したユーザー以外から同じログイン情報を参照することはできません。 同じ情報を使いまわしたい場合は、ファイルをコピーするなどして、同じ情報を登録し直す必要がある点に注意してください。
制約事項
今回注目するのは、MySQL 8.0.17 時点でまだ修正されていない、以下のバグとなります。
Bug #74691 mysql_config_editor does not escape strings
このバグでは、mysql_config_editor を使用してパスワードを設定した場合、特定の文字列が正しく認識されず、ログインすることができない旨の内容が記載されています。
具体的に以下の検証をおこなって確かめてみました。
再現試験
以下のようにパスワードにシャープ(「#
」)を含むユーザーを作成します。
1 2 |
mysql> CREATE USER 'test_user1'@'localhost' IDENTIFIED BY 'pass#pass'; Query OK, 0 rows affected (0.01 sec) |
そして、login-path を作成します。
1 2 3 4 5 6 |
# mysql_config_editor set --login-path='test_user1' --user='test_user1' --password Enter password: ※「pass#pass」と入力 # mysql_config_editor print --all [test_user1] user = test_user1 password = ***** |
パスワードを直接指定した場合はログインできますが、--login-path
オプションを指定した場合は認証エラーになってしまうことがわかります。
1 2 3 4 5 6 7 8 |
# mysql --user=test_user1 --password=pass#pass mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. (...) mysql> quit Bye [root@jace ~]# mysql --login-path=test_user1 ERROR 1045 (28000): Access denied for user 'test_user1'@'localhost' (using password: YES) |
回避策
この挙動は、パスワードを入力する際に、クォート(「’」)で囲むことで回避することが可能です。
1 2 3 4 5 6 7 8 |
# mysql_config_editor set --login-path=test_user1 --user=test_user1 --password Enter password: ※「'pass#pass'」と入力) WARNING : 'test_user1' path already exists and will be overwritten. Continue? (Press y|Y for Yes, any other key for No) : Y # mysql --login-path=test_user1 Welcome to the MySQL monitor. Commands end with ; or \g. (...) mysql> |
その他、my.cnf の権限を 600
などに設定して、クライアントオプショングループにログイン情報を書いても構いませんが、平文でパスワードが保存されてしまう点に注意してください。
なお、他の特殊記号(*
?
[
'
"
\
`
$
;
&
(
)
|
~
<
>
%
=
など)はこのバグに該当しないため問題なく使用することが可能ですが、バックスラッシュ(「\
」)は sql_mode に NO_BACKSLASH_ESCAPES が指定されていない限りエスケープ文字として機能するため、注意する必要があります。
MySQL Shell を使用したパスワード保存機能
また、MySQL Shell 8.0.12 からは、初回ログイン時にパスワードを自動で保存してくる機能が追加されています。詳細については、以下の弊社ブログ記事に詳しく記載されているので、ご一読いただければと思います。
この機能を使用してパスワードを保存すると、Linux 上では以下のようにログインパスとして登録がおこなわれていることがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 |
# mysqlsh --user=test_user1 Please provide the password for 'test_user1@localhost': *********(※「pass#pass」と入力) Save password for 'test_user1@localhost'? [Y]es/[N]o/Ne[v]er (default No): Y MySQL Shell 8.0.17 (...) MySQL localhost:33060+ ssl JS > \q Bye! # mysql_config_editor print --all [test_user1@localhost] user = test_user1 password = ***** host = localhost |
この機能ではパスワードは正しくエスケープされているため、シャープ(「#
」)を使用している場合でも、パスワードをそのまま打ち込んでしまって構いません。また、次回以降は、MySQL Shell からではなく、--login-path
オプションを使用しても、正常にログインすることが可能になります。
1 2 3 4 |
# mysql --login-path=test_user1@localhost Welcome to the MySQL monitor. Commands end with ; or \g. (...) mysql> |
まとめ
mysql_config_editor における制約やその回避方法について確認してきました。
ログインパスへの登録について MySQL Shell に同様の機能が追加されており、既存のバグも回避できることなどから、これからは MySQL Shell で動かすことを前提に、クライアントユーティリティツールの開発や移行が進んでいくのかもしれません。