6.2.4 액세스 제어 1 단계 : 연결 확인
사용자가 MySQL 서버에 연결하려고하면 서버는 사용자 ID와 올바른 암호를 지정하여 사용자가 자신의 ID를 검증 할 수 있을지 여부에 따라 연결을 허용할지 거부합니다. 수없는 경우, 서버는 액세스를 완전히 거부합니다. 그렇지 않으면 서버는 연결을 받아 2 단계로 진행 요청을 기다립니다.
사용자 ID는 두 부분의 정보에 근거합니다.
연결하는 클라이언트 호스트
MySQL 사용자 이름
ID 확인은 user
테이블의 3 개의 스코프 컬럼 ( Host
, User
, Password
)를 사용하여 수행됩니다. 서버는 일부 user
테이블 행의 Host
와 User
컬럼이 클라이언트 호스트 이름과 사용자 이름과 일치 행에 지정된 암호가 클라이언트에서 제공된 경우에만 연결을 허용합니다. 허용되는 Host
와 User
값에 대한 규칙은 섹션 6.2.3 "계정 이름 지정" 에 있습니다.
User
컬럼 값이 공백이 아니면, 입 접속 사용자 이름은 정확히 일치해야합니다. User
값이 공백이면 이것은 모든 사용자 이름과 일치합니다. 입 접속과 일치하는 user
테이블 행의 사용자 이름이 공백 인 경우 사용자는 클라이언트가 실제로 지정한 이름을 가진 사용자가 아니라 이름없는 익명 사용자로 간주됩니다. 즉, 연결 기간 동안 (즉 2 단계에서) 앞으로의 모든 액세스 확인에 공백 사용자 이름이 사용되는 것을 의미합니다.
Password
컬럼은 공백에 있습니다. 이것은 와일드 카드가 아닌 모든 비밀번호가 일치한다는 의미는 아닙니다. 이것은 사용자가 암호를 지정하지 않고 연결해야한다는 것을 의미합니다. 서버가 플러그인을 사용하여 클라이언트를 인증하는 경우 플러그인이 구현하는 인증 방법 Password
컬럼의 암호가 사용되는 경우도 그렇지 않은 경우도 있습니다. 이 경우, MySQL 서버에 인증 할 때 외부 암호도 사용 될 수 있습니다.
user
테이블에서 공백이 아닌 Password
값은 암호화 된 암호를 나타냅니다. MySQL은 모든 사용자가 볼 수있는 일반 텍스트 암호를 저장하지 않습니다. 대신 연결하려고 한 사용자가 입력 한 암호 ( PASSWORD()
함수를 사용하여) 암호화됩니다. 그 후, 암호화 된 암호는 연결 과정에서 암호가 올바른지 확인하는 데 사용됩니다. 이것은 암호화 된 암호가 연결을 통해 교환되지 않고 실행됩니다. 섹션 6.3.1 "사용자 이름과 암호" 를 참조하십시오.
MySQL에서 보면 암호화 된 암호가 실제 암호이기 때문에 암호화 된 암호에 대한 액세스 권한을 모든 사용자에게 부여하지 않도록하십시오. 특히 관리자가 아닌 사용자에게 mysql
데이터베이스의 테이블에 대한 읽기 액세스 권한을 부여하지 마십시오.
다음 표에서는 user
테이블 엔트리의 Host
값 및 User
값의 다양한 조합이 입 접속에 어떻게 적용되는지를 보여줍니다.
Host 값 | User 값 | 허용되는 연결 |
---|---|---|
'thomas.loc.gov' | 'fred' | thomas.loc.gov 에서 접속하는 fred |
'thomas.loc.gov' | '' | thomas.loc.gov 에서 접속하는 모든 사용자 |
'%' | 'fred' | 모든 호스트로부터 연결하는 fred |
'%' | '' | 모든 호스트로부터 연결하는 사용자 |
'%.loc.gov' | 'fred' | loc.gov 도메인의 모든 호스트에서 연결하는 fred |
'xy%' | 'fred' | xynet , xycom , xyedu 등에서 접속하는 fred . 아마 도움이되지 않습니다 |
'144.155.166.177' | 'fred' | IP 주소 144.155.166.177 호스트에서 연결하는 fred |
'144.155.166.%' | 'fred' | 144.155.166 클래스 C 서브넷의 모든 호스트로부터 연결하는 fred |
'144.155.166.0/255.255.255.0' | 'fred' | 앞의 예와 같은 |
입 접속 클라이언트 호스트 이름과 사용자 이름이 user
테이블의 여러 행과 일치 할 수도 있습니다. 이것은 이전의 일련의 예로 나타나고 있으며, 표시된 여러 항목이 fred
에 따르면 thomas.loc.gov
에서 연결과 일치합니다.
여러 일치가 가능한 경우 서버를 사용할지 여부를 결정해야합니다. 이 문제는 다음과 같이 해결됩니다.
서버가
user
테이블을 메모리에 읽을 때 줄을 매번 정렬합니다.클라이언트가 연결을 시도하면 서버는 행을 정렬 순서로 참조합니다.
서버는 클라이언트 호스트 이름과 사용자 이름이 일치하는 첫 번째 행을 사용합니다.
서버는 구체성이 가장 높은 Host
값이 먼저되도록 행을 나란히 정렬 규칙을 사용합니다. 리터럴의 호스트 이름과 IP 주소는 구체성이 가장 높습니다. (리터럴 IP 주소의 구체성은 IP 주소가 넷 마스크를 가질 지 여부에 따라 영향을받지 않는다 때문에 192.168.1.13
과 192.168.1.0/255.255.255.0
의 구체성은 동일한 것으로 간주됩니다.) 패턴 '%'
는 "모든 호스트"를 의미하기 때문에 구체성은 가장 낮습니다. 빈 문자열 ''
도 "모든 호스트"를 의미하지만, '%'
뒤에 정렬됩니다. 동일한 Host
값을 가진 행은 가장 구체적인 User
값이 먼저되도록 정렬됩니다 (빈 User
값은 "모든 사용자"를 의미하고 구체성이 가장 낮아집니다). Host
와 User
값의 구체성이 동일한 행은 순서는 확정입니다.
user
테이블이 다음의 내용이라고 가정하여 이것이 어떻게 작용 하는지를 설명합니다.
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
서버가 테이블을 메모리에 읽을 때 서버는 앞에서 언급 한 규칙을 사용하여 행을 정렬합니다. 정렬 후 결과는 다음과 같습니다.
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
클라이언트가 연결을 시도하면 서버는 정렬 된 행을 참조하고 발견 된 최초의 일치를 사용합니다. jeffrey
에 따르면 localhost
에서 연결의 경우 테이블의 두 행이 일치, 즉 Host
와 User
값이 'localhost'
와 ''
인 것과 값이 '%'
및 'jeffrey'
인 것이 일치 합니다. 정렬 순서에서 'localhost'
행이 먼저되기 때문에 서버는이 줄을 사용합니다.
다음 다른 예입니다. user
테이블이 다음과 같이되어 있다고 가정합니다.
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
정렬 된 테이블은 다음과 같이됩니다.
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
jeffrey
에 따르면 thomas.loc.gov
에서의 연결은 최초의 행과 일치하지만 jeffrey
에 의한 임의의 호스트로부터의 접속은 두 번째 행에 일치합니다.
일반적인 오해로 특정 사용자 이름에 대해 서버가 연결에 대한 일치를 발견하려고했을 때, 사용자의 이름을 명시 적으로 지정하는 모든 행이 먼저 사용된다는 인식이 있습니다. 이것은 올바르지 않습니다. 이것은 위의 예에 설명되어 jeffrey
에 따르면 thomas.loc.gov
에서의 연결은 User
컬럼 값으로 'jeffrey'
을 포함하고있는 행이 아닌 사용자 이름없는 행의 첫 번째 일치합니다. 그 결과 jeffrey
는 연결할 때 사용자 이름을 지정 했음에도 불구하고, 익명 사용자로 인증됩니다.
서버에 연결할 수 있지만 권한이 기대 한 것과 다를 아마도 다른 계정으로 인증되어 있습니다. 서버가 사용자의 인식에 사용한 계정을 찾으려면 CURRENT_USER()
함수를 사용합니다. ( 섹션 12.14 "정보 함수" 를 참조하십시오.)이 일치하는 user
테이블 행의 User
와 Host
값을 나타내는
형식의 값을 반환합니다. 예를 들어, user_name
@ host_name
jeffrey
가 연결되어 다음의 쿼리를 발행했다고합니다.
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
여기에 표시된 결과는 일치 한 user
테이블 행의 User
컬럼 값이 공백인지를 보여줍니다. 즉, 서버는 jeffrey
를 익명 사용자로 취급하고 있습니다.
인증 문제를 진단하기위한 다른 방법은 user
테이블을 출력하고 테이블을 수동으로 정렬하여 첫 번째 일치가 이루어졌다 행을 확인하는 방법입니다.