Erreur MySQL: accès refusé à l'utilisateur 'a' @ 'localhost' (en utilisant le mot de passe: OUI)

22

J'utilise le compte root créé le compte 'a'@'%'. Mais je ne peux pas utiliser le compte pour me connecter au serveur MySQL lorsque je spécifie le paramètre hôte. Je peux me connecter avec succès sans le -hparamètre. Veuillez consulter la transcription ci-dessous. J'espère que quelqu'un pourra m'aider à l'expliquer. Merci.

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> 

Modifier:

Oui, MySQL écoute sur le port 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 ~]# 
Juste un apprenant
la source
1
Je ne suis pas un spécialiste de MySql, mais j'ai vu ce problème plusieurs fois, je ne sais pas quelle était la raison, la solution était explicitement la définition d'hôte en plus 'a'@'%'. donc, le premier record a été 'a'@'%', et le second est 'a'@'localhost'.
com
pouvez-vous s'il vous plaît tester la même chose avec la version inférieure de mysql ..?
Abdul Manaf
utilisez les détails de connexion Cpanel pour vous connecter.
Abu Fahim
Dans mon cas, j'avais trois comptes annonymous créés par défaut, les supprimer résoudrait ce problème
Joaquín L. Robles

Réponses:

26

Voici une méthode simple et rapide pour vérifier comment MySQL effectue une authentification réussie.

Veuillez exécuter cette requête:

SELECT USER(),CURRENT_USER();

USER () indique comment vous avez tenté de vous authentifier dans mysqld

CURRENT_USER () indique comment vous avez été autorisé à vous authentifier par mysqld

Parfois, USER()et CURRENT_USER()sont différents. C'est parce que l'authentification mysql suit un protocole spécifique.

Selon le guide d'étude de certification MySQL 5.0

entrez la description de l'image ici

les pages 486,487 indiquent ce qui suit sur l'algorithme d'authentification de mysql:

Il existe deux étapes de contrôle d'accès client:

Dans la première étape, un client tente de se connecter et le serveur accepte ou rejette la connexion. Pour que la tentative réussisse, une entrée de la table utilisateur doit correspondre à l'hôte à partir duquel le client se connecte, le nom d'utilisateur et le mot de passe.

Dans la deuxième étape (qui se produit uniquement si un client s'est déjà connecté avec succès), le serveur vérifie chaque requête qu'il reçoit du client pour voir si le client dispose de privilèges suffisants pour l'exécuter.

Le serveur compare un client à des entrées dans les tables d'octroi en fonction de l'hôte à partir duquel le client se connecte et de l'utilisateur fourni par le client. Cependant, il est possible que plusieurs enregistrements correspondent:

Les valeurs d'hôte dans les tables de droits peuvent être spécifiées car les modèles contiennent des valeurs génériques. Si une table de subvention contient des entrées de myhost.example.com, %.example.com, %.comet %, tous correspondent à un client qui se connecte depuis myhost.example.com.

Les modèles ne sont pas autorisés pour les valeurs utilisateur dans les entrées de la table des droits, mais un nom d'utilisateur peut être donné sous la forme d'une chaîne vide pour spécifier un utilisateur anonyme. La chaîne vide correspond à n'importe quel nom d'utilisateur et agit donc efficacement comme un caractère générique.

Lorsque les valeurs Host et User dans plusieurs enregistrements de table utilisateur correspondent à un client, le serveur doit décider lequel utiliser. Pour ce faire, il trie d'abord les enregistrements avec les valeurs de colonne Hôte et Utilisateur les plus spécifiques, et en choisissant l'enregistrement correspondant qui apparaît en premier dans la liste triée, le tri s'effectue comme suit:

Dans la colonne hôte, les valeurs littérales telles que localhost, 127.0.0.1et myhost.example.comtrient avant les valeurs telles que celles %.example.com qui contiennent des caractères de modèle. Les valeurs des motifs sont triées en fonction de leur spécificité. Par exemple, %.example.comest plus spécifique que %.com, qui est plus spécifique que %.

Dans la colonne Utilisateur, les noms d'utilisateur non vides sont triés avant les noms d'utilisateur vides. Autrement dit, les utilisateurs non anonymes trient avant les utilisateurs anonymes.

Le serveur effectue ce tri au démarrage. Il lit les tables d'octroi en mémoire, les trie et utilise les copies en mémoire pour le contrôle d'accès.

À partir de cette description, vous n'avez pas à vous soucier de l'ordre des tables mysql.user car il existe une copie en mémoire des tables d'octroi qui est triée comme mentionné précédemment.

En ce qui concerne la façon dont vous vous êtes connecté, cela n'a mysql -u afonctionné. Revenez en arrière et connectez-vous à nouveau et exécutez ces commandes

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

Sois sûr que

  • chaque utilisateur a un mot de passe.
  • il n'y a pas d'utilisateurs anonymes (lorsque l'utilisateur est vide)

C'est juste une supposition, mais je soupçonne mysql -u ade me connecter via localhost car lorsque le protocole de connexion n'est pas spécifié, la valeur par défaut est de se connecter via le fichier socket. Il peut exister une entrée dans mysql.userlaquelle autoriser la connexion localhost anonyme.

Exécutez cette requête:

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

Si vous récupérez une ligne sans mot de passe, cela explique pleinement pourquoi cela mysq -u afonctionne.

MISE À JOUR 2012-01-19 11:12 EDT

Craig Efrein a soulevé une question intéressante: si deux noms d'utilisateur identiques existent dans la table mysql.user, l'un avec un mot de passe et l'autre sans, cela signifie-t-il que MySQL refuse l'authentification lorsqu'il n'utilise pas de mot de passe?

Cette question est une excellente information sur l'authentification des utilisateurs MySQL.

Veuillez noter que la clé primaire de mysql.user est hôte, utilisateur. Il n'y a pas d'autres index. Cela permet plusieurs occurrences d'un nom d'utilisateur. Chaque occurrence peut avoir un mot de passe différent ou aucun mot de passe. Cela permet à l'utilisateur «dbuser» de se connecter localement (dbuser @ localhost) sans mot de passe et avec la même connexion utilisateur depuis un autre serveur au sein d'un netblock donné (dbuser@'10.1.2.20 ») avec un mot de passe comme« pass1 »et cet utilisateur de se connecter à distance depuis n'importe où (dbuser @ '%') avec un mot de passe distant comme 'pass2'.

Compte tenu de l'algorithme d'authentification utilisé par MySQL, aucune restriction n'est imposée aux utilisateurs avec la présence ou l'absence d'un mot de passe.

C'est pourquoi le Guide d'étude de certification MySQL 5.0 dit à la page 498 Le paragraphe 6 de ses puces explique comment nettoyer le processus d'authentification:

Sous Unix, MySQL est fourni avec un script d'installation mysql_secure_installation qui peut effectuer plusieurs opérations de sécurité utiles sur votre installation. Le script a les capacités suivantes:

  • Définissez un mot de passe pour les comptes root
  • Supprimez tous les comptes root accessibles à distance.
  • Supprimez les comptes d'utilisateurs anonymes. Cela améliore la sécurité car il empêche toute personne de se connecter au serveur MySQL en tant que root à partir d'un hôte distant. Le résultat est que toute personne souhaitant se connecter en tant que root doit d'abord pouvoir se connecter sur l'hôte du serveur, ce qui constitue une barrière supplémentaire contre les attaques.
  • Supprimez la base de données de test (si vous supprimez les comptes anonymes, vous souhaiterez peut-être également supprimer la base de données de test à laquelle ils ont accès).
RolandoMySQLDBA
la source
Oui, j'ai essayé, il retourne une ligne sans mot de passe. Merci pour votre excellente explication et recommandé le livre de certification MySQL.
Juste un apprenant
2
Rolando, si deux noms d'utilisateur identiques existent dans la table mysql.user, l'un avec un mot de passe et l'autre sans, cela signifie-t-il que MySQL refuse l'authentification lorsqu'il n'utilise pas de mot de passe?
Craig Efrein
@Craig - Votre question est très intéressante. Je vais le transférer dans ma réponse et y répondre.
RolandoMySQLDBA
Merci pour la réponse détaillée, dans mon cas, j'avais configuré des utilisateurs anonymes.
SoWeLie
@RolandoMySQLDBA, Toutes les informations du guide d'étude de certification peuvent-elles déjà être trouvées dans le manuel en ligne MySQL?
Pacerier
5

Le caractère générique de l'hôte '%' ne correspond pas à 'localhost'. Par défaut, le client mysql essaiera de se connecter via une socket plutôt que tcp (généralement un endroit comme /var/lib/mysql/mysql.sock).

Vous pouvez soit changer votre allocation en 'a' @ 'localhost', soit forcer le client à opérer sur la pile TCP comme:

mysql -u a -p --protocol=TCP
atxdba
la source
J'ai essayé, mais toujours pas de chance.
Juste un apprenant
Comment configurer cette option my.cnfpour ne plus avoir besoin de ce paramètre?
shgnInc
1
Non. Si vous ne spécifiez pas de nom d'hôte -h, cela suppose que "localhost" signifie qu'il recherche un socket, pas un port TCP sans l'indicateur de protocole. Vous pouvez configurer un aliase shell si vous en avez assez de taper tous les arguments.
atxdba
2

Avez-vous vérifié que MySQL écoute réellement sur 3306? Exécutez un netstat -tlpn et fournissez les résultats. Si vous ne voyez pas 3306, ce n'est probablement pas le cas.

Dans my.cnf, vous devez vérifier que --skip-networking est mis en commentaire

[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
Craig Efrein
la source
J'ai également fait la même chose que celle posée dans la question. et a également fait ce que vous dites dans votre réponse, mais il y a toujours le même problème.
Abdul Manaf
Pouvez-vous fournir les résultats de la requête suivante: sélectionnez l'utilisateur, l'hôte de mysql.user;
Craig Efrein
Oui, MySQL écoute sur le port 3306. Voir ma modification.
Juste un apprenant
Vous pouvez également essayer mysql -u user -p -h 127.0.0.1. Si cela fonctionne, je crois que son mysql ne sait pas comment résoudre localhost. Une entrée pour localhost qui pointe vers 127.0.0.1 dans votre fichier / etc / hosts résoudra cela.
Craig Efrein
Avez-vous exécuté Flush Privileges?
Craig Efrein
1

Comme @atxdba l'a décrit, pour connecter le démon mysql à distance qui ne se connecte pas via socket, vous devez donc vous connecter à distance via TCP.

Pour cela, vous devez spécifier le --protocol=TCPpour chaque connexion. Cependant, vous pouvez le configurer my.cnfsur le serveur:

[client]
protocol=tcp
shgnInc
la source