mita2 database life

主にMySQLに関するメモです

MySQLで管理用IFを使いつつ特権ユーザをローカルアカウントのみに絞りたい

以前、接続が溢れているとき(too many connectionsエラー発生時)でも接続可能にする Administrative Network Interface(管理NW IF) の概要をブログに書きました。この時は、特権アカウントの接続元との関連は書かなかったのですが、特権アカウントの接続元をローカルのみに絞りたい場合、少し考えないといけないことがありました。

mita2db.hateblo.jp

特権アカウントはローカル接続のみとしたい

特権アカウントはローカル接続のみとしている(特権で接続するためにDBサーバへのSSHログインを前提とする)場合に、どのように管理用IFを設定すれば良いか試してみました。

ダメな設定

# /etc/my.cnf
admin_port=3307
admin_address=192.168.1.100

まず、このようにadmin_addressにDBサーバのIPアドレスを指定した場合、Admin IFである3307ポートへのアクセスはリモートアクセスのみになります。

# ローカルの3307ポートはLISTENされてない
$ mysql -uroot -P3307 -h127.0.0.1
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)

結果として、(root@'192.168.1.X'のような)リモートアクセス可能な特権アカウントを用意せざるを得ず、要件を満たせません。

要件を満たす設定

admin_address にループバックIF(127.0.0.1)を指定することで、ローカルからの接続が可能になります。127.0.0.1の代わりにlocalhostでも問題ありません。

# /etc/my.cnf
admin_port=3307
admin_address=127.0.0.1
$ mysql -uroot
ERROR 1040 (HY000): Too many connections

# 3307から接続すると、too many connections が出ている状況でも接続可能になっている
$ mysql -uroot -P3307 -h127.0.0.1
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

root@localhostユーザを利用した接続になっていますね。 この設定であれば、追加でリモートアクセス可能な特権アカウントは不要です。これで、要件を満たせそう・・・

と思ったのですが、これは skip_name_resolve が OFF になっていることが前提でした。 接続元ホスト127.0.0.1が名前解決され localhost になるため、root@localhost ユーザ が利用されます。

skip_name_resolve = ON のケース

skip_name_resolve を有効にしている場合は、root@127.0.0.1 ユーザを追加する必要があります。

GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1';

root@localhostUNIXドメインソケット経由の接続のために残す必要があります。 root@localhostroot@127.0.0.1 の2つの特権アカウントが存在する形になり、若干不便ですね・・・

まとめ

Administrative Network Interface を利用しつつ、特権ユーザはローカルホストからのみ接続許可としたい場合:

  1. skip_name_resolve = OFF + admin_address=127.0.0.1

  2. skip_name_resolve = ON + admin_address=127.0.0.1 + root@127.0.0.1 ユーザ