Подтвердить что ты не робот

Использование% для хоста при создании пользователя MySQL

Моей базе данных MySQL нужны два пользователя: appuser и поддержка.
Один из разработчиков приложений настаивает на создании четырех учетных записей для этих пользователей:

[email protected]'%'
[email protected]'localhost'
[email protected]'%'
[email protected]'localhost'

В жизни я не могу понять, почему он думает, что нам это нужно. Не использовал бы подстановочный знак, поскольку хозяин заботится о "localhost"?

Любые идеи?

(здесь используется MySQL 5.5)

4b9b3361

Ответ 1

localhost особенный в MySQL, он означает соединение через сокет UNIX (или, по-моему, именованные каналы в Windows), в отличие от сокета TCP/IP. Использование % в качестве хоста не включает localhost, поэтому необходимо явно указать его.

Ответ 2

Как отметил @nos в комментариях принятого в настоящее время ответа на этот вопрос, принятый ответ неверен.

Да, существует разница между использованием % и localhost для хоста учетной записи пользователя при подключении через сокет-соединение вместо стандартного соединения TCP/IP.

Значение хоста % не включает localhost для сокетов и поэтому должно быть указано, если вы хотите подключиться с помощью этого метода.

Ответ 3

Если вы хотите подключиться к [email protected]'%' из localhost, используйте mysql -h192.168.0.1 -uuser -p.

Ответ 4

Собираюсь дать немного другой ответ на предоставленные до сих пор.

Если у вас есть строка для анонимного пользователя из localhost в вашей таблице пользователей ''@'localhost' то это будет рассматриваться как более конкретное, чем у вашего пользователя с хостом подстановочного знака 'user'@'%'. Вот почему необходимо также указать 'user'@'localhost'.

Вы можете увидеть это более подробно в нижней части этой страницы.

Ответ 5

Давай просто проверим.

Подключитесь как суперпользователь, а затем:

SHOW VARIABLES LIKE "%version%"; 
+-------------------------+------------------------------+ 
| Variable_name           | Value                        | 
+-------------------------+------------------------------+ 
| version                 | 10.0.23-MariaDB-0+deb8u1-log | 

а потом

USE mysql;

Настроить

Создание пользователя foo с паролем bar для тестирования:

CREATE USER [email protected]'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;

соединять

Чтобы подключиться к Unix Domain Socket (то есть /var/run/mysqld/mysqld.sock ввода-вывода, который назван записью файловой системы /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 Domain

  1. получить PID клиентского процесса mysql, изучив вывод команды ps faux
  2. запустите lsof -n -p<yourpid>.

Вы увидите что-то вроде:

mysql [PID] quux 3u IPv4 [code] 0t0 TCP 127.0.0.1:[port]->127.0.0.1:mysql (ESTABLISHED)

или же

mysql [PID] quux 3u unix [code] 0t0 [code] socket

Так:

Случай 0: Host = '10.10.10.10 '(нулевой тест)

update user set host='10.10.10.10' where user='foo'; flush privileges;
  • Подключите через разъем: FAILURE
  • Соединитесь с 127.0.0.1: СБОЙ

Случай 1: Хост = '%'

update user set host='%' where user='foo'; flush privileges;
  • Подключение с помощью розетки: ОК
  • Подключение от 127.0.0.1: ОК

Случай 2: Host = 'localhost'

update user set host='localhost' where user='foo';flush privileges;

Поведение варьируется, и это, очевидно, зависит от skip-name-resolve. Если установлено, строки с localhost будут игнорироваться в соответствии с журналом. В журнале ошибок можно увидеть следующее: "запись пользователя" root @localhost "игнорируется в режиме --skip -n ame-resolver". Это означает, что нет соединения через Unix Domain Socket. Но это не опытным путем. localhost теперь означает ТОЛЬКО Unix Domain Socket и больше не соответствует 127.0.0.1.

skip-name-resolve выключен:

  • Подключение с помощью розетки: ОК
  • Подключение от 127.0.0.1: ОК

skip-name-resolve on:

  • Подключение с помощью розетки: ОК
  • Соединитесь с 127.0.0.1: СБОЙ

Случай 3: Host = '127.0.0.1'

update user set host='127.0.0.1' where user='foo';flush privileges;
  • Подключите через разъем: FAILURE
  • Подключение от 127.0.0.1: ОК

Случай 4: Host = ''

update user set host='' where user='foo';flush privileges;
  • Подключение с помощью розетки: ОК
  • Подключение от 127.0.0.1: ОК

(Согласно 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;
  • Подключите через разъем: FAILURE
  • Соединитесь с 127.0.0.1: СБОЙ

но

  • Соединитесь, используя mysql -pbar -ufoo -h192.168.0.1: ОК (!)

Последнее, потому что на самом деле это TCP-соединение от 192.168.0.1, как показывает lsof:

TCP 192.168.0.1:37059->192.168.0.1:mysql (ESTABLISHED)

Пограничный вариант A: Host = '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges;
  • Подключите через разъем: FAILURE
  • Соединитесь с 127.0.0.1: СБОЙ

Пограничный вариант B: Host = '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges;
  • Подключите через разъем: FAILURE
  • Соединитесь с 127.0.0.1: СБОЙ

Пограничный случай 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;
  • Подключите через разъем: FAILURE
  • Соединитесь с 127.0.0.1: СБОЙ

Что интересно:

  • mysql -pbar -ufoo -h127.0.0.2 соединяется с 127.0.0.1 и является FAILURE
  • 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;

Ответ 6

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

Локальный хост допускает только локальные подключения.

(поэтому для начала, если вам не нужны удаленные подключения к вашей базе данных, вы можете сразу избавиться от пользователя 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).