Моей базе данных MySQL нужны два пользователя: appuser и support.
Один из разработчиков приложения настаивает, чтобы я создал четыре учетных записи для этих пользователей:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Да хоть убей, я не могу понять, почему он думает, что нам это нужно. Разве использование подстановочного знака в качестве хоста не позаботится о «локальном хосте»?
Любые идеи?
(Здесь используется MySQL 5.5)
Как отметил @nos в комментариях к принятому в настоящее время ответу на этот вопрос, принятый ответ неверен.
Да, есть разница между использованием
%
иlocalhost
для хоста учетной записи пользователя при подключении через сокет вместо стандартного TCP / IP-подключения.Значение хоста
%
не включаетlocalhost
сокеты и, следовательно, должно быть указано, если вы хотите подключиться с помощью этого метода.источник
Давайте просто протестируем.
Подключитесь как суперпользователь, а затем:
SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | version | 10.0.23-MariaDB-0+deb8u1-log |
а потом
USE mysql;
Настроить
Создайте пользователя
foo
с паролемbar
для тестирования:CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Подключить
Чтобы подключиться к сокету домена Unix (то есть каналу ввода-вывода, который назван записью файловой системы
/var/run/mysqld/mysqld.sock
или что-то в этом роде), запустите это в командной строке (используйте--protocol
параметр, чтобы быть уверенным вдвойне)mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET
Можно ожидать, что указанное выше соответствует «пользователь исходит из локального хоста», но уж точно не «пользователь приходит с 127.0.0.1».
Чтобы вместо этого подключиться к серверу из «127.0.0.1», запустите это в командной строке.
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Если вы не укажете
--protocol=TCP
,mysql
команда все равно будет пытаться использовать сокет домена Unix. Вы также можете сказать:mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
Две попытки подключения в одной строке:
export MYSQL_PWD=bar; \ mysql -ufoo --protocol=SOCKET --execute="SELECT 1"; \ mysql -ufoo --bind-address=127.0.0.1 --host=127.0.0.1 --execute="SELECT 1"
(пароль устанавливается в среде так, что он передается
mysql
процессу)Проверка в случае сомнения
Чтобы действительно проверить, идет ли соединение через сокет TCP / IP или сокет домена Unix
ps faux
lsof -n -p<yourpid>
.Вы увидите что-то вроде:
или
Так:
Случай 0: Хост = '10 .10.10.10 '(нулевой тест)
update user set host='10.10.10.10' where user='foo'; flush privileges;
Случай 1: Хост = '%'
update user set host='%' where user='foo'; flush privileges;
Случай 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
Поведение меняется, и это, по-видимому, зависит от
skip-name-resolve
. Если установлено, то строки сlocalhost
игнорируются в соответствии с журналом. В журнале ошибок можно увидеть следующее: «запись пользователя 'root @ localhost' игнорируется в режиме --skip-name-resolve». . Это означает отсутствие подключения через сокет домена Unix. Но эмпирически это не так.localhost
теперь означает ТОЛЬКО сокет домена Unix и больше не соответствует 127.0.0.1.skip-name-resolve
выключен:skip-name-resolve
горит:Случай 3: Host = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
Случай 4: Хост = ''
update user set host='' where user='foo';flush privileges;
(Согласно MySQL 5.7: 6.2.4 Контроль доступа, Этап 1: Проверка соединения , пустая строка "также означает" любой хост ", но сортируется после"% ". )
Случай 5: Host = '192.168.0.1' (дополнительный тест)
('192.168.0.1' - один из IP-адресов моей машины, измените его соответствующим образом в вашем случае)
update user set host='192.168.0.1' where user='foo';flush privileges;
но
mysql -pbar -ufoo -h192.168.0.1
: ОК (!)Последнее, потому что на самом деле это TCP-соединение
192.168.0.1
, как показаноlsof
:Пограничный случай A: Host = '0.0.0.0'
update user set host='0.0.0.0' where user='foo';flush privileges;
Пограничный случай B: Host = '255.255.255.255'
update user set host='255.255.255.255' where user='foo';flush privileges;
Пограничный случай C: Host = '127.0.0.2'
(127.0.0.2 - вполне допустимый адрес обратной связи, эквивалентный 127.0.0.1, как определено в RFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
Интересно:
mysql -pbar -ufoo -h127.0.0.2
подключается127.0.0.1
и ОТКАЗmysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
в порядкеОчистка
delete from user where user='foo';flush privileges;
Дополнение
Чтобы увидеть, что на самом деле находится в
mysql.user
таблице, которая является одной из таблиц разрешений, используйте:SELECT SUBSTR(password,1,6) as password, user, host, Super_priv AS su, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) AS funcs, CONCAT(Repl_slave_priv, Repl_client_priv) AS replic, CONCAT(Shutdown_priv, Process_priv, File_priv, Show_db_priv, Reload_priv, Create_user_priv) AS admin FROM user ORDER BY user, host;
это дает:
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin | +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
Аналогично для таблицы
mysql.db
:SELECT host,db,user, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv) AS funcs FROM db ORDER BY user, db, host;
источник
Если вы хотите подключиться к
user@'%'
локальному хосту, используйтеmysql -h192.168.0.1 -uuser -p
.источник
Собираюсь дать несколько отличный ответ от тех, что были предоставлены до сих пор.
Если у вас есть строка для анонимного пользователя с локального хоста в вашей таблице пользователей,
''@'localhost'
тогда это будет рассматриваться как более конкретное, чем ваш пользователь с подстановочным знаком host'user'@'%'
. Вот почему необходимо также предоставлять'user'@'localhost'
.Вы можете увидеть это более подробно в нижней части этой страницы .
источник
Символ процента означает: любой хост, включая удаленные и локальные соединения.
Localhost разрешает только локальные соединения.
(так что для начала, если вам не нужны удаленные подключения к базе данных, вы можете сразу избавиться от пользователя appuser @ '%')
Так что да, они пересекаются, но ...
... есть причина для установки обоих типов учетных записей, это объясняется в документации mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .
Если у вас есть анонимный пользователь на вашем локальном хосте, который вы можете определить с помощью:
select Host from mysql.user where User='' and Host='localhost';
и если вы просто создаете пользователя appuser @ '%' (а вы не appuser @ 'localhost'), тогда, когда пользователь appuser mysql подключается с локального хоста, используется анонимная учетная запись пользователя (она имеет приоритет над вашим appuser @ Пользователь%).
И исправление для этого (как можно догадаться) - создать appuser @ 'localhost' (который более конкретен, чем анонимный пользователь локального хоста и будет использоваться, если ваш appuser подключается с localhost).
источник