MySQL-Fehler: Zugriff für Benutzer 'a' @ 'localhost' verweigert (mit Passwort: YES)

22

Ich benutze das Root-Konto erstellt das Konto 'a'@'%'. Ich kann das Konto jedoch nicht verwenden, um eine Verbindung zum MySQL-Server herzustellen, wenn ich den Host-Parameter angebe. Ich kann erfolgreich ohne den -hParameter verbinden. Bitte beachten Sie das Transkript unten. Ich hoffe, jemand kann mir helfen, es zu erklären. Vielen Dank.

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> 

Bearbeiten:

Ja, MySQL lauscht auf 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 ~]# 
Nur ein Anfänger
quelle
1
Ich bin kein Spezialist für MySQL, aber ich habe dieses Problem ein paar Mal gesehen, ich weiß nicht, was der Grund war, die Lösung war explizit die Definition des Hosts zusätzlich 'a'@'%'. Der erste Datensatz war also 'a'@'%'und der zweite ist 'a'@'localhost'.
com
kannst du bitte das selbe mit niedrigerer mysql version testen ..?
Abdul Manaf
benutze Cpanel Login Details Um eine Verbindung herzustellen.
Abu Fahim
In meinem Fall wurden standardmäßig drei anonyme Konten erstellt. Durch Löschen dieser Konten konnte das Problem behoben werden
Joaquín L. Robles,

Antworten:

26

Hier ist eine einfache Methode, um herauszufinden, wie MySQL eine erfolgreiche Authentifizierung durchführt.

Bitte führen Sie diese Abfrage aus:

SELECT USER(),CURRENT_USER();

USER () gibt an , wie Sie versucht haben, sich in mysqld zu authentifizieren

CURRENT_USER () gibt an , wie Sie sich von mysqld authentifizieren durften

Manchmal USER()und CURRENT_USER()sind anders. Das liegt daran, dass die MySQL-Authentifizierung einem bestimmten Protokoll folgt.

Laut MySQL 5.0-Leitfaden für Zertifizierungsstudien

Bildbeschreibung hier eingeben

Auf den Seiten 486.487 wird Folgendes zum MySQL-Authentifizierungsalgorithmus angegeben:

Es gibt zwei Stufen der Clientzugriffskontrolle:

In der ersten Phase versucht ein Client, eine Verbindung herzustellen, und der Server akzeptiert die Verbindung oder lehnt sie ab. Damit der Versuch erfolgreich ist, muss ein Eintrag in der Benutzertabelle mit dem Host, von dem aus der Client eine Verbindung herstellt, dem Benutzernamen und dem Kennwort übereinstimmen.

In der zweiten Phase (die nur erfolgt, wenn ein Client bereits eine erfolgreiche Verbindung hergestellt hat) überprüft der Server jede vom Client empfangene Abfrage, um festzustellen, ob der Client über ausreichende Berechtigungen zur Ausführung verfügt.

Der Server vergleicht einen Client mit Einträgen in den Grant-Tabellen basierend auf dem Host, von dem aus der Client eine Verbindung herstellt, und dem vom Client bereitgestellten Benutzer. Es ist jedoch möglich, dass mehrere Datensätze übereinstimmen:

Hostwerte in Grant-Tabellen können angegeben werden, da Muster Platzhalterwerte enthalten. Wenn eine Berechtigungstabelle enthält Einträge aus myhost.example.com, %.example.com, %.com, und %, alle von ihnen übereinstimmen einen Kunden, der von verbindet myhost.example.com.

Muster sind für die Benutzerwerte in Berechtigungstabelleneinträgen nicht zulässig, aber ein Benutzername kann als leere Zeichenfolge angegeben werden, um einen anonymen Benutzer anzugeben. Die leere Zeichenfolge stimmt mit einem beliebigen Benutzernamen überein und fungiert somit effektiv als Platzhalter.

Wenn der Host- und der Benutzerwert in mehr als einem Benutzertabellendatensatz mit einem Client übereinstimmen, muss der Server entscheiden, welcher verwendet werden soll. Dazu werden die Datensätze mit den spezifischsten Host- und Benutzerspaltenwerten zuerst sortiert und der übereinstimmende Datensatz ausgewählt, der zuerst in der sortierten Liste auftritt. Die Sortierung erfolgt wie folgt:

In der Spalte Host, wörtliche Werte wie localhost, 127.0.0.1und myhost.example.comsortieren voraus Werte wie %.example.com die Musterzeichen in ihnen haben. Musterwerte werden nach ihrer Spezifität sortiert. Zum Beispiel %.example.comist spezifischer als %.com, was spezifischer als ist %.

In der Spalte Benutzer werden nicht leere Benutzernamen vor leeren Benutzernamen sortiert. Das heißt, nicht anonyme Benutzer werden vor anonymen Benutzern sortiert.

Der Server führt diese Sortierung beim Start durch. Es liest die Grant-Tabellen in den Speicher, sortiert sie und verwendet die speicherinternen Kopien für die Zugriffssteuerung.

In dieser Beschreibung müssen Sie sich keine Gedanken über die Reihenfolge der mysql.user-Tabellen machen, da eine speicherinterne Kopie der Grant-Tabellen vorhanden ist, die wie oben beschrieben sortiert ist.

In Bezug auf, wie Sie sich angemeldet haben, hat nur mysql -u afunktioniert. Gehen Sie zurück und melden Sie sich erneut an und führen Sie diese Befehle aus

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

Stelle sicher das

  • Jeder Benutzer hat ein Passwort.
  • Es gibt keine anonymen Benutzer (wenn der Benutzer leer ist)

Dies ist nur eine Vermutung, aber ich vermute, eine mysql -u aVerbindung über localhost herzustellen, da bei nicht angegebenem Verbindungsprotokoll standardmäßig eine Verbindung über die Socket-Datei hergestellt wird. Möglicherweise ist ein Eintrag vorhanden mysql.user, der eine anonyme localhost-Verbindung zulässt.

Führen Sie diese Abfrage aus:

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

Wenn Sie eine Zeile ohne Kennwort zurückerhalten, wird vollständig erklärt, warum dies mysq -u afunktioniert.

UPDATE 2012-01-19 11:12 EDT

Craig Efrein hat eine interessante Frage aufgeworfen: Wenn zwei identische Benutzernamen in der Tabelle mysql.user existieren, einer mit und einer ohne Kennwort, bedeutet dies, dass MySQL die Authentifizierung verweigert, wenn kein Kennwort verwendet wird?

Diese Frage beschäftigt sich hervorragend mit MySQL-Benutzerauthentifizierung.

Bitte beachten Sie, dass der Primärschlüssel von mysql.user host, user ist. Es gibt keine anderen Indizes. Dies ermöglicht das mehrfache Auftreten eines Benutzernamens. Jedes Vorkommen kann ein anderes Passwort oder kein Passwort haben. Auf diese Weise kann sich der Benutzer 'dbuser' lokal anmelden (dbuser @ localhost), ohne ein Kennwort zu verwenden, und derselbe Benutzer kann sich von einem anderen Server innerhalb eines bestimmten Netzwerkblocks (dbuser@'10.1.2.20 ') mit einem Kennwort wie' pass1 'anmelden und dieser Benutzer muss sich anmelden Remote von überall (dbuser @ '%') mit einem Remote-Passwort wie 'pass2'.

In Anbetracht des von MySQL verwendeten Authentifizierungsalgorithmus gibt es keine Einschränkungen für Benutzer mit oder ohne Kennwort.

Aus diesem Grund wird in den Aufzählungspunkten des MySQL 5.0 Certification Study Guide in Absatz 6 erläutert, wie der Authentifizierungsprozess bereinigt werden kann:

Unter Unix wird MySQL mit einem mysql_secure_installation-Skript ausgeliefert, das verschiedene hilfreiche sicherheitsrelevante Vorgänge für Ihre Installation ausführen kann. Das Skript verfügt über die folgenden Funktionen:

  • Legen Sie ein Passwort für die Root-Accounts fest
  • Entfernen Sie alle remote zugänglichen Root-Konten.
  • Entfernen Sie die anonymen Benutzerkonten. Dies verbessert die Sicherheit, da verhindert wird, dass sich jemand von einem Remote-Host aus als Root mit dem MySQL-Server verbindet. Das Ergebnis ist, dass sich jeder, der eine Verbindung als Root herstellen möchte, zuerst auf dem Server-Host anmelden muss, was eine zusätzliche Barriere gegen Angriffe darstellt.
  • Entfernen Sie die Testdatenbank (Wenn Sie die anonymen Konten entfernen, möchten Sie möglicherweise auch die Testdatenbank entfernen, auf die sie Zugriff haben).
RolandoMySQLDBA
quelle
Ja, ich habe versucht, es wird eine Zeile ohne Passwort zurückgegeben. Vielen Dank für Ihre hervorragende Erklärung und die Empfehlung des MySQL-Zertifizierungsbuchs.
Nur ein Anfänger
2
Rolando, wenn zwei identische Benutzernamen in der mysql.user-Tabelle existieren, einer mit und einer ohne Passwort, bedeutet das, dass MySQL die Authentifizierung verweigert, wenn kein Passwort verwendet wird?
Craig Efrein
@Craig - Ihre Frage ist sehr bemerkenswert. Ich werde es in meine Antwort übernehmen und dort ansprechen.
RolandoMySQLDBA
Vielen Dank für die ausführliche Antwort, in meinem Fall hatte ich irgendwie anonyme Benutzer konfiguriert.
SoWeLie
@RolandoMySQLDBA, Sind alle Informationen im Leitfaden für Zertifizierungsstudien bereits im MySQL-Online-Handbuch enthalten?
Pacerier
5

Der Platzhalter '%' des Hosts stimmt nicht mit 'localhost' überein. Standardmäßig versucht der MySQL-Client, eine Verbindung über einen Socket und nicht über TCP herzustellen (normalerweise an Orten wie /var/lib/mysql/mysql.sock).

Sie können Ihre Berechtigung entweder in 'a' @ 'localhost' ändern oder den Client zwingen, über den TCP-Stack wie folgt zu arbeiten:

mysql -u a -p --protocol=TCP
atxdba
quelle
Ich habe es versucht, aber immer noch kein Glück.
Nur ein Anfänger
Wie konfiguriere my.cnfich diese Option, damit ich diesen Parameter nicht mehr benötige?
ShgnInc
1
Das tust du nicht. Wenn Sie keinen -h-Hostnamen angeben, wird "localhost" angenommen, was bedeutet, dass nach einem Socket gesucht wird, nicht nach einem TCP-Port ohne Protokollflag. Sie können ein Shell-Aliase einrichten, wenn Sie es leid sind, alle Argumente auszutippen.
atxdba
2

Haben Sie überprüft, ob MySQL tatsächlich 3306 abhört? Führen Sie ein netstat -tlpn aus und geben Sie die Ergebnisse an. Wenn Sie 3306 nicht sehen, ist es wahrscheinlich nicht.

In my.cnf sollten Sie sicherstellen , dass --skip-networking auskommentiert ist

[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
quelle
Ich habe auch dasselbe gemacht, wie in der Frage gefragt. und auch getan, was Sie in Ihrer Antwort sagen, aber es gibt immer noch das gleiche Problem.
Abdul Manaf
Können Sie die Ergebnisse der folgenden Abfrage bereitstellen: select user, host from mysql.user;
Craig Efrein
Ja, MySQL lauscht auf Port 3306. Siehe meine Bearbeitung.
Nur ein Anfänger
Sie können auch mysql -u user -p -h 127.0.0.1 ausprobieren. Wenn das funktioniert, dann glaube ich, dass es MySQL ist, das nicht weiß, wie man localhost auflöst. Ein Eintrag für localhost, der auf 127.0.0.1 in Ihrer Datei / etc / hosts verweist, wird das beheben.
Craig Efrein
Haben Sie Flush Privileges ausgeführt?
Craig Efrein
1

Wie in @atxdba beschrieben, müssen Sie zum Herstellen einer Verbindung zum mysql-Daemon von einem Remotestandort aus über TCP eine Verbindung herstellen, der nicht über einen Socket verbunden ist.

Hierzu sollten Sie die --protocol=TCPpro Verbindung angeben . Sie können es jedoch my.cnfauf dem Server einrichten :

[client]
protocol=tcp
shgnInc
quelle