8.2.19 Пользователи-прокси
Сервер MySQL аутентифицирует подключения клиентов, используя плагины аутентификации. Плагин, который аутентифицирует данное подключение, может потребовать, чтобы подключившийся (внешний) пользователь рассматривался как другой пользователь для целей проверки привилегий. Это позволяет внешнему пользователю выступать в качестве прокси для второго пользователя; то есть, принять на себя привилегии второго пользователя:
Внешний пользователь является “пользователем-прокси” (пользователь, который может имитировать или стать известным как другой пользователь).
Второй пользователь является “проксируемым пользователем” (пользователь, чья личность и привилегии могут быть приняты на себя пользователем-прокси).
В этом разделе описывается, как работает механизм пользователей-прокси. Для общей информации о плагинах аутентификации см. Раздел 8.2.17, «Подключаемые плагины аутентификации». Для информации о конкретных плагинах см. Раздел 8.4.1, «Плагины аутентификации». Для получения информации о написании плагинов аутентификации, поддерживающих пользователей-прокси, см. Реализация поддержки пользователей-прокси в плагинах аутентификации.
Одно из административных преимуществ использования прокси заключается в том, что DBA может создать одну учетную запись с набором привилегий, а затем разрешить множеству пользователей-прокси иметь эти привилегии, не назначая их индивидуально каждому пользователю. В качестве альтернативы пользователям-прокси DBA могут обнаружить, что роли предоставляют подходящий способ сопоставления пользователей с определёнными именованными наборами привилегий. Каждый пользователю может быть назначена определённая роль, чтобы получить соответствующий набор привилегий. См. Раздел 8.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 возвращает имя пользователя employee серверу, основываясь на содержимом ' и, возможно, обращаясь к какой-то внешней системе аутентификации. Имя my_auth_string'employee отличается от employee_ext, поэтому возврат employee служит запросом к серверу обрабатывать внешнего пользователя employee_ext в целях проверки привилегий как локального пользователя employee.
В этом случае employee_ext является пользователем-прокси, а employee — проксируемым пользователем.
Сервер проверяет возможность аутентификации по прокси для employee пользователя employee_ext, проверив, имеет ли employee_ext (пользователь-прокси) привилегию PROXY для employee (проксируемого пользователя). Если эта привилегия не назначена, возникает ошибка. В противном случае employee_ext принимает на себя привилегии employee. Сервер проверяет запросы, выполняемые во время сессии клиента от имени пользователя employee_ext, по отношению к привилегиям, предоставленным пользователю employee. В данном случае employee_ext может получать доступ к таблицам в базе данных employees.
Проксируемая учетная запись employee использует плагин аутентификации mysql_no_login, чтобы предотвратить подключение клиентов напрямую к данной учетной записи. (Предполагается, что плагин установлен. Инструкции см. в Разделе 8.4.1.8, «No-Login Pluggable Authentication»). Для альтернативных методов защиты проксируемых учетных записей от прямого использования см. Предотвращение прямого входа в проксируемые учетные записи.
При проксировании функции 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. В этом случае аккаунт нельзя использовать для прямого входа ни при каких обстоятельствах. Предполагается, что плагин установлен. Инструкции см. в разделе 8.4.1.8 «Плагин аутентификации без входа».Включите опцию
ACCOUNT LOCKпри создании аккаунта. См. раздел 15.7.1.3 «Оператор CREATE USER». В этом методе также укажите пароль, чтобы в случае последующего разблокирования аккаунта к нему нельзя было получить доступ без пароля. (Если включён компонентvalidate_password, создание аккаунта без пароля запрещено, даже если аккаунт заблокирован. См. раздел 8.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 может быть предоставлена в следующих случаях:
Пользователем, имеющим
GRANT PROXY ... WITH GRANT OPTIONдляproxied_user.Самим
proxied_user: значение функцииUSER()должно точно совпадать со значением функцииCURRENT_USER()иproxied_user, как для имени пользователя, так и для имени хоста.
Изначальный root аккаунт, созданный при установке MySQL, имеет привилегию PROXY ... WITH GRANT
OPTION для ''@'', то есть для всех пользователей и всех хостов. Это позволяет root настраивать прокси-пользователей, а также делегировать другим аккаунтам полномочия по настройке прокси-пользователей. Например, root может сделать это:
CREATE USER 'admin'@'localhost'
IDENTIFIED BY 'admin_password';
GRANT PROXY
ON ''@''
TO 'admin'@'localhost'
WITH GRANT OPTION;
Эти операторы создают пользователя admin, который может управлять всеми отображениями GRANT PROXY. Например, admin может сделать это:
GRANT PROXY ON sally TO joe;
Прокси-пользователи по умолчанию
Чтобы указать, что некоторые или все пользователи должны подключаться с помощью определённого плагина аутентификации, создайте пустой аккаунт MySQL с пустым именем пользователя и хоста (''@''), свяжите его с этим плагином и позвольте плагину возвращать реальное имя аутентифицированного пользователя (если оно отличается от пустого пользователя). Предположим, что существует плагин с именем ldap_auth, который реализует аутентификацию LDAP и сопоставляет подключаемых пользователей либо аккаунту разработчика, либо аккаунту менеджера. Чтобы настроить проксирование пользователей на эти аккаунты, используйте следующие операторы:
-- 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 ''@'';
Теперь предположим, что клиент подключается следующим образом:
$> mysql --user=myuser --password ...
Enter password: myuser_password
Сервер не находит myuser, определённого как пользователя MySQL, но поскольку существует пустой аккаунт (''@''), который соответствует имени пользователя и имени хоста клиента, сервер аутентифицирует клиента по этому аккаунту. Сервер вызывает плагин аутентификации ldap_auth и передаёт ему myuser и myuser_password в качестве имени пользователя и пароля.
Если плагин ldap_auth найдёт в каталоге LDAP, что myuser_password не является правильным паролем для myuser, аутентификация завершится неудачно, и сервер отклонит подключение.
Если пароль верен и ldap_auth обнаружит, что myuser является разработчиком, он вернёт имя пользователя developer серверу MySQL вместо myuser. Возвращение имени пользователя, отличного от имени пользователя клиента myuser, сигнализирует серверу, что он должен рассматривать myuser как прокси. Сервер проверяет, что ''@'' может пройти аутентификацию как developer (поскольку у ''@'' есть привилегия PROXY для этого) и принимает подключение. Сессия продолжается с myuser, имеющим привилегии прокси-пользователя developer. (Эти привилегии должны быть настроены администратором базы данных с использованием операторов GRANT, которые здесь не показаны.) Функции USER() и CURRENT_USER() возвращают эти значения:
mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER() | CURRENT_USER() |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+
Если плагин вместо этого найдёт в каталоге LDAP, что myuser является менеджером, он вернёт manager в качестве имени пользователя, и сессия продолжится с myuser, имеющим привилегии прокси-пользователя manager.
mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER() | CURRENT_USER() |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+
Для простоты внешняя аутентификация не может быть многоуровневой: ни учётные данные для developer, ни учётные данные для manager не учитываются в предыдущем примере. Однако они всё ещё используются, если клиент пытается подключиться и пройти аутентификацию непосредственно как учётная запись developer или manager, поэтому эти прокси-аккаунты следует защитить от прямого входа (см. Предотвращение прямого входа в прокси-аккаунты).
Конфликты стандартного пользователя-прокси и анонимного пользователя
Если вы намерены создать стандартного пользователя-прокси, проверьте наличие других учетных записей “соответствующих любому пользователю”, которые имеют приоритет над стандартным пользователем-прокси, поскольку они могут помешать его работе.
В предыдущем обсуждении учетная запись стандартного пользователя-прокси имеет '' в части имени хоста, что соответствует любому хосту. Если вы настраиваете стандартного пользователя-прокси, обратите внимание на существование учетных записей без прокси с той же частью имени пользователя и '%' в части имени хоста, потому что '%' также соответствует любому хосту, но имеет приоритет над '' по правилам, которые сервер использует для сортировки строк учетных записей внутри (см. Раздел 8.2.6, «Управление доступом, этап 1: Проверка подключения»).
Предположим, что установка MySQL включает в себя эти две учетные записи:
-- create default proxy account
CREATE USER ''@''
IDENTIFIED WITH some_plugin
AS 'some_auth_string';
-- create anonymous account
CREATE USER ''@'%'
IDENTIFIED BY 'anon_user_password';
Первая учетная запись (''@'') предназначена в качестве стандартного пользователя-прокси, используемого для аутентификации подключений для пользователей, которые не соответствуют более конкретной учетной записи. Вторая учетная запись (''@'%') — это учетная запись анонимного пользователя, которая могла быть создана, например, для обеспечения возможности подключения анонимно для пользователей без собственной учетной записи.
Обе учетные записи имеют ту же часть имени пользователя (''), которая соответствует любому пользователю. И каждая учетная запись имеет часть имени хоста, которая соответствует любому хосту. Тем не менее, существует приоритет в соответствии с учетными записями для попыток подключения, поскольку правила сопоставления сортируют хост '%' перед ''. Для учетных записей, которые не соответствуют более конкретной учетной записи, сервер пытается выполнить аутентификацию по ''@'%' (анонимный пользователь), а не по ''@'' (стандартный пользователь-прокси). В результате стандартная учетная запись прокси никогда не используется.
Чтобы избежать этой проблемы, воспользуйтесь одним из следующих стратегий:
Удалите учетную запись анонимного пользователя, чтобы она не конфликтовала со стандартным пользователем-прокси.
-
Используйте более конкретного стандартного пользователя-прокси, который соответствует перед анонимным пользователем. Например, чтобы разрешить только
localhostподключения прокси, используйте''@'localhost':CREATE USER ''@'localhost' IDENTIFIED WITH some_plugin AS '
some_auth_string';Кроме того, измените все
GRANT PROXYоператоры, чтобы назвать''@'localhost', а не''@'', как пользователя-прокси.Обратите внимание, что эта стратегия предотвращает подключения анонимных пользователей от
localhost. Используйте именованную учетную запись по умолчанию, а не анонимную учетную запись по умолчанию. Для примера этой техники обратитесь к инструкциям по использованию плагина
authentication_windows. См. Раздел 8.4.1.5, «Подключаемая аутентификация Windows».-
Создайте нескольких пользователей-прокси, одного для локальных подключений и одного для “всего остального” (удаленных подключений). Это может быть полезно особенно в тех случаях, когда локальные пользователи должны иметь разные привилегии, чем удаленные пользователи.
Создайте пользователей-прокси:
-- 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. Локальные подключения соответствуют пользователю-прокси''@'localhost', который отображается как пользователь'developer'@'localhost'прокси. Удаленные подключения соответствуют пользователю-прокси''@'%', который отображается как пользователь'developer'@'%'прокси.
Поддержка сервером отображения пользователя-прокси
Некоторые плагины аутентификации реализуют отображение пользователя-прокси для себя (например, плагины PAM и Windows аутентификации). Другие плагины аутентификации по умолчанию не поддерживают пользователей-прокси. sha256_password может запросить, чтобы сам сервер MySQL отображал пользователей-прокси в соответствии с предоставленными привилегиями прокси. Если переменная системы check_proxy_users включена, сервер выполняет отображение пользователей-прокси для любых плагинов аутентификации, которые делают такой запрос:
-
По умолчанию
check_proxy_usersотключена, поэтому сервер не выполняет отображение пользователей-прокси даже для плагинов аутентификации, которые запрашивают поддержку сервера для пользователей-прокси. -
Если
check_proxy_usersвключена, может также потребоваться включение плагин-специфической переменной системы, чтобы воспользоваться поддержкой отображения пользователя-прокси сервера. Для плагинаsha256_passwordвключитеsha256_password_proxy_users.
Например, чтобы включить все вышеперечисленные возможности, запустите сервер с этими строками в файле my.cnf:
[mysqld]
check_proxy_users=ON
sha256_password_proxy_users=ON
Предполагая, что соответствующие переменные системы были включены, создайте пользователя-прокси как обычно с помощью CREATE
USER, затем предоставьте ему привилегию PROXY для единственной другой учетной записи, которая будет рассматриваться как пользователь-прокси. Когда сервер получает успешный запрос подключения для пользователя-прокси, он обнаруживает, что у пользователя есть привилегия PROXY, и использует её для определения соответствующего пользователя-прокси.
-- create proxy account
CREATE USER 'proxy_user'@'localhost'
IDENTIFIED WITH sha256_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';
Для использования учетной записи прокси подключитесь к серверу, используя её имя и пароль:
$> mysql -u proxy_user -p
Enter password: (enter proxy_user password here)
Аутентификация проходит успешно, сервер обнаруживает, что proxy_user имеет привилегию PROXY для proxied_user, и сеанс продолжается с proxy_user с привилегиями proxied_user.
Отображение пользователя-прокси, выполняемое сервером, ограничено следующими условиями:
Сервер не выполняет прокси-аутентификацию к анонимному пользователю или из него, даже если соответствующая привилегия
PROXYпредоставлена.Когда одной учетной записи предоставлены привилегии прокси для более чем одной учетной записи прокси, отображение пользователя-прокси сервером является недетерминированным. Поэтому предоставление одной учетной записи привилегий прокси для нескольких учетных записей прокси не рекомендуется.
Переменные системы пользователя-прокси
Две переменные системы помогают отслеживать процесс входа пользователя-прокси:
-
proxy_user: Это значение равноNULL, если проксирование не используется. В противном случае оно указывает учетную запись пользователя-прокси. Например, если клиент выполняет аутентификацию через учетную запись прокси''@'', эта переменная устанавливается следующим образом:mysql>
SELECT @@proxy_user;+--------------+ | @@proxy_user | +--------------+ | ''@'' | +--------------+ external_user: Иногда плагин аутентификации может использовать внешнего пользователя для аутентификации на сервере MySQL. Например, при использовании нативной аутентификации Windows плагин, который выполняет аутентификацию с помощью API Windows, не нуждается в ID входа, переданном ему. Однако он все равно использует идентификатор пользователя Windows для аутентификации. Плагин может вернуть этот внешний идентификатор пользователя (или первые 512 байт UTF-8) на сервер с помощью read-only переменной сеансаexternal_user. Если плагин не устанавливает эту переменную, её значение равноNULL.
© 2025 Oracle
Licensed under the GPLv2 License.