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_ext
は employee
の権限を引き継ぎます。 サーバーは、employee_ext
によってクライアントセッション中に実行されたステートメントを、employee
に付与された権限に対してチェックします。 この場合、employee_ext
は employees
データベースのテーブルにアクセスできます。
プロキシ設定されたアカウント 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
権限が必要です。 この権限を付与するには、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_password
が myuser
の正しいパスワードではないことが 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_password
、sha256_password
。 check_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_user
に proxied_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
です。