Spec-Zone.ru › MySQL 5.7

6.2.5 Управление доступом, этап 1: Проверка подключения

При попытке подключения к серверу MySQL сервер принимает или отклоняет подключение на основе следующих условий:

  • Ваша личность и возможность её подтверждения путем предоставления соответствующих учетных данных.

  • Статус вашей учетной записи: заблокирована или разблокирована.

Сервер сначала проверяет учетные данные, а затем — состояние блокировки учетной записи. Неудача на любом этапе приводит к полному отказу в доступе. В противном случае сервер принимает подключение, переходит к этапу 2 и ожидает запросов.

Сервер выполняет проверку личности и учетных данных, используя столбцы в таблице user, принимая подключение только в случае выполнения этих условий:

  • Имя хоста клиента и имя пользователя должны совпадать со столбцами Host и User в какой-либо строке таблицы user. Правила допустимых значений Host и User см. в разделе 6.2.4 «Указание имён учётных записей».

  • Клиент предоставляет учетные данные, указанные в строке (например, пароль), как указано в столбце authentication_string. Учетные данные интерпретируются с помощью плагина аутентификации, указанного в столбце plugin.

  • В строке указано, что учетная запись разблокирована. Состояние блокировки хранится в столбце account_locked, значение которого должно быть 'N'. Блокировку учетных записей можно установить или изменить с помощью инструкции CREATE USER или ALTER USER.

Ваша личность определяется двумя параметрами:

  • Имя пользователя MySQL.

  • Хост клиента, с которого вы подключаетесь.

Если значение столбца User не пустое, имя пользователя в входящем подключении должно точно совпадать. Если значение User пустое, оно соответствует любому имени пользователя. Если строка таблицы user, соответствующая входящему подключению, имеет пустое имя пользователя, пользователь считается анонимным пользователем без имени, а не пользователем с указанным клиентом именем. Это означает, что пустое имя пользователя используется для дальнейшей проверки доступа на время подключения (то есть во время этапа 2).

Столбец authentication_string может быть пустым. Это не подстановочный символ и не означает, что подходит любой пароль. Это означает, что пользователь должен подключиться без указания пароля. Метод аутентификации, реализованный плагином, который аутентифицирует клиента, может или не может использовать пароль из столбца authentication_string. В этом случае возможно использование внешнего пароля для аутентификации на сервере MySQL.

Значения паролей, не являющиеся пустыми, хранящиеся в столбце authentication_string таблицы user, зашифрованы. MySQL не хранит пароли в открытом виде, чтобы их смог увидеть кто угодно. Вместо этого пароль, предоставленный пользователем, пытающимся подключиться, шифруется (с использованием метода хэширования паролей, реализованного плагином аутентификации учетных записей). Затем зашифрованный пароль используется во время процесса подключения для проверки правильности пароля. Это происходит без передачи зашифрованного пароля по каналу связи. См. раздел 6.2.1 «Имена пользователей и пароли учётных записей».

С точки зрения сервера MySQL, зашифрованный пароль является истинным паролем, поэтому вам не следует предоставлять к нему доступ никому. В частности, не предоставляйте пользователям, не являющимся администраторами, права чтения к таблицам в системе базы данных mysql.

В следующей таблице показано, как различные комбинации значений User и Host в таблице user применяются к входящим подключениям.

User Значение Host Значение Допустимые подключения
'fred' 'h1.example.net' fred, подключаясь с h1.example.net
'' 'h1.example.net' Любой пользователь, подключаясь с h1.example.net
'fred' '%' fred, подключаясь с любого хоста
'' '%' Любой пользователь, подключаясь с любого хоста
'fred' '%.example.net' fred, подключаясь с любого хоста в домене example.net
'fred' 'x.example.%' fred, подключаясь с x.example.net, x.example.com, x.example.edu, и так далее; это, вероятно, бесполезно
'fred' '198.51.100.177' fred, подключаясь с хоста с IP-адресом 198.51.100.177
'fred' '198.51.100.%' fred, подключаясь с любого хоста в подсети класса C 198.51.100
'fred' '198.51.100.0/255.255.255.0' Аналогично предыдущему примеру

Возможно, что имя хоста клиента и имя пользователя входящего подключения соответствуют более чем одной строке в таблице user. Представленный выше набор примеров демонстрирует это: несколько записей соответствуют подключению с h1.example.net пользователем fred.

Когда возможны несколько совпадений, сервер должен определить, какое из них использовать. Он решает эту проблему следующим образом:

  • При каждом чтении сервером таблицы user в память строки сортируются.

  • При попытке подключения клиентом сервер просматривает строки в отсортированном порядке.

  • Сервер использует первую строку, которая соответствует имени хоста и имени пользователя клиента.

Сервер использует правила сортировки, которые ставят строки с наиболее конкретными значениями Host на первое место:

  • Литеральные IP-адреса и имена хостов являются наиболее конкретными.

  • Конкретность литерального IP-адреса не зависит от наличия маски сети, поэтому 198.51.100.13 и 198.51.100.0/255.255.255.0 считаются одинаково конкретными.

  • Шаблон '%' означает “любой хост” и является наименее конкретным.

  • Пустая строка '' также означает “любой хост”, но сортируется после '%'.

Подключения, не являющиеся TCP (файлы сокетов, именованные каналы и общая память), обрабатываются как локальные подключения и соответствуют части хоста localhost, если такие учётные записи есть, или части хоста с подстановочными символами, которые соответствуют localhost в противном случае (например, local%, l%, %).

Строки с одинаковым значением Host сортируются с использованием наиболее конкретных значений User в первую очередь. Пустое значение User означает “любой пользователь” и является наименее конкретным, поэтому для строк с одинаковым значением Host пользователи без анонимного статуса сортируются перед анонимными пользователями.

Для строк с одинаково конкретными значениями Host и User порядок не определён.

Чтобы увидеть, как это работает, предположим, что таблица user выглядит следующим образом:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

Когда сервер считывает таблицу в память, он сортирует строки с использованием описанных правил. Результат после сортировки выглядит так:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

Когда клиент пытается подключиться, сервер просматривает отсортированные строки и использует первое найденное соответствие. Для подключения с localhost пользователем jeffrey две строки из таблицы соответствуют: та, у которой значения Host и User равны 'localhost' и '', и та, у которой значения равны '%' и 'jeffrey'. Строка 'localhost' появляется первой в отсортированном порядке, поэтому сервер использует её.

Вот еще один пример. Предположим, что таблица user выглядит следующим образом:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| h1.example.net |          | ...
+----------------+----------+-

Отсортированная таблица выглядит так:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| h1.example.net |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

Первая строка соответствует подключению любого пользователя с h1.example.net, а вторая строка соответствует подключению пользователя jeffrey с любого хоста.

Примечание

Распространено ошибочное мнение, что для заданного имени пользователя все строки, явно указывающие этого пользователя, используются в первую очередь, когда сервер пытается найти соответствие для подключения. Это не так. Предыдущий пример иллюстрирует это, где подключение с h1.example.net пользователем jeffrey соответствует не строке, содержащей 'jeffrey' в качестве значения столбца User, а строке без имени пользователя. В результате jeffrey аутентифицируется как анонимный пользователь, даже несмотря на то, что он указал имя пользователя при подключении.

Если вам удалось подключиться к серверу, но ваши привилегии не соответствуют ожиданиям, вероятно, вы аутентифицируетесь как другой пользователь. Чтобы узнать, под какой учетной записью сервер выполнил аутентификацию, используйте функцию CURRENT_USER(). (См. Раздел 12.15, «Функции получения информации».) Она возвращает значение в формате user_name@host_name, которое указывает на значения User и Host из соответствующей строки таблицы user. Предположим, что jeffrey подключается и выполняет следующий запрос:

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+

Результат, показанный здесь, указывает на то, что соответствующая строка таблицы user имела пустое значение в столбце User. Другими словами, сервер рассматривает jeffrey как анонимного пользователя.

Другой способ диагностики проблем с аутентификацией — распечатать таблицу user и вручную отсортировать ее, чтобы увидеть, где происходит первое соответствие.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/connection-access.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API