MySQL 보안 가이드(3)
2.4
GRANT 없이 사용자 설정
MySQL 3.22.11 이전 버전을 사용하는 경우 GRANT(또는 REVOKE) 문을 사용하여 사용자 및 해당 액세스 권한을 설정할 수 없지만 인증 테이블의 내용을 직접 수정할 수 있습니다. GRANT 문이 부여 테이블을 수정하는 방법을 이해하면 쉽습니다. 그런 다음 INSERT 문을 수동으로 실행하여 동일한 작업을 직접 수행할 수 있습니다.
GRANT 문을 실행할 때 사용자 이름과 호스트 이름, 그리고 비밀번호도 지정할 수 있습니다. 이 사용자에 대해 사용자 테이블 레코드가 생성되고 이러한 값은 사용자, 호스트 및 비밀번호 열에 기록됩니다. GRANT 문에 전역 권한을 지정하면 이러한 권한은 레코드의 권한 열에 기록됩니다. 주의해야 할 점은 GRANT 문은 비밀번호를 암호화하지만 INSERT는 그렇지 않다는 것입니다. 비밀번호를 암호화하려면 INSERT에서 PASSWORD() 함수를 사용해야 합니다.
데이터베이스 수준 권한을 지정하면 사용자 이름과 호스트 이름이 db 테이블의 사용자 및 호스트 열에 기록됩니다. 권한을 부여한 데이터베이스는 Db 열에 기록되고, 부여한 권한은 권한 열에 기록됩니다.
테이블 수준 권한과 열 수준 권한의 경우 효과는 비슷합니다. tables_PRiv 및 columns_priv 테이블에 레코드를 생성하여 사용자 이름, 호스트 이름, 데이터베이스는 물론 관련 테이블과 열을 기록합니다. 부여된 권한은 권한 열에 기록됩니다.
이전 소개를 기억하신다면 GRANT 문을 사용하지 않고도 GRANT가 수행하는 작업을 수행할 수 있을 것입니다. 인증 테이블을 직접 수정하는 경우 서버에 인증 테이블을 다시 로드하라고 지시해야 합니다. 그렇지 않으면 서버는 변경 사항을 알 수 없습니다. mysqladmin을 실행할 수 있습니다
플러시 권한 또는 mysqladmin
reload 명령은 강제로 다시 로드합니다. 이 작업을 잊어버리면 왜 서버가 원하는 작업을 수행하지 않는지 궁금해하게 됩니다.
다음 GRANT 문은 소유권을 가진 슈퍼유저를 생성합니다. 다른 사람에게 위임하는 기능 포함:
GRANT
모두 *.*에서 anyname@localhost로 "passwd"
로 식별되며 GRANT 사용
OPTION
이 명령문은 사용자 테이블에 anyname@localhost에 대한 레코드를 생성하고 모든 권한을 엽니다. 왜냐하면 여기에 슈퍼 유저(전역) 권한이 저장되어 있기 때문입니다. INSERT 문으로 동일한 작업을 수행하려면 다음 명령문을 사용하세요. :
INSERT INTO
user VALUES("localhost","anyname",PASSWORD("passwd"),
"Y","Y","Y","Y","Y","Y","Y"," Y","Y","Y","Y","Y","Y","Y")
MySQL 버전에 따라 작동하지 않을 수도 있습니다. 인증 테이블의 구조가 변경되었으며 사용자 테이블에 14개의 인증 열이 없을 수 있습니다. 쇼 사용
COLUMNS 부여 테이블에 포함된 각 권한 열을 찾아 그에 따라 INSERT 문을 조정하세요. 다음 GRANT 문도 수퍼유저 상태의 사용자를 생성하지만 권한은 하나만 있습니다.
식별된 *.*에 플러시@localhost로 다시 로드 부여
"flushpass"
이 예의 INSERT 문은 이전 문보다 간단하며 열 이름을 쉽게 나열하고 하나의 권한 열만 지정합니다. 다른 모든 열은 기본값 "N"으로 설정됩니다.
INSERT INTO 사용자(호스트,비밀번호,새로고침)
VALUES("localhost","flush",PASSWORD("flushpass"),"Y")
데이터베이스 수준 권한에는 ON을 사용하세요.
인증을 위해 ON *.* 대신 db_name.* 절:
GRANT ALL ON 샘플.* TO boris@localhost
식별자:
"ruby"
이러한 권한은 전역 권한이 아니므로 사용자 테이블에 저장되지 않습니다. (사용자가 연결할 수 있도록) 사용자 테이블에 레코드를 생성해야 하지만 DB도 생성해야 합니다. 테이블 레코드 레코드 데이터베이스 세트 권한:
INSERT INTO 사용자(호스트,사용자,비밀번호)
VALUES("localhost","boris",PASSWORD("ruby"))
INSERT INTO db
VALUES("localhost","sample_db","boris","Y","Y","Y","Y","Y","Y","N","Y","Y", "Y")
"N" 열은 마지막 데이터베이스 수준에 대한 WITH 사용 권한에 대한 것입니다.
승인하다
OPTION의 GRANT문의 경우 열을 "Y"로 설정해야 합니다.
테이블 수준 또는 열 수준 권한을 설정하려면 tables_priv 또는 columns_priv에서 INSERT 문을 사용합니다. 물론, GRANT 문이 없으면 이러한 테이블은 모두 MySQL에 동시에 나타나기 때문에 가질 수 없습니다. 이러한 테이블이 있고 어떤 이유로든 수동으로 조작하려는 경우 개별 열에 대한 권한을 활성화할 수 없다는 점을 알아 두십시오.
활성화하려는 권한 값을 포함하도록 tables_priv.Table_priv 또는 columns_priv.Column_priv 열을 설정합니다. 예를 들어 테이블에 대한 SELECT 및 INSERT 권한을 활성화하려면 관련 tables_priv 레코드에서 Table_priv를 "Select,Insert"로 설정합니다.
MySQL 계정이 있는 사용자의 권한을 수정하려면 권한을 추가하거나 취소하는지 여부에 관계없이 INSERT 대신 UPDATE를 사용하세요. 사용자를 완전히 삭제하려면 해당 사용자가 사용한 모든 테이블에서 레코드를 삭제하세요.
전체 권한 테이블을 직접 수정하기 위한 쿼리 실행을 피하고 싶다면 MySQL과 함께 제공되는 mysqlaccess 및 mysql_setpermissions 스크립트를 살펴볼 수 있습니다.
부록 1
퀴즈
방금 MySQL 서버를 설치하고 MySQL에 연결이 허용된 사용자를 추가한 후 다음 명령문을 사용하십시오.
GRANT ALL ON
samp_db.* 수신인 fred@*.snake.net 확인됨
"cocoa"
그리고 fred는 서버 호스트에 계정이 있어서 서버에 연결을 시도했습니다.
%mysql -u fred -pcocoa
samp_db
오류 1045: 사용자: 'fred@localhost'에 대한 액세스가 거부되었습니다(비밀번호 사용:
네)
왜요?
이유는 다음과 같습니다.
먼저 mysql_install_db가 초기 권한 테이블을 설정하는 방법과 서버가 사용자 테이블 레코드를 사용하여 고객 연결을 일치시키는 방법을 고려하십시오. mysql_install_db로 데이터베이스를 초기화하면 다음과 같은 사용자 테이블이 생성됩니다.
Host
사용자
localhost
pit.snake.net
localhost
pit.snake.net
root
root
처음 두 레코드는 루트가 로컬 호스트 또는 호스트 이름을 지정하여 로컬 서버에 연결할 수 있도록 허용하고, 마지막 두 레코드는 익명 사용자가 로컬에서 연결할 수 있도록 허용합니다. fred 사용자를 추가한 후
Host
사용자
localhost
pit.snake.net
localhost
pit.snake.net
%.snake.net
루트
루트
프레드
서버가 시작되면 레코드를 읽고 정렬합니다(먼저 호스트별로, 다음으로 호스트의 사용자별로). 더 구체적인 항목이 먼저 순위를 매깁니다.
호스트 사용자
localhost
localhost
pit.snake.net
pit.snake.net
%.snake.net
루트
루트
프레드
localhost가 있는 두 레코드는 함께 순위가 매겨지는 반면, 루트에 대한 레코드는 null보다 더 구체적이므로 첫 번째로 순위가 매겨집니다. Pit.snake.net의 기록도 비슷합니다. 이들 모두는 와일드카드가 없는 문자 그대로의 Host 값이므로 fred에 대한 기록보다 먼저 순위가 지정됩니다. 특히 익명 사용자는 fred보다 먼저 순위가 매겨집니다.
결과적으로 fred가 localhost에서 연결을 시도하면 Host 열에 사용자 이름이 비어 있는 레코드가 %.snake.net을 포함하는 레코드보다 먼저 일치됩니다. 기본 익명 사용자에게 비밀번호가 없기 때문에 이 레코드의 비밀번호는 비어 있습니다. fred가 연결할 때 비밀번호를 지정했기 때문에 불일치가 발생하여 연결이 실패했습니다.
여기서 기억해야 할 점은 와일드카드를 사용하여 사용자가 연결할 수 있는 호스트를 지정하는 것이 편리하다는 것입니다. 그러나 테이블에 익명 사용자 기록을 유지하는 한 localhost에서 연결하는 데 문제가 있습니다.
일반적으로 익명 사용자 기록을 삭제하는 것이 좋습니다:
mysql>
사용자 WHERE에서 삭제
User="";
한 단계 더 나아가 다른 인증 테이블에서 익명 사용자를 삭제하세요. User 열이 있는 테이블은 db, tables_priv 및 columns_priv입니다.
부록 2
새로운 MySQL 설치를 더욱 안전하게 만들기
새로운 MySQL 서버를 직접 설치한 후에는 MySQL 루트 사용자를 위한 디렉토리를 지정해야 합니다(기본값은 비밀번호 없음). 그렇지 않으면 이를 잊어버리면 MySQL은 매우 위험한 상태가 됩니다. 상태(적어도 잠시 동안).
유닉스(리눅스)에서는 매뉴얼의 지시에 따라 MySQL을 설치한 후 mysql_install_db 스크립트를 실행해 인증 테이블과 초기 권한이 포함된 mysql 데이터베이스를 구축해야 한다. Windows에서는 배포판에서 설치 프로그램을 실행하여 데이터 디렉터리와 mysql 데이터베이스를 초기화합니다. 서버도 실행 중이라고 가정합니다.
컴퓨터에 MySQL을 처음 설치하면 mysql 데이터베이스의 인증 테이블이 다음과 같이 초기화됩니다.
비밀번호를 지정하지 않고도 localhost에서 루트로 연결할 수 있습니다. 루트 사용자는 모든 권한(관리 권한 포함)을 가지며 무엇이든 할 수 있습니다. (그런데, MySQL 슈퍼유저는 Unix 슈퍼유저와 이름이 동일하며, 서로 아무런 관련이 없습니다.)
test라는 이름의 데이터베이스와 이름이 test_로 시작하는 모든 데이터베이스에 로컬로 연결할 수 있는 사용자에게 익명 액세스 권한이 부여됩니다. 익명 사용자는 데이터베이스에 대해 무엇이든 할 수 있지만 관리 권한은 없습니다.
연결하는 사용자가 localhost 호스트 이름을 사용하는지 아니면 실제 호스트 이름을 사용하는지에 관계없이 localhost에서 여러 서버에 대한 연결이 허용됩니다. 예:
% mysql -h
localhost 테스트
% mysql -hpit.snake.net
test
비밀번호를 지정하지 않고 MySQL에 루트로 연결한다는 것은 초기 설치가 안전하지 않다는 의미이므로 관리자로서 가장 먼저 해야 할 일은 루트 비밀번호를 설정하는 것입니다. 그런 다음 비밀번호를 설정한 방법을 사용하면 이 변경 사항을 알 수 있도록 서버에 인증 테이블을 다시 로드하도록 지시할 수도 있습니다. (서버가 시작되면 테이블을 메모리에 다시 로드하고 사용자가 테이블을 수정했는지 알 수 없습니다.)
MySQL의 경우
버전 3.22 이상에서는 mysqladmin을 사용하여 비밀번호를 설정할 수 있습니다:
% mysqladmin -u root 비밀번호
비밀번호
모든 버전의 MySQL에서 mysql 프로그램을 사용하여 mysql 데이터베이스의 사용자 인증 테이블을 직접 수정할 수 있습니다:
%
mysql -u 루트 mysql
mysql>UPDATE 사용자 SET
비밀번호=PASSWORD("귀하의 비밀번호") 어디서
User="root";
이전 버전의 MySQL을 사용하는 경우 mysql 및 UPDATE를 사용하세요.
비밀번호를 설정한 후 다음 명령을 실행하여 서버에 인증 테이블을 다시 로드하도록 지시해야 하는지 확인하세요.
%
mysqladmin -u 루트 상태
서버에서 여전히 비밀번호를 지정하지 않고 루트로 연결할 수 있는 경우 인증 테이블을 다시 로드하세요.
%
mysqladmin -u 루트
reload
루트 비밀번호를 설정한 후(필요한 경우 인증 테이블을 다시 로드) 루트로 서버에 연결할 때마다 비밀번호를 지정해야 합니다.
위 내용은 MySQL 보안 가이드(3)(재인쇄) 내용입니다. 더 많은 관련 글은 PHP 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!