Mi base de datos MySQL necesita dos usuarios: appuser y support.
Uno de los desarrolladores de aplicaciones insiste en que cree cuatro cuentas para estos usuarios:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Por mi vida, no puedo entender por qué cree que necesitamos esto. ¿Usar el comodín como anfitrión no se ocuparía del 'localhost'?
¿Algunas ideas?
(Usando MySQL 5.5 aquí)
Como @nos señaló en los comentarios de la respuesta actualmente aceptada a esta pregunta, la respuesta aceptada es incorrecta.
Sí, existe una diferencia entre usar
%
ylocalhost
para el host de la cuenta de usuario cuando se conecta a través de una conexión de socket en lugar de una conexión TCP / IP estándar.Un valor de host de
%
no incluyelocalhost
para sockets y, por lo tanto, debe especificarse si desea conectarse utilizando ese método.fuente
Probemos.
Conéctese como superusuario y luego:
SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | version | 10.0.23-MariaDB-0+deb8u1-log |
y entonces
USE mysql;
Preparar
Cree un usuario
foo
con contraseñabar
para realizar pruebas:CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Conectar
Para conectarse al Unix Domain Socket (es decir, la tubería de E / S que recibe el nombre de la entrada del sistema de archivos
/var/run/mysqld/mysqld.sock
o algo así), ejecútelo en la línea de comando (use la--protocol
opción para estar doblemente seguro)mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET
Se espera que lo anterior coincida con "el usuario proviene de localhost" pero ciertamente no con "el usuario proviene de 127.0.0.1".
Para conectarse al servidor desde "127.0.0.1" en su lugar, ejecute esto en la línea de comando
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Si lo omite
--protocol=TCP
, elmysql
comando seguirá intentando utilizar el socket de dominio Unix. También puede decir:mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
Los dos intentos de conexión en una línea:
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"
(la contraseña se establece en el entorno para que se pase al
mysql
proceso)Verificación en caso de duda
Para comprobar realmente si la conexión se realiza a través de un socket TCP / IP o un socket de dominio Unix
ps faux
lsof -n -p<yourpid>
.Verás algo como:
o
Entonces:
Caso 0: Host = '10 .10.10.10 '(prueba nula)
update user set host='10.10.10.10' where user='foo'; flush privileges;
Caso 1: Host = '%'
update user set host='%' where user='foo'; flush privileges;
Caso 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
El comportamiento varía y esto aparentemente depende de
skip-name-resolve
. Si se establece, hace que las líneas conlocalhost
se ignoren según el registro. Se puede ver lo siguiente en el registro de errores: "La entrada 'usuario' 'root @ localhost' ignorada en el modo --skip-name-resolve". . Esto significa que no hay conexión a través del socket de dominio Unix. Pero este no es el caso empíricamente.localhost
ahora significa SOLO el socket de dominio Unix, y ya no coincide con 127.0.0.1.skip-name-resolve
esta apagado:skip-name-resolve
Está encendido:Caso 3: Host = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
Caso 4: Anfitrión = ''
update user set host='' where user='foo';flush privileges;
(De acuerdo con MySQL 5.7: 6.2.4 Control de acceso, Etapa 1: Verificación de conexión , la cadena vacía '' también significa "cualquier host", pero se ordena después de '%' ) .
Caso 5: Host = '192.168.0.1' (prueba adicional)
('192.168.0.1' es una de las direcciones IP de mi máquina, cámbiela apropiadamente en su caso)
update user set host='192.168.0.1' where user='foo';flush privileges;
pero
mysql -pbar -ufoo -h192.168.0.1
: OK (!)Esto último porque en realidad proviene de una conexión TCP
192.168.0.1
, como lo revelalsof
:Caso de borde A: Host = '0.0.0.0'
update user set host='0.0.0.0' where user='foo';flush privileges;
Caso de borde B: Host = '255.255.255.255'
update user set host='255.255.255.255' where user='foo';flush privileges;
Caso de borde C: Host = '127.0.0.2'
(127.0.0.2 es una dirección de loopback perfectamente válida equivalente a 127.0.0.1 como se define en RFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
Curiosamente:
mysql -pbar -ufoo -h127.0.0.2
se conecta desde127.0.0.1
y es FALLOmysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
esta bienLimpiar
delete from user where user='foo';flush privileges;
Apéndice
Para ver qué hay realmente en la
mysql.user
tabla, que es una de las tablas de permisos, use: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;
esto da:
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin | +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
De manera similar para la mesa
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;
fuente
Si desea conectarse
user@'%'
desde localhost usemysql -h192.168.0.1 -uuser -p
.fuente
Vamos a proporcionar una respuesta ligeramente diferente a las proporcionadas hasta ahora.
Si tiene una fila para un usuario anónimo de localhost en su tabla de usuarios
''@'localhost'
, esto se tratará como más específico que su usuario con host con comodines'user'@'%'
. Por eso es necesario proporcionar también'user'@'localhost'
.Puede ver esto explicado con más detalle en la parte inferior de esta página .
fuente
El símbolo de porcentaje significa: cualquier host, incluidas las conexiones remotas y locales.
El localhost solo permite conexiones locales.
(para empezar, si no necesita conexiones remotas a su base de datos, puede deshacerse del usuario appuser @ '%' de inmediato)
Entonces, sí, se superponen, pero ...
... hay una razón para configurar ambos tipos de cuentas, esto se explica en los documentos de mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .
Si tiene un usuario anónimo en su localhost, puede detectarlo con:
select Host from mysql.user where User='' and Host='localhost';
y si solo crea el usuario appuser @ '%' (y no el appuser @ 'localhost'), cuando el usuario appuser mysql se conecta desde el host local, se usa la cuenta de usuario anónimo (tiene prioridad sobre su appuser @ '%' usuario).
Y la solución para esto es (como se puede adivinar) crear el appuser @ 'localhost' (que es más específico que el usuario anónimo del host local y se usará si su appuser se conecta desde el localhost).
fuente