MySQL の CLI クライアントツール(以後 MySQL CLI)を使用中に "password" を含む行がヒストリに残らなくてイライラした事がある人も少なくないと思います。開発環境等では ~/.mysql_history にパスワードが残ってしまうリスクより利便性を優先したい所ですし、そもそも "password" という文字列が含まれるだけでヒストリに残りませんので、思わぬ場面でこの機能が邪魔になる事もあります。
この問題を解決するためのメモです。
解決方法
これを解決するためには、ソースコードを修正してコンパイルしなおすか、バイナリを書き換える以外に方法が無いです。今回はバイナリ書き換えで対応しました。以下のコマンドを実行し、新しい MySQL CLI を作って下さい。
cat `which mysql` |
perl -pe 's/\*(IDENTIFIED\*:\*PASSWORD\*)/\0\1/' > ~/mymysql &&
chmod 755 ~/mymysql
あとは標準の mysql コマンドの代わりに新しく作ったバイナリ(上記の例では ~/mymysql)を使うだけです。
これしか方法が無い理由
MySQL CLI には MYSQL_HISTIGNORE という環境変数、または --histignore オプションを参照し、ここに設定された文字列をヒストリに残さない仕組みがあります。詳細は以下をご覧下さい。
ならば MYSQL_HISTIGNORE を意図的に空にしてやれば "password" が含まれる文字列もヒストリに残るのではないかと思いますが、そうは行きません。なぜなら MYSQL_HISTIGNORE の設定値は、ハードコーディングされた値 *IDENTIFIED*:*PASSWORD* に追加する形でしか登録されないからです(* はワイルドカード、: はデリミタです)。この辺のソースは以下の部分です。
- MySQL 5.7
- https://github.com/mysql/mysql-server/blob/5.7/client/mysql.cc#L1366
- MySQL 8.0
- https://github.com/mysql/mysql-server/blob/8.0/client/mysql.cc#L1359
というわけで、初期値の文字列を直接書き換える事で対応させました。
最後に
ずっと気になってたのですが軽微な問題なので放置してました。別件で MySQL のソースを利用している最中なので、改めて確認してみたら上記の通りで、環境変数やオプションでどうにか出来る問題ではない事が分かってしまいました。
ところで何のためにこうなっているかですが、ヒストリを記録する ~/.mysql_history にパスワード等の秘匿情報を平文で残さないための配慮である事は言うまでもありません。個人的にはこれによって得られるメリットは特に開発環境等において少ないと思っているのですが、リスクと利便性のトレードオフは各自で判断して下さい。