>  기사  >  데이터 베이스  >  MySQL 보안 가이드(2)(리디렉션됨)

MySQL 보안 가이드(2)(리디렉션됨)

黄舟
黄舟원래의
2016-12-17 15:05:32893검색

MySQL 보안 가이드(2)


2.1.3 데이터베이스 및 테이블 권한
다음 권한은 데이터베이스 및 테이블 작업에 적용됩니다.

ALTER
를 사용하면 ALTER를 사용할 수 있습니다. TABLE 문에서는 실제로 간단한 1단계 권한입니다. 데이터베이스에서 수행하려는 작업에 따라 다른 권한이 있어야 합니다.
CREATE
를 사용하면 데이터베이스와 테이블을 만들 수 있지만 인덱스는 만들 수 없습니다.
DELETE
를 사용하면 테이블에서 기존 레코드를 삭제할 수 있습니다.
DROP
을 사용하면 데이터베이스와 테이블을 삭제할 수 있지만 인덱스는 삭제할 수 없습니다.
INDEX
를 사용하면 색인을 생성하고 삭제할 수 있습니다.
참조
현재 사용되지 않습니다.
SELECT
를 사용하면 SELECT 문을 사용하여 테이블에서 데이터를 검색할 수 있습니다. SELECT NOW() 또는 SELECT 4/2와 같이 테이블을 포함하지 않는 SELECT 문에는 필요하지 않습니다.
UPDATE
를 사용하면 테이블의 기존 레코드를 수정할 수 있습니다.
2.1.4 관리 권한
다음 권한은 서버 작동을 제어하는 ​​관리 작업이나 사용자 권한 부여 기능에 사용됩니다.

FILE
을 사용하면 서버 호스트에서 파일을 읽거나 쓰도록 서버에 지시할 수 있습니다. 이 권한은 우연히 부여되어서는 안 되며 위험합니다. "권한 부여 테이블 위험 방지"를 참조하세요. 서버는 이 권한을 한도 내에서 유지하기 위해 약간의 주의를 기울입니다. 누구나 읽을 수 있는 파일만 읽을 수 있습니다. 작성 중인 파일은 존재하지 않아야 합니다. 이렇게 하면 서버가 /etc/passwd 또는 다른 사람의 데이터베이스에 속한 데이터 디렉토리와 같은 중요한 파일을 강제로 다시 작성하는 것을 방지할 수 있습니다.
FILE 권한을 부여하는 경우 UNIX 루트 사용자로 서버를 실행하고 있지 않은지 확인하세요. 루트는 파일 시스템의 어느 위치에서나 새 파일을 생성할 수 있기 때문입니다. 권한이 없는 사용자로 서버를 실행하는 경우 서버는 사용자가 액세스할 수 있는 디렉터리에만 파일을 생성할 수 있습니다.

GRANT
를 사용하면 GRANT를 포함하여 다른 사람에게 자신의 권한을 부여할 수 있습니다.
PROCESS
를 사용하면 SHOW를 사용할 수 있습니다. PROCESS 문 또는 mysqladmin process 명령을 사용하여 서버에서 실행 중인 스레드(프로세스)에 대한 정보를 볼 수 있습니다. 이 권한을 사용하면 KILL 문이나 mysqladmin을 사용할 수도 있습니다. kill 명령은 스레드를 종료합니다.
언제든지 자신의 스레드를 보거나 삭제할 수 있습니다. PROCESS 권한은 모든 스레드에서 이러한 작업을 수행할 수 있는 기능을 제공합니다.

RELOAD
를 사용하면 광범위한 서버 관리 작업을 수행할 수 있습니다. FLUSH 문을 발행할 수 있으며, mysqladmin의 reload,refresh,flush-hosts,flush-logs,flush-privileges,flush-tables 명령을 참조할 수도 있다.
SHUTDOWN
을 사용하면 mysqladmin shutdown을 사용하여 서버를 종료할 수 있습니다.
사용자, db 및 호스트 테이블에서 각 권한은 별도의 열로 지정됩니다. 이들 컬럼은 모두 ENUM("N", "Y") 타입으로 선언되어 있으므로 각 가중치의 기본값은 "N"이다. tables_priv 및 columns_priv의 권한은 SET로 표시되며, 이를 통해 단일 열과 어떤 조합으로든 권한을 지정할 수 있습니다. 이 두 테이블은 다른 세 테이블보다 최신이므로 더 효율적인 표현을 사용합니다. (향후에는 user, db,host 테이블도 SET 타입으로 표현될 가능성이 있습니다.)

tables_priv 테이블의 Table_priv 컬럼은 다음과 같이 정의됩니다.

SET ('Select',' Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter')
colums_priv의 Column_priv 열 테이블은 다음과 같이 정의됩니다.

SET('Select','Insert','Update','References')
열 수준이 더 적은 권한이 적합하므로 열 권한은 테이블 권한보다 적습니다. 예를 들어 테이블을 만들 수 있지만 분리된 열을 만들 수는 없습니다.

사용자 테이블에는 다른 인증 테이블에 없는 특정 권한 열(File_priv, Process_priv, Reload_priv 및 Shutdown_priv)이 포함되어 있습니다. 이러한 권한은 특정 데이터베이스나 테이블과 관련되지 않은 수행을 서버에 요청하는 작업에 적용됩니다. 사용자가 현재 데이터베이스에 있는 내용을 기반으로 데이터베이스를 닫을 수 있도록 허용하는 것은 의미가 없습니다.

2.2 서버가 클라이언트 액세스를 제어하는 ​​방법
MySQL을 사용할 때 클라이언트 액세스 제어에는 두 단계가 있습니다. 첫 번째 단계는 서버에 연결을 시도할 때 발생합니다. 서버는 사용자 테이블을 조사하여 귀하의 이름, 연결하려는 호스트 및 귀하가 제공한 비밀번호와 일치하는 항목을 찾을 수 있는지 확인합니다. 일치하는 항목이 없으면 연결할 수 없습니다. 일치하는 항목이 있으면 연결을 설정하고 두 번째 단계를 계속합니다. 이 단계에서는 사용자가 실행하는 모든 쿼리에 대해 서버가 인증 테이블을 확인하여 쿼리를 실행할 수 있는 충분한 권한이 있는지 확인합니다. 두 번째 단계는 서버와의 대화가 끝날 때까지 계속됩니다.

이 섹션에서는 인증 테이블 항목을 들어오는 연결 요청 또는 쿼리와 일치시키기 위해 MySQL 서버에서 사용하는 원칙을 자세히 설명합니다. 여기에는 권한 정보와 결합된 인증 테이블 범위 열의 합법적인 값 유형이 포함됩니다. 인증 테이블. 테이블의 항목을 확인하는 모드 및 순서입니다.

2.2.1 범위 열 내용
일부 범위 열에는 리터럴 값이 필요하지만 대부분 와일드카드나 기타 특수 값을 허용합니다.

호스트
호스트 열 값은 호스트 이름 또는 IP 주소일 수 있습니다. localhost 값은 localhost를 의미하지만 호스트 이름을 사용할 때가 아니라 localhost 호스트 이름을 사용할 때만 일치합니다. 로컬 호스트 이름이 pit.snake.net이고 사용자 테이블에 두 개의 레코드(하나는 Host 값 또는 localhost이고 다른 하나는pit.snake.net)가 있는 경우 localhost가 있는 레코드는 다음과 같이 처리됩니다. localhost에 연결할 때 일치하고 다른 것들은pit.snake.net에 연결할 때만 일치합니다. 클라이언트가 두 가지 방법으로 연결할 수 있도록 하려면 사용자 테이블에 두 개의 레코드가 있어야 합니다.

와일드카드를 사용하여 호스트 값을 지정할 수도 있습니다. SQL 패턴 문자 "%" 및 "_"를 사용할 수 있으며 쿼리에서 LIKE 연산자를 사용할 때와 동일한 의미를 갖습니다(regex 연산자는 허용되지 않음). SQL 패턴 문자는 호스트 이름과 IP 주소 모두에 사용될 수 있습니다. 예를 들어 %wisc.edu는 wisc.edu 도메인의 모든 호스트와 일치하고 %.edu는 College of Education의 모든 호스트와 일치합니다. 마찬가지로 192.168.%는 192.168의 모든 항목과 일치합니다. 클래스 B 서브넷의 호스트이며 192.168.3.%는 192.168.3의 모든 항목과 일치합니다. 클래스 C 서브넷의 호스트.

% 값은 모든 호스트와 일치하며 사용자가 어디서나 연결할 수 있도록 하는 데 사용할 수 있습니다. 빈 호스트 값은 %와 같습니다. (예외: db 테이블에서 Host 값이 비어 있으면 "호스트 테이블을 추가로 확인"한다는 의미입니다. 이 프로세스는 "쿼리 액세스 확인"에서 소개됩니다.)

MySQL에서 3.23부터는 17비트 네트워크 주소를 지정하고 IP 주소가 처음 17자리인 모든 호스트와 일치하는 192.168.128.0/17과 같이 네트워크 주소에 사용되는 넷마스크 표시로 IP 주소를 지정할 수도 있습니다. 192.168128.

사용자
사용자 이름은 텍스트이거나 비어 있어야 합니다. 공백 값은 모든 사용자와 일치합니다. 사용자 값인 %는 공백을 의미하지 않으며 대신 리터럴 % 이름과 일치하는데 이는 아마도 원하는 것이 아닐 것입니다.

들어오는 연결이 사용자 테이블을 통해 인증되고 일치하는 레코드에 빈 User 값이 포함되어 있는 경우 클라이언트는 익명 사용자로 간주됩니다.

비밀번호
비밀번호 값은 비어 있거나 비어 있지 않을 수 있으며, 와일드카드는 허용되지 않습니다. 빈 비밀번호는 모든 비밀번호가 일치한다는 의미는 아니며 사용자가 비밀번호를 지정해서는 안 된다는 의미입니다.

비밀번호는 문자 그대로의 텍스트가 아닌 암호화된 값으로 저장됩니다. 비밀번호 열에 문자 그대로 비밀번호를 저장하면 사용자가 연결할 수 없습니다! GRANT 문과 mysqladmin 비밀번호 명령은 자동으로 비밀번호를 암호화하지만 INSERT, REPLACE, UPDATE 또는 SET과 같은 명령을 사용하는 경우 PASSWORD와 같은 명령의 경우 단순히 "new_password" 대신 PASSWORD("new_password")를 사용하여 비밀번호를 지정해야 합니다.

Db
columns_priv 및 tables_priv 테이블에서 Db 값은 실제 데이터베이스 이름(문자 그대로)이어야 하며 패턴과 공백은 허용되지 않습니다. db 및 호스트에서는 Db 값을 문자 그대로 지정하거나 SQL 패턴 문자 '%' 또는 '_'를 사용하여 와일드카드를 지정할 수 있습니다. '%' 또는 공백은 모든 데이터베이스와 일치합니다.
Table_name, Column_name
이 열의 값은 리터럴 테이블이거나 열 이름이어야 하며 패턴과 공백은 허용되지 않습니다.
일부 범위 열은 서버에서 대소문자를 구분하는 것으로 간주되지만 다른 열은 그렇지 않습니다. 이러한 원칙은 아래 표에 요약되어 있습니다. 특히 쿼리에서 테이블 이름의 대소문자 구분은 서버가 실행 중인 호스트의 파일 시스템에 따라 달라지더라도 Table_name 값은 항상 대소문자를 구분하여 처리됩니다(UNIX는 대소문자를 구분하고 Windows는 그렇지 않습니다). ).

표 3 부여 테이블 범위 열의 대소문자 구분

호스트
사용자
비밀번호
Db
Table_name
열_이름
대소문자 구분
아니요




아니요


2.2.2 쿼리 액세스 확인
쿼리를 실행할 때마다 서버는 쿼리를 실행할 수 있는 충분한 권한이 있는지 확인하고 적절한 액세스 권한이 있거나 모든 검색이 완료될 때까지 user, db, tables_priv 및 columns_priv 순서로 확인합니다. 지켜보고 아무것도 얻지 마십시오. 더 구체적으로 말하면:

서버는 사용자 테이블에서 연결을 시작한 레코드와 일치하는 레코드를 확인하여 사용자가 어떤 전역 권한을 가지고 있는지 확인합니다. 쿼리가 있고 쿼리에 충분하면 서버가 쿼리를 실행합니다.
글로벌 권한이 충분하지 않은 경우 서버는 db 테이블을 검색하고 레코드에 있는 권한을 글로벌 권한에 추가합니다. 쿼리 결과가 충분하면 서버가 쿼리를 실행합니다.
결합된 전역 권한과 데이터베이스 수준 권한이 충분하지 않은 경우 서버는 계속해서 tables_priv 테이블을 살펴본 다음 columns_priv 테이블을 찾습니다.
모든 테이블을 확인한 후에도 여전히 권한이 없으면 서버는 쿼리 실행 시도를 거부합니다.
부울 용어로 인증 테이블의 권한은 서버에서 다음과 같이 사용됩니다.

user OR tables_priv OR columns_priv

이전 설명에서는 인증 테이블이 4개만 언급되어 있는데 실제로는 5개가 있는 이유가 궁금할 것입니다. 실제로 서버는 다음과 같이 접근 권한을 확인합니다:

user OR (db AND 호스트) OR tables_priv OR columns_priv

첫 번째로 간단한 표현식은 호스트 테이블이 GRANT 및 REVOKE 문의 영향을 받지 않기 때문입니다. 사용자 권한을 관리하기 위해 항상 GRANT 및 REVOKE를 사용한다면 호스트 테이블에 대해 생각할 필요가 없습니다. 하지만 어떻게 작동하는지 알아야 합니다.

서버는 데이터베이스 수준 권한을 확인할 때 클라이언트에 대한 db 테이블을 조회합니다. 호스트 열이 비어 있으면 "호스트 테이블을 확인하여 데이터베이스에 액세스할 수 있는 호스트를 알아보세요"를 의미합니다.
서버는 db 테이블의 레코드와 동일한 Db 열 값을 호스트 테이블에서 찾습니다. 클라이언트 호스트와 일치하는 호스트 레코드가 없으면 데이터베이스 수준 권한이 부여되지 않습니다. 이러한 레코드 중 하나에 연결된 클라이언트의 호스트와 일치하는 Host 열 값이 있으면 db 테이블 레코드와 호스트 테이블 레코드가 결합되어 클라이언트의 데이터베이스 수준 권한을 생성합니다.
그러나 권한은 논리적 AND로 결합됩니다. 즉, 지정된 권한이 두 테이블 모두에 존재하지 않는 한 클라이언트는 해당 권한을 갖지 않습니다. 이런 방식으로 db 테이블에 기본 권한 집합을 부여한 다음 호스트 테이블을 사용하여 특정 호스트에 대해 선택적으로 비활성화할 수 있습니다. 예를 들어 도메인의 모든 호스트에서 데이터베이스 액세스를 허용하지만 보안 수준이 낮은 영역에 있는 호스트에 대한 데이터베이스 권한을 끌 수 있습니다.

이전 설명에서는 확실히 액세스 확인 과정이 다소 복잡한 것처럼 들립니다. 특히 서버가 사용자가 실행하는 모든 쿼리에 대해 권한 확인을 수행한다고 생각하는 경우에는 실제로 서버가 권한 확인을 수행하는 대신 이 프로세스가 매우 빠릅니다. 각 쿼리에 대해 부여 테이블에서 정보를 조회하고 시작 시 테이블의 내용을 메모리로 읽은 다음 쿼리가 메모리 내 복사본을 사용하는지 확인합니다. 이는 액세스 확인 작업의 성능을 크게 향상시킵니다. 하지만 아주 명백한 부작용이 있습니다. 인증 테이블의 내용을 직접 수정하면 서버는 권한 변경에 대해 알 수 없습니다.

예를 들어, 새로운 사용자를 추가하기 위해 INSERT 문을 사용하여 사용자 테이블에 새 레코드를 추가하는 경우 레코드에 이름이 지정된 사용자는 서버에 연결할 수 없습니다. 이는 새로운 관리자(때때로 숙련된 베테랑)에게 매우 혼란스러웠으며 당시의 해결책은 간단했습니다. 서버에 인증 테이블 내용을 변경한 후 다시 로드하라고 지시하면 FLUSH를 보낼 수 있습니다. 권한 또는 mysqladmin 실행 플러시 권한(또는 플러시 권한을 지원하지 않는 이전 버전이 있는 경우 mysqladmin을 사용하세요. 다시 로드합니다. ).

2.2.3 범위 열 일치 순서
MySQL 서버는 인증 테이블의 레코드를 특정 방식으로 정렬한 다음 레코드를 순서대로 찾아 들어오는 연결을 일치시킵니다. 발견된 첫 번째 일치 항목에 따라 사용되는 레코드가 결정됩니다. 특히 사용자 테이블의 경우 MySQL에서 사용하는 정렬 순서를 이해하는 것이 중요합니다.

서버가 user 테이블의 내용을 읽을 때 Host 및 User 열의 값에 따라 레코드를 정렬합니다. Host 값이 결정적인 역할을 합니다. (동일한 Host 값이 정렬됩니다.) 함께 사용하고 User 값에 따라 정렬됩니다. 그러나 정렬은 이소순서(단어별 정렬)가 아니며 부분적으로만 그렇습니다. 기억해야 할 점은 문자 그대로의 단어가 패턴보다 우선한다는 것입니다. 즉, client.your.net에서 서버에 연결하고 호스트에 client.your.net과 %.your.net이라는 두 개의 값이 있는 경우 첫 번째 값이 먼저 선택됩니다. 마찬가지로 %.your.net이 %.net보다 우선하고 %가 그 다음입니다. IP 주소 매칭도 마찬가지입니다.

한마디로 우선순위가 구체적일수록. 예제는 이 기사의 부록을 참조하세요.

2.3 인증 테이블 위험 방지
이 세션에서는 인증 시 몇 가지 주의 사항과 알 수 없는 값 선택으로 인해 발생하는 위험을 소개합니다. 일반적으로 슈퍼유저 권한을 부여하는 데는 매우 "인색"해야 합니다. 즉, 사용자 테이블의 항목에 대한 권한을 활성화하지 말고 다른 인증 테이블을 사용하여 사용자 권한을 데이터베이스, 테이블 또는 열로 제한해야 합니다. 사용자 테이블의 권한은 서버 작업에 영향을 미치는 모든 데이터베이스의 모든 테이블에 대한 액세스를 허용합니다.

mysql 데이터베이스에 권한을 부여하지 마세요. 인증 테이블이 포함된 데이터베이스에 대한 권한이 있는 사용자는 테이블을 수정하여 다른 데이터베이스에 대한 권한을 얻을 수 있습니다. 사용자가 mysql 데이터베이스 테이블을 수정할 수 있도록 허용하는 권한을 부여하면 사용자에게 전역 GRANT 권한도 효과적으로 부여됩니다. 사용자가 테이블을 직접 수정할 수 있다면 이는 상상할 수 있는 모든 GRANT 문을 실행할 수 있는 것과 같습니다.

FILE 권한은 특히 위험하므로 쉽게 부여하지 마십시오. FILE 권한이 있는 사람이 할 수 있는 작업은 다음과 같습니다.

CREATE TABLE etc_passwd (pwd_entry TEXT);
데이터 INFILE "/etc/passwd" 로드 TABLE etc_passwd;
SELECT * FROM etc_passwd;

이러한 명령문을 실행한 후 사용자는 이미 비밀번호 파일의 내용을 갖게 됩니다. 실제로 서버에서 공개적으로 읽을 수 있는 모든 파일의 내용은 FILE 권한이 있는 사용자가 네트워크를 통해 액세스할 수 있습니다.

파일 권한은 충분히 제한적인 파일 권한이 설정되지 않은 시스템의 데이터베이스를 손상시키는 데 악용될 수도 있습니다. 이것이 바로 서버에서만 읽을 수 있도록 데이터 디렉터리를 설정해야 하는 이유입니다. 데이터베이스 테이블에 해당하는 파일을 사용자의 서버 계정을 가진 사용자뿐만 아니라 누구나 읽을 수 있는 경우 FILE 권한이 있는 모든 사용자도 네트워크를 통해 연결하여 읽을 수 있습니다. 이 프로세스는 아래에 설명되어 있습니다.

LONGBLOB 열이 있는 테이블을 만듭니다.
사용자 테스트;
CREATE TABLE tmp(b LONGBLOB);

이 테이블을 사용하여 도용하려는 데이터베이스 테이블에 해당하는 각 파일의 내용을 읽은 다음 해당 테이블 내용을 자신의 데이터베이스에 있는 파일에 씁니다.

LOAD DATA INFILE "./other_db/x.frm" INTO TABLE tmp
"" 줄로 이스케이프된 필드 TERMINATED BY "";
SELECT * FROM tmp INTO OUTFILE "y.frm"
필드 ""로 이스케이프됨 ""으로 끝나는 줄;
tmp에서 삭제;
데이터 입력 파일 로드 "./other_db/x.ISD" INTO TABLE tmp
"" 라인으로 이스케이프된 필드 종료됨 BY "";
SELECT * FROM tmp INTO OUTFILE "y.ISD"
""에서 이스케이프된 필드 ""로 종료된 줄;
tmp에서 삭제;
데이터 입력 파일 로드 "./other_db/x.ISM" INTO TABLE tmp
"" 줄로 이스케이프된 필드 종료됨 BY "";
SELECT * FROM tmp INTO OUTFILE "y.ISM"
이제 other_db.x의 내용이 포함된 새 테이블 y가 생겼으며 해당 테이블에 대한 전체 액세스 권한을 갖습니다.
다른 사람들이 같은 방식으로 공격하는 것을 방지하기 위해 "1부"에 따르면 "내부 보안 - 데이터 디렉토리 보호"의 지침을 사용하여 데이터 디렉토리에 대한 권한을 설정하십시오. 서버를 시작할 때 --skip-show-database 옵션을 사용하여 사용자가 갖고 있지 않은 데이터베이스로 사용자를 제한할 수도 있습니다. 액세스 권한을 표시합니다. 데이터베이스 및 쇼 테이블. 이는 사용자가 액세스할 수 없는 데이터베이스 및 테이블에 대한 정보를 찾는 것을 방지하는 데 도움이 됩니다.

ALTER 권한은 의도하지 않은 방식으로 사용될 수 있습니다. user1이 table1에 액세스할 수 있지만 tables2에는 액세스할 수 없도록 하려고 한다고 가정합니다. ALTER 권한이 있는 사용자는 ALTER를 사용할 수 있습니다. TABLE은 table2의 이름을 table1로 변경하여 열을 변경합니다.

GRANT 권한에 주의하세요. 권한은 서로 다르지만 둘 다 GRANT 권한을 가진 두 사용자는 서로의 권한을 더욱 강력하게 만들 수 있습니다.

위 내용은 MySQL 보안 가이드(2)(재인쇄) 내용입니다. 더 많은 관련 글은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.