MySQL 8.0 リファレンスマニュアル


6.2.18 プロキシユーザー

MySQL サーバーは、認証プラグインを使用してクライアント接続を認証します。 特定の接続を認証するプラグインは、特権チェックのために接続 (外部) ユーザーを別のユーザーとして扱うようにリクエストする場合があります。 これにより、外部ユーザーを 2 人目のユーザーのプロキシにできます。つまり、2 人目のユーザーの権限を引き受けることができます:

  • 外部ユーザーは「プロキシユーザー」 (別のユーザーとして偽装または認識できるユーザー) です。

  • 2 番目のユーザーは「プロキシユーザー」 (プロキシユーザーがアイデンティティと権限を引き受けることができるユーザー) です。

このセクションでは、プロキシユーザー機能の動作について説明します。 認証プラグインに関する一般的な情報については、セクション6.2.17「プラガブル認証」を参照してください。 特定のプラグインの詳細は、セクション6.4.1「認証プラグイン」 を参照してください。 プロキシユーザーをサポートする認証プラグインの記述の詳細は、Implementing Proxy User Support in Authentication Plugins を参照してください。

注記

プロキシによって得られる管理上の利点の 1 つは、DBA が一連の権限を持つ単一のアカウントを設定し、それらの各ユーザーに権限を個別に割り当てることなく、複数のプロキシユーザーがそれらの権限を持つことができることです。 プロキシユーザーのかわりに、DBA は、ユーザーを特定の名前付き権限セットにマップするための適切な方法をロールが提供する場合があります。 各ユーザーには、特定の単一のロールを付与して、実際には適切な権限セットを付与できます。 セクション6.2.10「ロールの使用」を参照してください。

プロキシユーザーサポートの要件

特定の認証プラグインに対してプロキシを実行するには、次の条件を満たす必要があります:

  • プロキシは、プラグイン自体またはプラグインのかわりに MySQL サーバーによってサポートされている必要があります。 後者の場合、サーバーサポートを明示的に有効にする必要がある場合があります。プロキシユーザーマッピングのサーバーサポート を参照してください。

  • プラグインによって認証されるように外部プロキシユーザーのアカウントを設定する必要があります。 CREATE USER ステートメントを使用してアカウントを認証プラグインに関連付けるか、ALTER USER を使用してそのプラグインを変更します。

  • プロキシユーザーのアカウントが存在し、プロキシユーザーが想定する権限が付与されている必要があります。 これには、CREATE USER および GRANT ステートメントを使用します。

  • 通常、プロキシユーザーは、プロキシシナリオでのみ使用でき、直接ログインには使用できないように構成されます。

  • プロキシユーザーアカウントには、プロキシ設定されたアカウントに対する PROXY 権限が必要です。 これを行うには、GRANT ステートメントを使用します。

  • プロキシアカウントに接続しているクライアントをプロキシユーザーとして処理するには、認証プラグインがクライアントユーザー名とは異なるユーザー名を返して、プロキシユーザーが想定する権限を定義するプロキシアカウントのユーザー名を示す必要があります。

    または、サーバーによってプロキシマッピングが提供されるプラグインの場合、プロキシユーザーはプロキシユーザーが保持する PROXY 権限から決定されます。

プロキシメカニズムでは、外部クライアントユーザー名のみをプロキシユーザー名にマップできます。 ホスト名をマッピングするためのプロビジョニングはありません:

  • クライアントがサーバーに接続すると、サーバーはクライアントプログラムによって渡されたユーザー名とクライアントの接続元のホストに基づいて適切なアカウントを決定します。

  • そのアカウントがプロキシアカウントである場合、サーバーは、認証プラグインによって返されたユーザー名とプロキシアカウントのホスト名を使用してプロキシアカウントの一致を検索することで、適切なプロキシアカウントを決定しようとします。 プロキシ設定されたアカウントのホスト名は無視されます。

単純なプロキシユーザーの例

次のアカウント定義について考えてみます:

-- create proxy account
CREATE USER 'employee_ext'@'localhost'
  IDENTIFIED WITH my_auth_plugin
  AS 'my_auth_string';

-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'employee'@'localhost'
  IDENTIFIED WITH mysql_no_login;
GRANT ALL
  ON employees.*
  TO 'employee'@'localhost';

-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'employee'@'localhost'
  TO 'employee_ext'@'localhost';

クライアントがローカルホストから employee_ext として接続すると、MySQL は my_auth_plugin という名前のプラグインを使用して認証を実行します。 my_auth_plugin が、'my_auth_string'の内容に基づいて、外部認証システムを参照することで、employee のユーザー名をサーバーに返すとします。 employee という名前は employee_ext とは異なるため、employee を返すことは、権限チェックの目的で employee_ext 外部ユーザーを employee ローカルユーザーとして処理するためのリクエストとして機能します。

この場合、employee_ext はプロキシユーザーで、employee はプロキシユーザーです。

サーバーは、employee_ext (プロキシユーザー) が employee (プロキシユーザー) に対する PROXY 権限を持っているかどうかを確認することで、employee_ext ユーザーに対して employee のプロキシ認証が可能であることを検証します。 この権限が付与されていない場合は、エラーが発生します。 それ以外の場合、employee_extemployee の権限を引き継ぎます。 サーバーは、employee_ext によってクライアントセッション中に実行されたステートメントを、employee に付与された権限に対してチェックします。 この場合、employee_extemployees データベースのテーブルにアクセスできます。

プロキシ設定されたアカウント employee は、mysql_no_login 認証プラグインを使用して、クライアントがアカウントを使用して直接ログインできないようにします。 (これは、プラグインがインストールされていることを前提としています。 手順については、セクション6.4.1.8「ログインなしのプラガブル認証」 を参照してください。) プロキシ設定されたアカウントを直接使用しないように保護する別の方法については、プロキシアカウントへの直接ログインの防止 を参照してください。

プロキシが発生すると、USER() および CURRENT_USER() の機能を使用して、接続ユーザー (プロキシユーザー) と、現在のセッション中に権限が適用されるアカウント (プロキシユーザー) の違いを確認できます。 先ほど説明した例では、これらの関数は次の値を返します。

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

プロキシユーザーアカウントを作成する CREATE USER ステートメントでは、プロキシサポート認証プラグインを指定する IDENTIFIED WITH 句のあとに、オプションで、ユーザーの接続時にサーバーがプラグインに渡す文字列を指定する AS 'auth_string'句が続きます。 存在する場合、この文字列は、プロキシ (外部) クライアントユーザー名をプロキシユーザー名にマップする方法をプラグインが決定するのに役立つ情報を提供します。 AS 句が必要かどうかは、プラグインごとに異なります。 その場合、認証文字列の形式は、プラグインがそれをどのように使用するかによって異なります。 許可される認証文字列の値については、特定のプラグインに関するドキュメントを参照してください。

プロキシアカウントへの直接ログインの防止

プロキシアカウントは通常、プロキシアカウントによってのみ使用されます。 つまり、クライアントはプロキシアカウントを使用して接続し、適切なプロキシユーザーの権限にマップされて引き受けます。

プロキシ設定されたアカウントを直接使用できないようにするには、複数の方法があります:

  • アカウントを mysql_no_login 認証プラグインに関連付けます。 この場合、アカウントはどのような状況でも直接ログインには使用できません。 これは、プラグインがインストールされていることを前提としています。 その手順は、セクション6.4.1.8「ログインなしのプラガブル認証」を参照してください。

  • アカウントの作成時に ACCOUNT LOCK オプションを含めます。 セクション13.7.1.3「CREATE USER ステートメント」を参照してください。 この方法では、アカウントが後でロック解除された場合にパスワードなしでアクセスできないように、パスワードも含めます。 (validate_password コンポーネントが有効な場合、アカウントがロックされていても、パスワードなしのアカウントの作成は許可されません。 セクション6.4.3「パスワード検証コンポーネント」を参照してください。)

  • パスワードを使用してアカウントを作成しますが、他のユーザーにはパスワードを通知しません。 アカウントのパスワードを誰にも知らない場合、クライアントはそれを使用して MySQL サーバーに直接接続できません。

PROXY 権限の付与および取消し

外部ユーザーが別のユーザーとして接続し、別のユーザーの権限を持つことができるようにするには、PROXY 権限が必要です。 この権限を付与するには、GRANT ステートメントを使用します。 例:

GRANT PROXY ON 'proxied_user' TO 'proxy_user';

このステートメントは、mysql.proxies_priv 付与テーブルに行を作成します。

接続時に、proxy_user は有効な外部認証 MySQL ユーザーを表し、proxied_user は有効なローカル認証ユーザーを表す必要があります。 そうでない場合、接続は失敗します。

対応する REVOKE 構文は次のとおりです。

REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';

MySQL GRANT および REVOKE 構文の拡張機能は、通常どおりに動作します。 例:

-- grant PROXY to multiple accounts
GRANT PROXY ON 'a' TO 'b', 'c', 'd';

-- revoke PROXY from multiple accounts
REVOKE PROXY ON 'a' FROM 'b', 'c', 'd';

-- grant PROXY to an account and enable the account to grant
-- PROXY to the proxied account
GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION;

-- grant PROXY to default proxy account
GRANT PROXY ON 'a' TO ''@'';

次のような場合に、PROXY 権限を付与できます。

  • proxied_user に対する GRANT PROXY ... WITH GRANT OPTION を持つユーザーによる。

  • 自分で proxied_user による: アカウント名のユーザー名とホスト名の両方の部分で、USER() の値が CURRENT_USER() および proxied_user と完全に一致する必要があります。

MySQL のインストール中に作成された最初の root アカウントには、''@''(すべてのユーザーおよびすべてのホスト) に対する PROXY ... WITH GRANT OPTION 権限があります。 これにより、root はプロキシユーザーを設定したり、プロキシユーザーを設定するための権限をほかのアカウントに委任したりできます。 たとえば、root は次の操作を実行できます。

CREATE USER 'admin'@'localhost'
  IDENTIFIED BY 'admin_password';
GRANT PROXY
  ON ''@''
  TO 'admin'@'localhost'
  WITH GRANT OPTION;

これらのステートメントによって、すべての GRANT PROXY マッピングを管理できる admin ユーザーが作成されます。 たとえば、admin は次の操作を実行できます。

GRANT PROXY ON sally TO joe;

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

一部またはすべてのユーザーが特定の認証プラグインを使用して接続する必要があることを指定するには、空のユーザー名とホスト名 (''@'') で「空白」 MySQL アカウントを作成し、それをそのプラグインに関連付けて、プラグインが実際の認証済ユーザー名を返すようにします (空白のユーザーと異なる場合)。 LDAP 認証を実装し、接続ユーザーを開発者またはマネージャアカウントにマップする ldap_auth という名前のプラグインが存在するとします。 これらのアカウントに対するユーザーのプロキシを設定するには、次のステートメントを使用します:

-- create default proxy account
CREATE USER ''@''
  IDENTIFIED WITH ldap_auth
  AS 'O=Oracle, OU=MySQL';

-- create proxied accounts; use
-- mysql_no_login plugin to prevent direct login
CREATE USER 'developer'@'localhost'
  IDENTIFIED WITH mysql_no_login;
CREATE USER 'manager'@'localhost'
  IDENTIFIED WITH mysql_no_login;

-- grant to default proxy account the
-- PROXY privilege for proxied accounts
GRANT PROXY
  ON 'manager'@'localhost'
  TO ''@'';
GRANT PROXY
  ON 'developer'@'localhost'
  TO ''@'';

ここで、クライアントが次のように接続するとします:

shell> mysql --user=myuser --password ...
Enter password: myuser_password

サーバーは MySQL ユーザーとして定義された myuser を検出しませんが、クライアントユーザー名およびホスト名と一致する空白のユーザーアカウント (''@'') があるため、サーバーはそのアカウントに対してクライアントを認証します。 サーバーは ldap_auth 認証プラグインを呼び出し、myuser および myuser_password をユーザー名とパスワードとして渡します。

myuser_passwordmyuser の正しいパスワードではないことが LDAP ディレクトリで ldap_auth プラグインによって検出された場合、認証は失敗し、サーバーは接続を拒否します。

パスワードが正しく、ldap_auth によって myuser が開発者であることが検出された場合は、MySQL サーバーに myuser ではなく、developer というユーザー名が返されます。 myuser のクライアントユーザー名とは異なるユーザー名を返すと、myuser をプロキシとして扱う必要があることがサーバーに通知されます。 サーバーは、''@''developer として認証できることを検証し (''@''にはそれを行う PROXY 権限があるため)、接続を受け入れます。 セッションは、developer プロキシユーザーの権限を持つ myuser に進みます。 (これらの権限は、DBA が GRANT ステートメントを使用して設定するべきですが、表示されません。) USER() および CURRENT_USER() 関数は、次の値を返します。

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

かわりに、LDAP ディレクトリで myuser がマネージャであることが検出されると、ユーザー名として manager が返され、セッションは manager プロキシユーザーの権限を持つ myuser で続行されます。

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

単純にするために、外部認証はマルチレベルで実行できません。前述の例では、developer の証明書も、manager の証明書も考慮されません。 ただし、クライアントが developer または manager アカウントとして直接接続および認証しようとする場合は、これらのプロキシアカウントを直接ログインから保護する必要があります (プロキシアカウントへの直接ログインの防止 を参照)。

デフォルトのプロキシユーザーと匿名ユーザーの競合

デフォルトのプロキシユーザーを作成する場合は、デフォルトのプロキシユーザーよりも優先される他の既存の「いずれかのユーザーに一致」アカウントを確認します。これは、そのユーザーが意図したとおりに作業できない可能性があるためです。

前述の説明で、デフォルトのプロキシユーザーアカウントのホスト部分には、任意のホストと一致する''があります。 デフォルトのプロキシユーザーを設定する場合は、ホスト部分に同じユーザー部分と'%'を持つ非プロキシアカウントが存在するかどうかも注意して確認してください。これは、'%'も任意のホストに一致しますが、サーバーがアカウント行を内部的にソートするために使用するルールによって''よりも優先されるためです (セクション6.2.6「アクセス制御、ステージ 1: 接続の検証」 を参照)。

MySQL のインストールに、次の 2 つのアカウントが含まれていると仮定します。

-- create default proxy account
CREATE USER ''@''
  IDENTIFIED WITH some_plugin
  AS 'some_auth_string';
-- create anonymous account
CREATE USER ''@'%'
  IDENTIFIED BY 'anon_user_password';

最初のアカウント (''@'') はデフォルトのプロキシユーザーとして使用され、それ以外の場合はより特定のアカウントと一致しないユーザーの接続を認証するために使用されます。 2 つ目のアカウント (''@'%') は匿名ユーザーアカウントで、たとえば、独自のアカウントを持たないユーザーが匿名で接続できるようにするために作成された可能性があります。

両方のアカウントに同じユーザー部分 ('') があり、これは任意のユーザーに一致します。 各アカウントには、任意のホストと一致するホスト部分があります。 ただし、一致ルールは''の前に'%'のホストをソートするため、接続試行のアカウント照合には優先度があります。 他の特定のアカウントと一致しないアカウントの場合、サーバーは''@'' (デフォルトのプロキシユーザー) ではなく、''@'%' (匿名ユーザー) に対して認証を試みます。 その結果、デフォルトのプロキシアカウントは使用されません。

この問題を回避するには、次のいずれかの方法を使用します:

  • 匿名アカウントを削除して、デフォルトのプロキシユーザーと競合しないようにします。

  • 匿名ユーザーの前に一致する特定のデフォルトプロキシユーザーを使用します。 たとえば、localhost プロキシ接続のみを許可するには、''@'localhost'を使用します:

    CREATE USER ''@'localhost'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';

    また、GRANT PROXY ステートメントを変更して、''@''ではなく''@'localhost'をプロキシユーザーとして指定します。

    この戦略により、localhost からの匿名ユーザー接続が防止されることに注意してください。

  • 匿名のデフォルトアカウントではなく、名前付きのデフォルトアカウントを使用します。 この方法の例については、authentication_windows プラグインを使用する手順を参照してください。 セクション6.4.1.6「Windows プラガブル認証」を参照してください。

  • 複数のプロキシユーザーを作成します。1 つはローカル接続用、もう 1 つは「その他すべて」用です (リモート接続)。 これは、特にローカルユーザーがリモートユーザーとは異なる権限を持つ必要がある場合に役立ちます。

    プロキシユーザーを作成します:

    -- create proxy user for local connections
    CREATE USER ''@'localhost'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';
    -- create proxy user for remote connections
    CREATE USER ''@'%'
      IDENTIFIED WITH some_plugin
      AS 'some_auth_string';

    プロキシユーザーを作成します:

    -- create proxied user for local connections
    CREATE USER 'developer'@'localhost'
      IDENTIFIED WITH mysql_no_login;
    -- create proxied user for remote connections
    CREATE USER 'developer'@'%'
      IDENTIFIED WITH mysql_no_login;

    各プロキシアカウントに、対応するプロキシアカウントの PROXY 権限を付与します:

    GRANT PROXY
      ON 'developer'@'localhost'
      TO ''@'localhost';
    GRANT PROXY
      ON 'developer'@'%'
      TO ''@'%';

    最後に、ローカルおよびリモートのプロキシユーザーに適切な権限を付与します (表示されていません)。

    some_plugin/'some_auth_string'の組合せによって、some_plugin がクライアントユーザー名を developer にマップするとします。 ローカル接続は、'developer'@'localhost'プロキシユーザーにマップされる''@'localhost'プロキシユーザーと一致します。 リモート接続は、'developer'@'%'プロキシユーザーにマップされる''@'%'プロキシユーザーと一致します。

プロキシユーザーマッピングのサーバーサポート

一部の認証プラグインは、プロキシユーザーマッピングを実装しています (PAM や Windows 認証プラグインなど)。 その他の認証プラグインは、デフォルトではプロキシユーザーをサポートしていません。 その中には、付与されたプロキシ権限に従って、MySQL サーバー自体がプロキシユーザーをマップするようにリクエストできるものがあります: mysql_native_passwordsha256_passwordcheck_proxy_users システム変数が有効になっている場合、サーバーは、このようなリクエストを行う認証プラグインに対してプロキシユーザーマッピングを実行します:

  • デフォルトでは、check_proxy_users は無効になっているため、サーバーはプロキシユーザーのサーバーサポートをリクエストする認証プラグインに対してもプロキシユーザーマッピングを実行しません。

  • check_proxy_users が有効になっている場合は、サーバープロキシユーザーマッピングのサポートを利用するために、プラグイン固有のシステム変数を有効にする必要がある場合もあります:

    • mysql_native_password プラグインの場合は、mysql_native_password_proxy_users を有効にします。

    • sha256_password プラグインの場合は、sha256_password_proxy_users を有効にします。

たとえば、前述のすべての機能を有効にするには、my.cnf ファイルで次の行を使用してサーバーを起動します:

[mysqld]
check_proxy_users=ON
mysql_native_password_proxy_users=ON
sha256_password_proxy_users=ON

関連するシステム変数が有効になっている場合は、CREATE USER を使用して通常どおりにプロキシユーザーを作成し、プロキシユーザーとして扱われる単一の他のアカウントに PROXY 権限を付与します。 サーバーは、プロキシユーザーに対する正常な接続リクエストを受信すると、そのユーザーに PROXY 権限があることを確認し、それを使用して適切なプロキシユーザーを決定します。

-- create proxy account
CREATE USER 'proxy_user'@'localhost'
  IDENTIFIED WITH mysql_native_password
  BY 'password';

-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'proxied_user'@'localhost'
  IDENTIFIED WITH mysql_no_login;
-- grant privileges to proxied account
GRANT ...
  ON ...
  TO 'proxied_user'@'localhost';

-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'proxied_user'@'localhost'
  TO 'proxy_user'@'localhost';

プロキシアカウントを使用するには、名前とパスワードを使用してサーバーに接続します:

shell> mysql -u proxy_user -p
Enter password: (enter proxy_user password here)

認証に成功すると、サーバーは proxy_userproxied_user に対する PROXY 権限があることを検出し、セッションは proxied_user の権限を持つ proxy_user に進みます。

サーバーによって実行されるプロキシユーザーマッピングには、次の制限事項があります:

  • 関連付けられた PROXY 権限が付与されている場合でも、サーバーは匿名ユーザーとの間でプロキシを行いません。

  • 単一のアカウントに複数のプロキシアカウントのプロキシ権限が付与されている場合、サーバープロキシユーザーマッピングは非決定的です。 したがって、複数のプロキシアカウントに対する単一アカウントのプロキシ権限への付与はお薦めしません。

プロキシユーザーのシステム変数

次の 2 つのシステム変数は、プロキシのログインプロセスをトレースする際に役立ちます。

  • proxy_user: プロキシ処理が使用されていない場合、この値は NULL です。 それ以外の場合は、プロキシユーザーのアカウントを示します。 たとえば、クライアントが''@''プロキシアカウントを介して認証する場合、この変数は次のように設定されます:

    mysql> SELECT @@proxy_user;
    +--------------+
    | @@proxy_user |
    +--------------+
    | ''@''        |
    +--------------+
  • external_user: 認証プラグインは外部ユーザーを使用して、MySQL サーバーへの認証を行うことがあります。 たとえば、Windows のネイティブ認証を使用するときは、Windows の API を使用して認証するプラグインに、ログイン ID を渡す必要がありません。 ただし、認証には引き続き Windows ユーザ ID が使用されます。 このプラグインは、読み取り専用のセッション変数 external_user を使用して、この外部ユーザー ID (または最初の 512 UTF-8 バイト) をサーバーに返すことがあります。 プラグインがこの変数を設定しない場合、その値は NULL です。


関連キーワード:  ユーザー, アカウント, 認証, 権限, PROXY, サーバー, 接続, user, proxy, GRANT