MySQLのProxy User

MySQL 5.5からユーザ認証の仕組みがプラグイン化され、それに伴ってProxy Userなるものが導入されています。マニュアルを読んでも分かりにくい。特に"Proxy User"と"Proxied User"の違いとか。ということでマニュアルを翻訳したら理解できるかと思ってやり始めました。

が、しかし!!
すでに分かりやすい短い解説が↓ここに orz
漢(オトコ)のコンピュータ道: MySQL 5.5新機能徹底解説 ここの「認証および監査のプラグイン化」の項目
とりあえずマニュアルの抄訳もやっちゃったので残しておきます。

MySQL 5.6 Reference Manual 6.3.8. Proxy Usersの抄訳

MySQLサーバへの認証を認証プラグインで行う際、権限の確認のために外部からの接続ユーザを別のユーザとして取り扱うことをプラグインは要求する。これは外部のユーザを"第2のユーザ"としてプロキシすることを可能とする; つまり"第2のユーザ"の権限を持つことである。言い換えると、外部ユーザは(他のユーザとして振る舞うことができるユーザ)「プロキシ・ユーザ Proxy User」であり、"第2のユーザ"は(「プロキシ・ユーザ」によって権限を利用されるユーザ)「プロキシされた・ユーザ Proxied User」となる。

本章ではプロキシ・ユーザ機能を解説する。認証プラグインの一般的な情報はSection 6.3.7, “Pluggable Authentication”。プロキシ・ユーザをサポートした独自の認証プラグインを開発を計画している場合はSection 22.2.4.9.4, “Implementing Proxy User Support in Authentication Plugins”を参照。

プロキシは以下の条件を満たした場合に行われる;

  • 接続するクライアントが「プロキシ・ユーザ」として扱われる場合、「プロキシされた・ユーザ」として識別するために、プラグインは別の名称を返す
  • プロキシ・ユーザ」のアカウントはプラグインによって認証されなければならない。CREATE USER文やGRANT文によってプラグインとアカウントが結びつけられる
  • プロキシ・ユーザ」のアカウントは、「プロキシされた・ユーザ」のアカウントに対するPROXY権限を持つ。GRANT文によってこれを行う。

CREATE USER 'empl_external'@'localhost'
  IDENTIFIED WITH auth_plugin AS 'auth_string';
CREATE USER 'employee'@'localhost'
  IDENTIFIED BY 'employee_pass';
GRANT PROXY
  ON 'employee'@'localhost'
  TO 'empl_external'@'localhost';

ローカルホスト上のクライアントからユーザ名empl_externalで接続すると、MySQLサーバはauth_pluginで認証を行う。もし('auth_string'のコンテンツを元に外部認証システムなどを利用して)auth_pluginがユーザ名employeeをMySQLサーバに返すと、MySQLサーバ内での権限チェックのために、MySQLサーバはemployeeユーザとしてこのクライアント接続を扱う。この場合、'empl_external'が「プロキシ・ユーザ」で、'employee' が「プロキシされた・ユーザ」となる。サーバは、'employee'としてのプロキシ認証を'empl_external'ができるかを、'empl_external'が'employee'に対するPROXY権限を持っているかどうかをチェックすることで確かめる。

USER() と CURRENT_USER() (詳細は略)

USER():接続したユーザアカウント
CURRENT_USER():このセッションで適用されている権限に該当するアカウント

mysql> SELECT USER(), CURRENT_USER();
+-------------------------+--------------------+
| USER()                  | CURRENT_USER()     |
+-------------------------+--------------------+
| empl_external@localhost | employee@localhost |
+-------------------------+--------------------+

PROXY権限の付与 (略)

デフォルト プロキシユーザ

一部もしくは全てのユーザが外部プラグインを利用するよう設定する場合は、「ブランク」MySQLユーザを作成し、このこれが認証プラグインを利用するよう設定する。これによってプラグインは実際に使用するユーザ名(ブランクとは異なるユーザ名)を返す。ldap_authを使ってLDAP認証を行う例は以下の通り:

CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL';
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'developer_pass';
CREATE USER 'manager'@'localhost' IDENTIFIED BY 'manager_pass';
GRANT PROXY ON 'manager'@'localhost' TO ''@'';
GRANT PROXY ON 'developer'@'localhost' TO ''@'';

ここでクライアントが接続を試みた場合、

mysql --user=myuser --password='myuser_pass' ...

サーバはMySQLユーザとしてのmyuserを見つけることはできない(mysql.userテーブルに存在しないため)。しかし、 ''@'' で表現されるブランクユーザアカウントが存在している。これにユーザ名とホスト名がマッチするため、サーバはクライアントの認証をこのアカウントにて行う。サーバはldap_authを利用してmyuserとmyuser_passをユーザとパスワードとして渡す。

ldap_authがLDAPディレクトリにてmyuser_passがmyuserユーザのパスワードとして正しくないと判断すると、サーバは接続を拒否する。

もしパスワードが正しく、かつldap_authがmyuserユーザはdeveloperであると判断すると、プラグインはサーバにユーザ名developerを返す。サーバは ''@'' がPROXY権限を持つdeveloperとして認証されたとして接続を許可する。該当のセッションはmyuserユーザがdeveloperの権限で処理される。(この例では記載されていないがdeveloperには適宜権限をGRANT文で付与すること) USER() と CURRENT_USER()の出力は以下の通り。

mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER()           | CURRENT_USER()      |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+