MySQL 오류 : 사용자 'a'@ 'localhost'에 대한 액세스가 거부되었습니다 (암호 사용 : YES)


22

루트 계정을 사용하여 계정을 만들었습니다 'a'@'%'. 그러나 호스트 매개 변수를 지정할 때 계정을 사용하여 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 ~]# 

1
나는 MySql의 전문가는 아니지만이 문제를 몇 번 보았습니다. 이유가 무엇인지 모르겠습니다. 솔루션은에 대한 호스트 정의뿐만 아니라 명시 적이었습니다 'a'@'%'. 첫 번째 레코드는 'a'@'%'이고 두 번째 레코드는 입니다 'a'@'localhost'.
com

더 낮은 mysql 버전으로 동일한 것을 테스트 할 수 있습니까?
Abdul Manaf

Cpanel Login Details를 사용하여 연결합니다.
Abu Fahim

내 경우에는 내가 그들에게이 문제를 해결할 삭제, 기본적으로 만들어 세 annonymous 계정을했다
호아킨 L. 블스

답변:


26

MySQL이 성공적인 인증을 수행하는 방법을 확인하는 빠르고 더러운 방법이 있습니다.

이 쿼리를 실행하십시오 :

SELECT USER(),CURRENT_USER();

USER () 는 mysqld에서 인증을 시도한 방법을보고합니다

CURRENT_USER () 는 mysqld에 의해 인증 된 방법을보고합니다

때때로, USER()그리고 CURRENT_USER()다릅니다. mysql 인증이 특정 프로토콜을 따르기 때문입니다.

MySQL 5.0 인증 연구 가이드 에 따르면

여기에 이미지 설명을 입력하십시오

페이지 486,487은 mysql의 인증 알고리즘에 대해 다음을 설명합니다.

클라이언트 액세스 제어에는 두 단계가 있습니다.

첫 번째 단계에서 클라이언트는 연결을 시도하고 서버는 연결을 수락하거나 거부합니다. 성공하려면 user 테이블의 일부 항목이 클라이언트가 연결되는 호스트, 사용자 이름 및 비밀번호와 일치해야합니다.

두 번째 단계 (클라이언트가 이미 성공적으로 연결 한 경우에만 발생)에서 서버는 클라이언트로부터 수신 한 모든 쿼리를 검사하여 클라이언트가이를 실행할 수있는 권한이 있는지 확인합니다.

서버는 클라이언트가 연결되는 호스트와 클라이언트가 제공 한 사용자를 기반으로 권한 부여 테이블의 항목과 클라이언트를 일치시킵니다. 그러나 둘 이상의 레코드가 일치 할 수 있습니다.

권한 부여 테이블의 호스트 값은 패턴에 와일드 카드 값이 포함되어 지정 될 수 있습니다. 보조금 테이블 항목에서 포함되어있는 경우 myhost.example.com, %.example.com, %.com,과 %, 그들 모두에서 연결하는 클라이언트를 일치 myhost.example.com.

권한 부여 테이블 항목의 사용자 값에는 패턴이 허용되지 않지만 익명 사용자를 지정하기 위해 사용자 이름이 빈 문자열로 제공 될 수 있습니다. 빈 문자열은 모든 사용자 이름과 일치하므로 효과적으로 와일드 카드 역할을합니다.

둘 이상의 사용자 테이블 레코드의 호스트 및 사용자 값이 클라이언트와 일치하면 서버는 사용할 것을 결정해야합니다. 가장 구체적인 호스트 및 사용자 열 값이있는 레코드를 먼저 정렬하고 정렬 된 목록에서 처음 발생하는 일치하는 레코드를 선택하면 정렬이 다음과 같이 수행됩니다.

호스트 열에서 리터럴 값 (예 : localhost , 127.0.0.1myhost.example.com종류에 앞서 같은 값의 %.example.com 그들의 패턴 문자가 있습니다. 패턴 값은 특정 정도에 따라 정렬됩니다. 예를 들어 %.example.com보다 %.com보다 구체적 %입니다. 보다보다 구체적 입니다.

사용자 열에서 비어 있지 않은 사용자 이름은 빈 사용자 이름보다 먼저 정렬됩니다. 즉, 비 익명 사용자가 익명 사용자보다 우선합니다.

서버는 시작할 때이 정렬을 수행합니다. 권한 부여 테이블을 메모리로 읽고 정렬 한 후 액세스 제어를 위해 메모리 내 사본을 사용합니다.

이 설명에서는 이전에 언급 한대로 정렬 된 권한 부여 테이블의 메모리 사본이 있으므로 mysql.user 테이블의 순서에 대해 걱정할 필요가 없습니다.

로그인 방법과 관련하여 mysql -u a 작동했습니다. 돌아가서 다시 로그인하여 다음 명령을 실행하십시오.

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

확인하십시오

  • 모든 사용자는 비밀번호를 가지고 있습니다.
  • 익명 사용자가 없습니다 (사용자가 비어있는 경우)

이것은 단지 추측 일이지만 mysql -u a연결 프로토콜을 지정하지 않으면 기본값은 소켓 파일을 통해 연결하기 때문에 localhost를 통해 연결하는 것으로 의심 됩니다. 에 항목이있을 수 있습니다mysql.user익명 로컬 호스트 연결을 허용 .

이 쿼리를 실행하십시오.

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

암호가없는 행으로 돌아 가면 왜 mysq -u a작동 하는지 완전히 설명 합니다.

업데이트 2012-01-19 11:12 EDT

크레이그 에프 레인 (Craig Efrein) 은 mysql.user 테이블에 두 개의 동일한 사용자 이름이 존재하고 하나는 암호가 있고 다른 하나는없는 경우 MySQL이 암호를 사용하지 않을 때 인증을 거부한다는 의미입니까?

이 질문은 MySQL 사용자 인증에 대한 훌륭한 글입니다.

mysql.user의 기본 키는 host, user입니다. 다른 색인이 없습니다. 이것은 여러 번의 사용자 이름을 허용합니다. 각 항목마다 다른 암호를 사용하거나 암호를 사용하지 않을 수 있습니다. 이를 통해 사용자 'dbuser'는 비밀번호가없고 'pass1'과 같은 비밀번호를 사용하여 지정된 넷 블록 (dbuser@'10.1.2.20 ') 내 다른 서버에서 동일한 사용자 로그인을 사용하여 로컬로 로그인 (dbuser @ localhost)하고 해당 사용자는 로그인 할 수 있습니다. 'pass2'와 같은 원격 비밀번호를 사용하여 어디에서나 (dbuser @ '%') 원격으로

MySQL이 사용하는 인증 알고리즘을 고려할 때 암호가 있거나없는 사용자에게는 제한이 없습니다.

이것이 바로 MySQL 5.0 Certification Study Guide의 6 절 에있는 요점에서 인증 프로세스를 정리하는 방법을 설명하는 이유입니다.

Unix의 경우 MySQL에는 설치시 유용한 보안 관련 작업을 수행 할 수있는 mysql_secure_installation 스크립트가 제공됩니다. 스크립트에는 다음 기능이 있습니다.

  • 루트 계정의 비밀번호 설정
  • 원격으로 액세스 가능한 루트 계정을 제거하십시오.
  • 익명 사용자 계정을 제거하십시오. 이는 원격 호스트에서 루트로 MySQL 서버에 연결할 수 없도록하므로 보안을 향상시킵니다. 결과적으로 루트로 연결하려는 사람은 먼저 서버 호스트에 로그인 할 수 있어야하므로 공격에 대한 추가 장벽이 제공됩니다.
  • 테스트 데이터베이스를 제거하십시오 (익명 계정을 제거하는 경우 액세스 권한이있는 테스트 데이터베이스를 제거 할 수도 있습니다).

예, 시도했지만 암호없이 행을 반환합니다. 훌륭한 설명에 감사하고 MySQL 인증 책을 추천했습니다.
단지 학습자

2
Rolando가 mysql.user 테이블에 두 개의 동일한 사용자 이름이 존재하는 경우 (하나는 암호가 있고 다른 하나는없는 경우), 이는 암호를 사용하지 않을 때 MySQL이 인증을 거부한다는 것을 의미합니까?
Craig Efrein

@Craig-귀하의 질문은 매우 주목할 만합니다. 나는 그것을 내 대답으로 옮기고 거기에서 다룰 것입니다.
RolandoMySQLDBA

자세한 경우 답변을 주셔서 감사합니다. 제 경우에는 익명의 사용자가 어떻게 든 구성했습니다.
SoWeLie

@RolandoMySQLDBA, 인증 연구 가이드의 모든 정보가 이미 MySQL 온라인 매뉴얼에 나와 있습니까?
Pacerier

5

'%'호스트 와일드 카드가 'localhost'와 일치하지 않습니다. 기본적으로 mysql 클라이언트는 tcp (보통 /var/lib/mysql/mysql.sock와 같은 곳) 대신 소켓을 통해 연결을 시도합니다.

부여를 'a'@ 'localhost'로 변경하거나 클라이언트가 다음과 같이 TCP 스택을 통해 작동하도록 할 수 있습니다.

mysql -u a -p --protocol=TCP

나는 시도했지만 여전히 운이 없다.
단지 학습자

my.cnf이 매개 변수가 더 이상 필요하지 않도록 이 옵션을 구성하는 방법은 무엇입니까?
shgnInc

1
당신은하지 않습니다. -h 호스트 이름을 지정하지 않으면 "localhost"로 가정하여 프로토콜 플래그가없는 TCP 포트가 아닌 소켓을 찾고 있음을 의미합니다. 모든 인수를 입력하는 데 지치면 쉘 별명을 설정할 수 있습니다.
atxdba

2

MySQL이 실제로 3306에서 청취 중인지 확인 했습니까? netstat -tlpn을 실행하고 결과를 제공하십시오. 3306이 보이지 않으면 아마도 그렇지 않을 것입니다.

에서 의 my.cnf 당신은 --skip-네트워킹 주석 확인해야합니다

[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

나는 또한 질문에서 요구 한 것과 똑같이했다. 그리고 당신이 당신의 대답에서 말한 것을했지만 여전히 같은 문제가 있습니다.
Abdul Manaf

다음 쿼리의 결과를 제공 할 수 있습니다. select user, host from mysql.user;
Craig Efrein

예, MySQL은 포트 3306에서 수신 대기합니다. 편집 내용을 참조하십시오.
단지 학습자

mysql -u user -p -h 127.0.0.1을 사용해 볼 수도 있습니다. 그것이 작동하면 로컬 호스트를 해결하는 방법을 모르는 mysql을 믿습니다. / etc / hosts 파일에서 127.0.0.1을 가리키는 localhost 항목이이를 해결합니다.
Craig Efrein

Flush Privileges를 실행 했습니까?
Craig Efrein

1

@atxdba가 설명했듯이 소켓을 통해 연결되지 않은 원격에서 mysql 데몬을 연결하려면 TCP를 통해 원격에서 연결해야합니다.

이를 위해 --protocol=TCP각 연결마다를 지정해야 합니다. 그러나 my.cnf서버 에서 설정할 수 있습니다 .

[client]
protocol=tcp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.