web-dev-qa-db-fra.com

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

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 Host. Je peux me connecter sans le -h paramè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> 

Éditer:

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 ~]# 
22
Just a learner

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();

SER () 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 ( Guide d'étude de certification MySQL 5.0

enter image description here

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, certaines entrées de la table utilisateur doivent 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, %.com Et %, Elles correspondent toutes à un client qui se connecte à partir de 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.1 Et myhost.example.com Trient avant les valeurs telles que %.example.com Qui contiennent des caractères de modèle. Les valeurs des modèles sont triées en fonction de leur spécificité. Par exemple, %.example.com Est 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é, seul mysql -u a A fonctionné. 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 a De se connecter via localhost parce que 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.user Qui autorise une 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 mysq -u a Fonctionne.

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 Host, user. 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 à 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 indique à la page 498 le paragraphe 6 dans ses puces indique 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).
27
RolandoMySQLDBA

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
5
atxdba

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
2
Craig Efrein

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=TCP pour chaque connexion. Vous pouvez cependant le définir dans my.cnf sur le serveur:

[client]
protocol=tcp
1
shgnInc