Loading...
MySQL 9.5 Reference Manual 9.5의 8.2.6 Access Control, Stage 1: Connection Verification의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL server에 연결을 시도하면, server는 다음 조건에 따라 연결을 허용하거나 거부합니다:
사용자의 identity와, 적절한 자격 증명을 제공하여 그 identity를 검증할 수 있는지 여부.
계정이 locked 상태인지 unlocked 상태인지 여부.
server는 먼저 자격 증명을 확인한 다음, 계정 locking 상태를 확인합니다. 어느 단계에서든 실패하면 server는 해당 사용자에 대한 접근을 완전히 거부합니다. 그렇지 않으면 server는 연결을 허용하고, 이후 Stage 2로 들어가 요청을 기다립니다.
server는 user table의 column을 사용하여
identity 및 자격 증명을 검사하며, 다음 조건이 만족되는 경우에만
연결을 허용합니다:
client host name과 user name이 어떤 user table
row의 Host 및 User column과 일치해야 합니다.
허용 가능한 Host 및 User 값에 대한 규칙은
Section 8.2.4, “Specifying Account Names”를
참조하십시오.
row에 지정된 자격 증명(예: password)을 client가 제공해야 하며,
이는 authentication_string column에 의해
나타납니다. 자격 증명은 plugin column에
지정된 인증 플러그인을 사용하여 해석됩니다.
row가 계정이 unlocked 상태임을 나타내야 합니다. locking 상태는
account_locked column에 기록되며,
값이 'N'이어야 합니다. 계정 locking은
CREATE USER 또는
ALTER USER statement로 설정하거나
변경할 수 있습니다.
사용자의 identity는 다음 두 가지 정보에 기반합니다:
MySQL user name.
연결을 수행하는 client host.
User column 값이 공백이 아니라면,
들어오는 연결의 user name은 정확히 일치해야 합니다.
User 값이 공백이면, 어떤 user name과도
일치합니다. 들어오는 연결과 일치하는 user table row에
user name이 공백인 경우, 사용자는 client가 실제로 지정한 이름이
아닌, 이름이 없는 anonymous user로 간주됩니다.
이는 연결이 유지되는 동안(즉, Stage 2 동안) 모든 이후 접근 검사에 공백 user name이 사용된다는 의미입니다.
authentication_string column은 공백일 수 있습니다.
이는 wildcard가 아니며, 임의의 password가 일치한다는 의미가
아닙니다. 사용자가 password를 지정하지 않고 연결해야 함을 의미합니다.
client를 인증하는 플러그인이 구현한 인증 메서드는
authentication_string column의 password를 사용할 수도 있고,
사용하지 않을 수도 있습니다. 이 경우 MySQL server에 인증하기 위해
외부 password가 추가로 사용될 수 있습니다.
user table의 authentication_string
column에 저장된 공백이 아닌 password 값은 암호화되어 있습니다.
MySQL은 password를 누구나 볼 수 있는 평문으로 저장하지 않습니다.
대신, 연결을 시도하는 사용자가 제공한 password는(계정
인증 플러그인이 구현한 password 해싱 메서드를 사용해) 암호화됩니다.
그 후 연결 과정에서 password가 올바른지 확인할 때 이 암호화된 password가
사용됩니다. 이 과정은 암호화된 password가 연결을 통해 전송되지 않고
수행됩니다. Section 8.2.1, “Account User Names and Passwords”를
참조하십시오.
MySQL server의 관점에서 암호화된 password가 실제
password이므로, 이 값에 대한 접근 권한을 누구에게도 부여해서는 안 됩니다.
특히, nonadministrative user에게
mysql system database 내 table에 대한 읽기 접근 권한을
부여하지 마십시오.
다음 table은 user table에서 다양한
User 및 Host 값 조합이
들어오는 연결에 어떻게 적용되는지를 보여 줍니다.
User Value | Host Value | Permissible Connections |
|---|---|---|
'fred' | 'h1.example.net' | fred, h1.example.net에서 연결 |
'' | 'h1.example.net' | 어떤 user든 h1.example.net에서 연결 |
'fred' | '%' | 어떤 host에서든 fred가 연결 |
'' | '%' | 어떤 user든 어떤 host에서든 연결 |
'fred' | '%.example.net' | example.net 도메인의 어떤 host에서든<br>fred가 연결 |
'fred' | 'x.example.%' | fred가<br>x.example.net,<br>x.example.com,<br>x.example.edu 등에서 연결; 이는<br>아마도 유용하지 않음 |
'fred' | '198.51.100.177' | IP 주소가<br>198.51.100.177인 host에서 fred가 연결 |
'fred' | '198.51.100.%' | 198.51.100 클래스 C 서브넷 내<br>어떤 host에서든 fred가 연결 |
'fred' | '198.51.100.0/255.255.255.0' | 이전 예와 동일 |
들어오는 연결의 client host name과 user name이
user table의 둘 이상의 row와 일치할 수 있습니다.
앞의 예제 집합이 이를 보여 줍니다. 나열된 여러 entry는
h1.example.net에서 fred가 연결하는 경우에
일치합니다.
여러 개의 match가 가능한 경우, server는 어느 row를 사용할지 결정해야 합니다. server는 다음과 같이 이 문제를 해결합니다:
server가 user table을 메모리로 읽어들일 때마다,
row를 정렬합니다.
client가 연결을 시도하면, server는 정렬된 순서대로 row를 검사합니다.
server는 client host name과 user name에 일치하는 첫 번째 row를 사용합니다.
server는 가장 구체적인 Host 값을 가진 row가 먼저 오도록
정렬 규칙을 사용합니다:
리터럴 IP 주소와 host name이 가장 구체적입니다.
host 부분에 IP 주소가 있는 계정은 다음과 같은 구체성 순서를 가집니다:
host 부분이 IP 주소로 주어진 계정:
1CREATE USER 'user_name'@'127.0.0.1'; 2CREATE USER 'user_name'@'198.51.100.44';
host 부분이 CIDR 표기법으로 된 IP 주소인 계정:
1CREATE USER 'user_name'@'192.0.2.21/8'; 2CREATE USER 'user_name'@'198.51.100.44/16';
host 부분이 서브넷 마스크와 함께 IP 주소로 된 계정:
1CREATE USER 'user_name'@'192.0.2.0/255.255.255.0'; 2CREATE USER 'user_name'@'198.51.0.0/255.255.0.0';
패턴 '%'는 “any host”를 의미하며,
가장 덜 구체적입니다.
빈 문자열 ''도 “any host”를 의미하지만,
'%' 뒤에 정렬됩니다.
Non-TCP(소켓 파일, 네임드 파이프, 공유 메모리) 연결은
로컬 연결로 취급되며, 해당 계정이 있는 경우 host 부분이
localhost인 항목과 match되고, 그렇지 않으면
localhost와 일치하는 와일드카드가 포함된 host 부분과
match됩니다(예: local%, l%, %).
'%'를 localhost와 동등하게 취급하는 동작은 deprecated되었으며,
향후 MySQL 버전에서 제거될 것으로 예상해야 합니다.
동일한 Host 값을 가진 row는 가장 구체적인
User 값을 가진 row가 먼저 오도록 정렬됩니다.
공백 User 값은 “any user”를 의미하며,
가장 덜 구체적입니다. 따라서 동일한
Host 값을 가진 row에서는 nonanonymous user가
anonymous user보다 먼저 정렬됩니다.
동일하게 구체적인 Host 및 User
값을 가진 row 간의 순서는 비결정적입니다.
동작 방식을 살펴보기 위해, user table이
다음과 같다고 가정해 봅니다:
1+-----------+----------+- 2| Host | User | ... 3+-----------+----------+- 4| % | root | ... 5| % | jeffrey | ... 6| localhost | root | ... 7| localhost | | ... 8+-----------+----------+-
server가 table을 메모리로 읽어들이면, 앞에서 설명한 규칙으로 row를 정렬합니다. 정렬 후 결과는 다음과 같습니다:
1+-----------+----------+- 2| Host | User | ... 3+-----------+----------+- 4| localhost | root | ... 5| localhost | | ... 6| % | jeffrey | ... 7| % | root | ... 8+-----------+----------+-
client가 연결을 시도하면, server는 정렬된 row를 순서대로 검사하고
찾은 첫 번째 match를 사용합니다.
localhost에서 jeffrey가 연결하는 경우,
table의 두 row가 match됩니다:
Host 및 User 값이
'localhost' 및 ''인 row와,
'%' 및 'jeffrey'인 row입니다.
'localhost' row가 정렬 순서상 먼저 나타나므로,
server는 이 row를 사용합니다.
다른 예를 들어 보겠습니다. user table이
다음과 같다고 가정합니다:
1+----------------+----------+- 2| Host | User | ... 3+----------------+----------+- 4| % | jeffrey | ... 5| h1.example.net | | ... 6+----------------+----------+-
정렬된 table은 다음과 같습니다:
1+----------------+----------+- 2| Host | User | ... 3+----------------+----------+- 4| h1.example.net | | ... 5| % | jeffrey | ... 6+----------------+----------+-
첫 번째 row는 h1.example.net에서 어떤 user든
연결하는 경우를 match하며, 두 번째 row는 어떤 host에서든
jeffrey가 연결하는 경우를 match합니다.
참고
일반적인 오해 중 하나는, 특정 user name에 대해, server가 연결에 대한 match를 찾으려 할 때 항상 해당 user를 명시적으로 기록한 모든 row를 먼저 사용한다고 생각하는 것입니다. 이는 사실이 아닙니다. 앞의 예제는 이를 잘 보여 줍니다.
이 예제에서는
h1.example.net에서 jeffrey가 연결할 때,
User column 값에 'jeffrey'가 포함된 row가
아닌, user name이 없는 row가 먼저 match됩니다.
그 결과, jeffrey는 연결 시 user name을 지정했음에도
불구하고 anonymous user로 인증됩니다.
server에 연결할 수 있지만 권한이 예상과 다르다면,
아마도 다른 계정으로 인증되고 있을 가능성이 있습니다. server가
어떤 계정을 사용해 사용자를 인증했는지 확인하려면
CURRENT_USER() 함수를 사용하십시오.
(Section 14.15, “Information Functions”를 참조하십시오.)
이 함수는 match된 user table row의
User 및 Host 값을 나타내는
user_name@host_name 형식의 값을
반환합니다. 예를 들어, jeffrey가 연결한 뒤
다음 query를 실행한다고 가정합니다:
1mysql> SELECT CURRENT_USER(); 2+----------------+ 3| CURRENT_USER() | 4+----------------+ 5| @localhost | 6+----------------+
여기 표시된 결과는 match된 user table row의
User column 값이 공백이었음을 나타냅니다.
즉, server는 jeffrey를 anonymous user로
취급하고 있습니다.
인증 문제를 진단하는 또 다른 방법은
user table을 출력한 뒤, 첫 번째 match가
어디에서 발생하는지 확인하기 위해 직접 정렬해 보는 것입니다.
8.2.5 Specifying Role Names
8.2.7 Access Control, Stage 2: Request Verification