4.2.9 Управление доступом, этап 1: верификация подсоединения
4.2.9 Управление доступом, этап 1: верификация подсоединения
При попытке соединения с сервером MySQL он либо устанавливает соединение,
либо отказывает в нем - на основе данных о вашей личности и того, можете
ли вы подтвердить их соответствующим паролем. Если нет, сервер полностью
отказывает вам в доступе. В противном случае сервер устанавливает
соединение, затем переходит ко второму этапу и ожидает запросов.
Личность задается двумя порциями информации:
-
хостом, с которого вы подсоединяетесь
-
вашим именем пользователя MySQL
Проверка личности осуществляется с помощью трех полей контекста таблицы
user (Host, User и Password). Сервер устанавливает соединение только в том
случае, если находит в таблице user запись, в которой имя хоста и имя
пользователя совпадают с введенными вами, и вы указываете правильный
пароль.
Значения в полях контекста таблицы user могут задаваться следующим
образом:
Непустые значения в поле Password представляют собой зашифрованные пароли.
В MySQL пароли не хранятся в виде открытого текста, который может
прочитать кто угодно. Напротив, пароль, который вводится пользователем при
попытке подсоединения, шифруется (с помощью функции PASSWORD()). В
дальнейшем зашифрованный пароль используется клиентом/сервером в процессе
проверки его правильности (это делается вообще без пересылки пароля во
время подсоединения). Заметим, что с MySQL считает зашифрованный пароль
РЕАЛЬНЫМ паролем, поэтому не следует допускать к нему кого бы то ни было!
В частности, не разрешайте обычным пользователям доступ для чтения к
таблицам в базе mysql!
Примеры, приведенные ниже, показывают, каким входящим подсоединениям
соответствуют различные комбинации значений, указанных в полях Host и User
таблицы user:
Таблица 1
Значение в поле
Таблица 1
Значение в поле
Host | Значение в поле
Значение в поле
User | Подсоединения, которым соответствует запись
Подсоединения, которым соответствует запись
|
'thomas.loc.gov' | 'fred' | fred, подключающийся с thomas.loc.gov
|
'thomas.loc.gov' | '' | Любой пользователь, подключающийся с thomas.loc.gov
|
'%' | 'fred' | fred, подключающийся с любого хоста
|
'%' | '' | Любой пользователь, подключающийся с любого хоста
|
'%.loc.gov' | 'fred' | fred, подключающийся с любого хоста, принадлежащего домену loc.gov
|
'x.y.%' | 'fred' | fred, подключающийся с x.y.net, x.y.com,x.y.edu, и т.д. (это, по-видимому, бесполезный вариант)
|
'144.155.166.177' | 'fred' | fred, подключающийся с хоста, имеющего IP-адрес 144.155.166.177
|
'144.155.166.%' | 'fred' | fred, подключающийся с любого хоста в подсети 144.155.166 класса C
|
'144.155.166.0/255.255.255.0' | 'fred' | То же самое, что и в предыдущем примере
|
Поскольку в IP-адресе, указываемом в поле Host, могут использоваться
шаблонные символы (например '144.155.166.%' - данное значение
соответствует всем без исключения хостам указанной подсети), возникает
опасность, что кто-нибудь может попытаться воспользоваться этой
возможностью, указав имя хоста, например, как 144.155.166.somewhere.com.
Чтобы ``поставить заслон'' таким попыткам, в MySQL не разрешены имена
хостов, начинающиеся с цифр и точки. Другими словами, имени хоста типа
1.2.foo.com, никогда не найдется соответствия в столбцах Host таблиц
привилегий. IP-адресу с шаблонными символами может соответствовать только
IP-адрес.
Входящее подсоединение может совпадать с несколькими записями в таблице
user. Например, как было показано выше, подсоединению с thomas.loc.gov by
fred могут подходить разные записи. Каким образом сервер определяет, какую
из записей использовать, при совпадении с более чем одной из них? Для
этого после считывания таблицы user во время запуска сервер производит ее
сортировку, а затем, когда пользователь пытается установить соединение,
записи таблицы просматриваются в порядке их упорядочения,. Используется
первая подошедшая запись.
Сортировка таблицы user осуществляется следующим образом. Предположим,
таблица user имеет следующий вид:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
При считывании этой таблицы сервер упорядочивает записи, начиная с
наиболее конкретных значений в столбце Host ('%' в столбце Host означает
``любой хост'' и является наименее конкретным). Записи с одинаковым
значением в столбце Host упорядочиваются между собой начиная с наиболее
конкретных значений в столбце User (пустое значение в столбце User
означает ``любой пользователь'' и является наименее конкретным).
Окончательно отсортированная таблица user имеет следующий вид:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
При попытке подсоединения сервер просматривает отсортированные записи и
использует первую подходящую запись. Для подсоединения с localhost
пользователя jeffrey первыми подходящими записями являются записи со
значением 'localhost' в столбце Host. Из них запись с пустым значением
имени пользователя соответствует и имени подсоединяющегося хоста и имени
пользователя. (запись '%'/'jeffrey' тоже подошла бы, но она -- не первая
подходящая в этой таблице).
Рассмотрим другой пример. Пусть таблица user имеет вид:
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| % | jeffrey | ...
| thomas.loc.gov | | ...
+----------------+----------+-
Отсортированная таблица выглядит следующим образом:
+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| thomas.loc.gov | | ...
| % | jeffrey | ...
+----------------+----------+-
Для подсоединения пользователя jeffrey с thomas.loc.gov подходит первая
запись, в то время как для подсоединения jeffrey с whitehouse.gov -
вторая.
Существует распространенное заблуждение: иногда думают, что при поиске
записей для данного имени пользователя, соответствующих определенному
подсоединению, сервер первыми будет использовать записи, в которых этот
пользователь указан явно. Это абсолютно неверно, как и продемонстрировано
в предыдущем примере: для подсоединения пользователя jeffrey с
thomas.loc.gov первой подходящей записью является не запись, содержащая
значение 'jeffrey' в поле User, а запись, не содержащая имени пользователя
вовсе!
Если у вас возникают проблемы с подсоединением к серверу, распечатайте
таблицу user и отсортируйте ее вручную, чтобы увидеть, где
происходит первое совпадение.
| |