web-dev-qa-db-ja.com

MySQLエラー:ユーザー 'a' @ 'localhost'のアクセスが拒否されました(パスワードを使用:YES)

私はアカウント'a'@'%'を作成したrootアカウントを使用します。しかし、Hostパラメーターを指定すると、アカウントを使用してMySQLサーバーに接続できません。 -hパラメータがなくても正常に接続できます。以下の筆記録をご覧ください。私は誰かがそれを説明するのを手伝ってくれることを願っています。ありがとう。

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> 

編集:

はい、MySQLはポート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

MySQLが正常に認証を実行する方法を確認するための簡単な方法です。

このクエリを実行してください:

_SELECT USER(),CURRENT_USER();
_

SER() は、mysqldで認証を試みた方法を報告します

CURRENT_USER() は、mysqldによる認証が許可された方法を報告します

USER()CURRENT_USER()が異なる場合があります。これは、mysql認証が特定のプロトコルに従っているためです。

MySQL 5.0 Certification Study Guide によると==

enter image description here

486、487ページには、mysqlの認証アルゴリズムに関する次の記述があります。

クライアントアクセス制御には2つの段階があります。

最初の段階では、クライアントが接続を試み、サーバーが接続を受け入れるか拒否します。成功するには、ユーザーテーブルの一部のエントリが、クライアントの接続元のホスト、ユーザー名、およびパスワードと一致する必要があります。

2番目の段階(クライアントがすでに正常に接続している場合にのみ発生します)では、サーバーはクライアントから受け取ったすべてのクエリをチェックして、クライアントにそれを実行するための十分な特権があるかどうかを確認します。

サーバーは、クライアントの接続元のホストとクライアントが提供するユーザーに基づいて、クライアントを許可テーブルのエントリと照合します。ただし、複数のレコードが一致する可能性があります。

パターンにワイルドカード値が含まれているため、付与テーブルのホスト値を指定できます。付与テーブルに_myhost.example.com_、_%.example.com_、_%.com_、および_%_のエントリが含まれている場合、それらすべてが_myhost.example.com_から接続するクライアントと一致します。

付与テーブルエントリのユーザー値にはパターンを使用できませんが、匿名ユーザーを指定するために、ユーザー名を空の文字列として指定できます。空の文字列は任意のユーザー名に一致するため、事実上ワイルドカードとして機能します。

複数のユーザーテーブルレコードのHost値とUser値がクライアントと一致する場合、サーバーはどちらを使用するかを決定する必要があります。これは、最も具体的なHostおよびUser列の値を持つレコードを最初にソートし、ソートされたリストで最初に出現する一致するレコードを選択することにより、次のように行われます。

ホスト列では、localhost、_127.0.0.1_、_myhost.example.com_などのリテラル値が、パターン文字を含む_%.example.com_などの値よりも前にソートされます。パターン値は、具体性に応じて並べ替えられます。たとえば、_%.example.com_は_%.com_より具体的であり、_%_より具体的です。

[ユーザー]列では、空白でないユーザー名が空白のユーザー名よりも先に並べ替えられます。つまり、非匿名ユーザーは、匿名ユーザーより先にソートされます。

サーバーは、起動時にこの並べ替えを実行します。付与テーブルをメモリに読み込み、それらを並べ替え、メモリ内コピーをアクセス制御に使用します。

前述のようにソートされた付与テーブルのメモリ内コピーがあるため、この説明から、mysql.userテーブルの順序を気にする必要はありません。

ログイン方法に関しては、_mysql -u a_のみが機能しました。戻って再度ログインし、これらのコマンドを実行します

_SELECT USER(),CURRENT_USER();
SELECT user,Host,password FROM mysql.user;
_

確認してください

  • すべてのユーザーはパスワードを持っています。
  • 匿名ユーザーがいない(ユーザーが空白の場合)

これは推測にすぎませんが、接続プロトコルが指定されていない場合、デフォルトではソケットファイル経由で接続するため、localhost経由での接続は_mysql -u a_だと思います。 _mysql.user_に、匿名のローカルホスト接続を許可するエントリが存在する可能性があります。

このクエリを実行します。

_SELECT user,Host,password FROM mysql.user WHERE user='' AND Host='localhost';
_

パスワードなしで行を取得した場合、それが_mysq -u a_が機能する理由を完全に説明しています。

UPDATE 2012-01-19 11:12 EDT

Craig Efrein 興味深い質問がありました:mysql.userテーブルに2つの同一のユーザー名が存在する場合、1つはパスワードあり、もう1つはパスワードなしで、MySQLはパスワードを使用しないと認証を拒否しますか?

この質問は、MySQLのユーザー認証に関する優れた説明です。

Mysql.userの主キーはHost、userであることに注意してください。他のインデックスはありません。これにより、複数のユーザー名を使用できます。出現ごとに異なるパスワードを設定することも、パスワードを設定しないこともできます。これにより、ユーザー 'dbuser'はパスワードを使用せずにローカルでログイン(dbuser @ localhost)でき、同じユーザーは特定のネットブロック(dbuser@'10.1.2.20 ')内の別のサーバーから' pass1 'のようなパスワードでログインし、そのユーザーがログインできます。 「pass2」などのリモートパスワードを使用して、どこからでもリモートで(dbuser @ '%')。

MySQLが使用する認証アルゴリズムを考えると、パスワードの有無にかかわらず、ユーザーに制限はありません。

これが MySQL 5.0認定調査ガイドの498ページの段落6 にある箇条書きで、認証プロセスをクリーンアップする方法を説明している理由です:

Unixの場合、MySQLにはmysql_secure_installationスクリプトが付属しており、インストール時にセキュリティ関連のいくつかの便利な操作を実行できます。スクリプトには次の機能があります。

  • Rootアカウントのパスワードを設定する
  • リモートからアクセス可能なルートアカウントを削除します。
  • 匿名ユーザーアカウントを削除します。これにより、リモートホストからMySQLサーバーにrootとして接続する可能性がなくなるため、セキュリティが向上します。その結果、rootとして接続するユーザーは、最初にサーバーホストにログインできる必要があります。これにより、攻撃に対する追加の障壁が提供されます。
  • テストデータベースを削除します(匿名アカウントを削除する場合、アクセス権のあるテストデータベースも削除することをお勧めします)。
27
RolandoMySQLDBA

「%」ホストのワイルドカードが「localhost」と一致しません。デフォルトでは、mysqlクライアントはtcpではなくソケットを介して接続しようとします(通常、/ var/lib/mysql/mysql.sockなどの場所)。

許可を 'a' @ 'localhost'に変更するか、クライアントにTCPスタックのような操作を強制することができます。

mysql -u a -p --protocol=TCP
5
atxdba

MySQLが実際に3306でリッスンしていることを確認しましたか? netstat -tlpnを実行し、結果を提供します。 3306が表示されない場合は、おそらく表示されません。

my.cnfでは、-skip-networkingがコメント化されていることを確認する必要があります

[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

@atxdbaで説明されているように、ソケットを介して接続しないmysqlデーモンをリモートから接続するには、TCPを介してリモートから接続する必要があります。

そのためには、接続ごとに--protocol=TCPを指定する必要があります。ただし、サーバーのmy.cnfで設定できます。

[client]
protocol=tcp
1
shgnInc