Error de MySQL: acceso denegado para el usuario 'a' @ 'localhost' (usando la contraseña: SÍ)


22

Yo uso la cuenta raíz creó la cuenta 'a'@'%'. Pero no puedo usar la cuenta para conectarme al servidor MySQL cuando especifico el parámetro del host. Puedo conectarme exitosamente sin el -hparámetro. Por favor, vea la transcripción a continuación. Espero que alguien pueda ayudarme a explicarlo. Gracias.

mysql> grant all on *.* to 'a'@'%' identified by a;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'a' at line 1
mysql> grant all on *.* to 'a'@'%' identified by 'a';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for 'a'@'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for a@%                                                                                            |
+-----------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'a'@'%' IDENTIFIED BY PASSWORD '*667F407DE7C6AD07358FA38DAED7828A72014B4E' |
+-----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> exit
Bye

[root@localhost ~]# mysql -h localhost -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -h 127.0.0.1 -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -u a -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'a'@'localhost' (using password: YES)
[root@localhost ~]# mysql -u a
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.5.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql> status
--------------
mysql  Ver 14.14 Distrib 5.5.17, for Linux (x86_64) using readline 5.1

Connection id:      20
Current database:   
Current user:       a@localhost
SSL:            Not in use
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.5.17 MySQL Community Server (GPL)
Protocol version:   10
Connection:     Localhost via UNIX socket
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:        /var/lib/mysql/mysql.sock
Uptime:         15 days 15 hours 20 min 18 sec

Threads: 1  Questions: 40  Slow queries: 0  Opens: 41  Flush tables: 1  Open tables: 4  Queries per second avg: 0.000
--------------

mysql> 

Editar:

Sí, MySQL está escuchando en el puerto 3306.

[root@localhost ~]# nmap localhost

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-01-18 07:35 CST
Interesting ports on localhost.localdomain (127.0.0.1):
Not shown: 1674 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
111/tcp  open  rpcbind
631/tcp  open  ipp
840/tcp  open  unknown
3306/tcp open  mysql

Nmap finished: 1 IP address (1 host up) scanned in 0.064 seconds
[root@localhost ~]# 

1
No soy un especialista en MySql, pero vi este problema varias veces, no sé cuál fue el motivo, además de la solución explícita de la definición de host 'a'@'%'. entonces, el primer registro fue 'a'@'%', y el segundo es 'a'@'localhost'.
com

¿puedes probar lo mismo con una versión mysql inferior?
Abdul Manaf

use los detalles de inicio de sesión de Cpanel para conectarse.
Abu Fahim

En mi caso, tenía tres cuentas anónimas creadas de forma predeterminada, eliminarlas resolvería este problema
Joaquín L. Robles

Respuestas:


26

Aquí hay un método rápido y sucio para verificar cómo MySQL realiza una autenticación exitosa.

Por favor ejecute esta consulta:

SELECT USER(),CURRENT_USER();

USER () informa cómo intentó autenticarse en mysqld

CURRENT_USER () informa cómo mysqld le permitió autenticarse

A veces, USER()y CURRENT_USER()son diferentes. Esto se debe a que la autenticación mysql sigue un protocolo específico.

De acuerdo con la Guía de estudio de certificación MySQL 5.0

ingrese la descripción de la imagen aquí

las páginas 486,487 establecen lo siguiente en el algoritmo de autenticación de mysql:

Hay dos etapas de control de acceso de clientes:

En la primera etapa, un cliente intenta conectarse y el servidor acepta o rechaza la conexión. Para que el intento tenga éxito, alguna entrada en la tabla de usuarios debe coincidir con el host desde el cual se conecta el cliente, el nombre de usuario y la contraseña.

En la segunda etapa (que ocurre solo si un cliente ya se ha conectado correctamente), el servidor verifica cada consulta que recibe del cliente para ver si el cliente tiene suficientes privilegios para ejecutarlo.

El servidor compara un cliente con las entradas en las tablas de concesión en función del host desde el que se conecta el cliente y el usuario que proporciona el cliente. Sin embargo, es posible que más de un registro coincida:

Los valores de host en las tablas de concesión se pueden especificar ya que los patrones contienen valores comodín. Si una tabla de permisos contiene entradas de myhost.example.com, %.example.com, %.com, y %, todos ellos coinciden con un cliente que se conecta desde myhost.example.com.

No se permiten patrones para los valores de usuario en las entradas de la tabla de concesión, pero se puede asignar un nombre de usuario como una cadena vacía para especificar un usuario anónimo. La cadena vacía coincide con cualquier nombre de usuario y, por lo tanto, actúa efectivamente como comodín.

Cuando los valores de Host y Usuario en más de un registro de tabla de usuario coinciden con un cliente, el servidor debe decidir cuál usar. Para ello, clasifica primero los registros con los valores de columna Host y Usuario más específicos y elige el registro coincidente que aparece primero en la lista ordenada. La clasificación se realiza de la siguiente manera:

En la columna Host, los valores literales como localhost, 127.0.0.1y se myhost.example.comordenan antes que los valores como %.example.com ese tienen caracteres de patrón. Los valores del patrón se ordenan de acuerdo con su especificidad. Por ejemplo, %.example.comes más específico que %.com, que es más específico que %.

En la columna Usuario, los nombres de usuario que no están en blanco se ordenan antes que los nombres de usuario en blanco. Es decir, los usuarios no anónimos se clasifican por delante de los usuarios anónimos.

El servidor realiza esta clasificación cuando se inicia. Lee las tablas de concesión en la memoria, las ordena y usa las copias en memoria para el control de acceso.

A partir de esta descripción, no necesita preocuparse por el orden de las tablas mysql.user ya que hay una copia en memoria de las tablas de concesión que está ordenada como se mencionó anteriormente.

Con respecto a cómo inició sesión, solo mysql -u afuncionó. Regrese e inicie sesión nuevamente y ejecute estos comandos

SELECT USER(),CURRENT_USER();
SELECT user,host,password FROM mysql.user;

Asegúrate de eso

  • Cada usuario tiene una contraseña.
  • no hay usuarios anónimos (cuando el usuario está en blanco)

Esto es solo una suposición, pero sospecho que se mysql -u aconecta a través de localhost porque cuando no se especifica el protocolo de conexión, el valor predeterminado es conectarse a través del archivo socket. Puede existir una entrada mysql.userque permita la conexión de host local anónimo.

Ejecute esta consulta:

SELECT user,host,password FROM mysql.user WHERE user='' AND host='localhost';

Si regresa una fila sin contraseña, eso explica completamente por qué mysq -u afunciona.

ACTUALIZACIÓN 2012-01-19 11:12 EDT

Craig Efrein planteó una pregunta interesante: si existen dos nombres de usuario idénticos en la tabla mysql.user, uno con una contraseña y otro sin ella, ¿eso significa que MySQL niega la autenticación cuando no se usa una contraseña?

Esta pregunta es un excelente aviso sobre la autenticación de usuarios de MySQL.

Tenga en cuenta que la clave principal de mysql.user es host, user. No hay otros índices. Esto permite múltiples ocurrencias de un nombre de usuario. Cada aparición puede tener una contraseña diferente o no tener contraseña. Esto permite al usuario 'dbuser' iniciar sesión localmente (dbuser @ localhost) sin contraseña y el mismo usuario inicia sesión desde otro servidor dentro de un determinado bloque de red (dbuser@'10.1.2.20 ') con una contraseña como' pass1 'y ese usuario iniciar sesión remotamente desde cualquier lugar (dbuser @ '%') con una contraseña remota como 'pass2'.

Dado el algoritmo de autenticación que utiliza MySQL, no hay restricciones impuestas a los usuarios con la presencia o ausencia de una contraseña.

Esta es la razón por la cual la Guía de estudio de certificación de MySQL 5.0 dice en la página 498, el párrafo 6 en sus viñetas, muestra cómo limpiar el proceso de autenticación:

En Unix, MySQL viene con un script mysql_secure_installation que puede realizar varias operaciones útiles relacionadas con la seguridad en su instalación. El script tiene las siguientes capacidades:

  • Establecer una contraseña para las cuentas raíz
  • Elimine cualquier cuenta raíz accesible de forma remota.
  • Eliminar las cuentas de usuario anónimo. Esto mejora la seguridad porque evita la posibilidad de que alguien se conecte al servidor MySQL como root desde un host remoto. El resultado es que cualquier persona que quiera conectarse como root primero debe poder iniciar sesión en el host del servidor, lo que proporciona una barrera adicional contra el ataque.
  • Elimine la base de datos de prueba (si elimina las cuentas anónimas, es posible que también desee eliminar la base de datos de prueba a la que tienen acceso).

Sí, lo intenté, devuelve una fila sin contraseña. Gracias por su excelente explicación y recomendó el libro de certificación MySQL.
Solo aprendiz

2
Rolando, si existen dos nombres de usuario idénticos en la tabla mysql.user, uno con contraseña y otro sin él, ¿eso significa que MySQL niega la autenticación cuando no usa una contraseña?
Craig Efrein

@ Craig: tu pregunta es muy notable. Lo transferiré a mi respuesta y lo abordaré allí.
RolandoMySQLDBA

Gracias por la respuesta detallada, en mi caso tenía usuarios anónimos configurados de alguna manera.
SoWeLie

@RolandoMySQLDBA, ¿Puede toda la información de la guía de estudio de certificación ya se puede encontrar en el manual de MySQL en línea?
Pacerier

5

El comodín de host '%' no coincide con 'localhost'. Por defecto, el cliente mysql intentará conectarse a través de un socket en lugar de tcp (generalmente en algún lugar como /var/lib/mysql/mysql.sock).

Puede cambiar su concesión a 'a' @ 'localhost' o forzar al cliente a operar sobre la pila TCP como:

mysql -u a -p --protocol=TCP

Lo intenté, pero aún no tuve suerte.
Solo aprendiz

¿Cómo configurar esta opción my.cnfpara no necesitar más este parámetro?
shgnInc

1
Usted no Si no especifica un nombre de host -h, asume "localhost", lo que significa que está buscando un socket, no un puerto TCP sin el indicador de protocolo. Puede configurar un alias de shell si está cansado de escribir todos los argumentos.
atxdba

2

¿Ha verificado para asegurarse de que MySQL realmente está escuchando en 3306? Ejecute un netstat -tlpn y proporcione los resultados. Si no ve 3306, entonces probablemente no lo sea.

En my.cnf debe verificar que --skip-networking esté comentado

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
language        = /usr/share/mysql/English
bind-address    = 65.55.55.2
# skip-networking

También hice lo mismo que se hizo en la pregunta. y también hice lo que dices en tu respuesta pero todavía hay el mismo problema.
Abdul Manaf

¿Puede proporcionar los resultados de la siguiente consulta: seleccione usuario, host de mysql.user;
Craig Efrein

Sí, MySQL está escuchando en el puerto 3306. Vea mi edición.
Solo aprendiz

También es posible que desee probar mysql -u user -p -h 127.0.0.1. Si eso funciona, entonces creo que es mysql que no sabe cómo resolver localhost. Una entrada para localhost que apunta a 127.0.0.1 en su archivo / etc / hosts lo resolverá.
Craig Efrein

¿Ejecutó Flush Privileges?
Craig Efrein

1

Como lo describió @atxdba, para conectar el demonio mysql desde el control remoto que no se conecta a través del socket, por lo que debe conectarse desde el control remoto a través de TCP.

Para esto, debe especificar el --protocol=TCPpor cada conexión. Aunque, puede configurarlo en my.cnfel servidor:

[client]
protocol=tcp
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.