MySQL 사용자 권한 부여 및 회수 모범 사례
MySQL GRANT, REVOKE, SHOW GRANTS, DROP USER를 최소 권한 원칙에 따라 안전하게 사용하는 방법과 앱 및 관리자 계정 예제
MySQL 사용자 권한 부여 및 회수 모범 사례
MySQL 권한은 앱, 도구, 관리자가 연결 후 수행할 수 있는 작업을 결정합니다. 광범위한 접근 권한을 가진 단일 계정은 작은 버그나 유출된 비밀번호를 전체 데이터베이스 노출로 이어지게 할 수 있습니다.
GRANT, REVOKE, SHOW GRANTS를 최소 권한 원칙과 함께 사용하세요: 각 계정은 필요한 권한만, 사용하는 호스트에서만 가져야 합니다.
MySQL 권한 이해하기
GRANT와 REVOKE를 다루기 전에 MySQL에서 사용 가능한 다양한 범위와 유형의 권한을 이해하는 것이 중요합니다. 권한은 사용자가 수행할 수 있는 작업과 데이터베이스 객체를 정의합니다.
MySQL 권한은 범위에 따라 분류할 수 있습니다:
- 전역 권한 (
*.*): MySQL 서버의 모든 데이터베이스와 테이블에 적용됩니다. 예:SUPER,PROCESS,RELOAD,CREATE USER - 데이터베이스 권한 (
database_name.*): 특정 데이터베이스 내의 모든 테이블과 객체에 적용됩니다. 예:SELECT,INSERT,UPDATE,DELETE,CREATE,DROP - 테이블 권한 (
database_name.table_name): 특정 테이블의 모든 열에 적용됩니다. 예:SELECT,INSERT,UPDATE,DELETE,ALTER - 열 권한 (
database_name.table_name.column_name): 테이블 내 특정 열에 적용됩니다. 덜 일반적이지만 세밀한 제어에 유용합니다. - 루틴 권한 (
database_name.routine_name): 저장 프로시저와 함수에 적용되며EXECUTE와ALTER ROUTINE을 제어합니다. - 프록시 권한: 한 사용자가 다른 사용자로 행동할 수 있게 하며, 사용자 ID를 관리하는 애플리케이션에 유용합니다.
일반적인 특정 권한은 다음과 같습니다:
SELECT: 테이블에서 데이터 읽기INSERT: 테이블에 새 행 추가UPDATE: 테이블의 기존 행 수정DELETE: 테이블에서 행 제거CREATE: 데이터베이스, 테이블 또는 인덱스 생성DROP: 데이터베이스, 테이블 또는 인덱스 삭제ALTER: 테이블 구조 수정INDEX: 인덱스 생성 또는 삭제REFERENCES: 외래 키 제약 조건 설정CREATE VIEW,SHOW VIEW: 뷰 관리CREATE ROUTINE,ALTER ROUTINE,EXECUTE: 저장 프로시저 및 함수 관리 및 실행FILE: 서버 호스트에서 파일 읽기 또는 쓰기 (매우 강력하므로 극도로 주의해서 사용)GRANT OPTION: 사용자가 자신의 권한을 다른 사용자에게 부여할 수 있게 합니다. 매우 강력한 권한이므로 신중하게 부여해야 합니다.
GRANT 명령: 안전하게 권한 부여하기
GRANT 명령은 MySQL 사용자에게 권한을 할당하는 데 사용됩니다. 권한을 부여할 때는 최소 권한 원칙을 고려하는 것이 중요합니다. 절대적으로 필요한 것만 부여하세요.
기본 구문
GRANT 명령의 일반 구문은 다음과 같습니다:
GRANT privileges ON object TO 'user'@'host' [WITH GRANT OPTION];
privileges: 쉼표로 구분된 권한 목록 (예:SELECT, INSERT)object: 범위 지정 (예: 전역의 경우*.*,database_name.*,database_name.table_name)'user'@'host': 사용자 계정 (사용자 이름과 연결 가능한 호스트 포함).host는 IP 주소, 호스트 이름 또는 와일드카드(%는 모든 호스트,localhost는 로컬 연결)일 수 있습니다.WITH GRANT OPTION: (선택 사항) 사용자가 지정된 권한을 다른 사용자에게 부여할 수 있게 합니다.
비밀번호는 CREATE USER와 ALTER USER로 생성하거나 변경하세요. 이전 MySQL 릴리스에서는 GRANT ... IDENTIFIED BY를 허용했지만, 최신 MySQL 구문은 계정 생성을 분리합니다.
실용 예제
몇 가지 일반적인 시나리오를 살펴보겠습니다.
새 사용자 생성 및 전역 읽기 전용 액세스 부여 (매우 권장되지 않음)
CREATE USER 'global_reader'@'localhost' IDENTIFIED BY 'StrongPass123!'; GRANT SELECT ON *.* TO 'global_reader'@'localhost';경고:
*.*에SELECT를 부여하면 모든 데이터베이스와 테이블에 대한 액세스 권한이 부여됩니다. 이는 일반적으로 애플리케이션 사용자에게 너무 광범위하며 특정 관리 작업에 필요하지 않은 한 피해야 합니다.애플리케이션 사용자에게 특정 데이터베이스에 대한 전체 액세스 권한 부여
자체 데이터베이스 내에서 데이터를 관리해야 하는 애플리케이션 사용자의 일반적인 시나리오입니다.
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'AppPassSecure!'; GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp_db`.* TO 'app_user'@'localhost';여기서
app_user는myapp_db데이터베이스 내에서만 기본 CRUD 작업을 수행할 수 있지만 새 테이블을 생성하거나 스키마를 수정할 수는 없습니다.특정 테이블에 대한 읽기 전용 액세스 권한 부여
특정 테이블에서만 읽어야 하는 보고 도구의 경우입니다.
CREATE USER 'report_tool'@'%' IDENTIFIED BY 'ReportSecret!'; GRANT SELECT ON `sales_db`.`orders` TO 'report_tool'@'%';'%'호스트는report_tool이 모든 호스트에서 연결할 수 있도록 허용하지만,sales_db의orders테이블에 대한SELECT액세스만 허용합니다.GRANT OPTION부여 (매우 주의해서 사용)관리자가 특정 데이터베이스에 대한 권한 관리를 위임해야 하는 경우입니다.
CREATE USER 'db_admin'@'localhost' IDENTIFIED BY 'AdminPass#456'; GRANT ALL PRIVILEGES ON `inventory_db`.* TO 'db_admin'@'localhost' WITH GRANT OPTION;이제
db_admin은inventory_db에 대한 모든 권한을 다른 사용자에게 부여할 수 있습니다. 이는 중앙 제어를 우회하는 강력한 권한이므로 불가피한 경우에만 사용해야 합니다.
권한 부여 팁
- 최소 권한 원칙: 사용자나 애플리케이션이 기능을 수행하는 데 필요한 최소 권한 집합을 항상 부여하세요. 전용 데이터베이스 관리자 계정이 아닌 이상
ALL PRIVILEGES는 피하세요. - 특정 호스트: 가능하면
'%'대신 특정 IP 주소나 호스트 이름('user'@'192.168.1.10'또는'user'@'appserver.example.com')으로 사용자 연결을 제한하세요. - 별도 사용자: 동일한 데이터베이스에 액세스하더라도 다른 애플리케이션이나 서비스에 대해 별도의 사용자 계정을 만드세요. 이는 잠재적인 보안 침해를 격리합니다.
- 애플리케이션에
root사용 금지: 애플리케이션에root사용자 계정을 절대 사용하지 마세요. 전용 최소 권한 사용자를 만드세요.
REVOKE 명령: 효과적으로 권한 회수하기
REVOKE 명령은 MySQL 사용자로부터 권한을 제거하는 데 사용됩니다. 역할이 변경되거나 애플리케이션이 폐기될 때 안전한 데이터베이스 환경을 유지하는 데 GRANT만큼 중요합니다.
기본 구문
REVOKE 명령의 일반 구문은 다음과 같습니다:
REVOKE privileges ON object FROM 'user'@'host';
privileges: 회수할 쉼표로 구분된 권한 목록object: 회수할 범위 (권한이 부여된 범위와 일치해야 함)'user'@'host': 권한을 회수할 사용자 계정
실용 예제
애플리케이션 사용자로부터
DELETE권한 회수애플리케이션이 더 이상 데이터를 삭제할 필요가 없거나 권한을 낮추려는 경우입니다.
REVOKE DELETE ON `myapp_db`.* FROM 'app_user'@'localhost';이제
app_user는myapp_db내에서SELECT,INSERT,UPDATE는 계속할 수 있지만DELETE는 할 수 없습니다.위임된 관리자로부터
GRANT OPTION회수db_admin이 더 이상inventory_db에 대한 다른 사용자의 권한을 관리할 필요가 없는 경우입니다.REVOKE GRANT OPTION ON `inventory_db`.* FROM 'db_admin'@'localhost';참고:
GRANT OPTION을 회수하려면REVOKE문에서 명시적으로GRANT OPTION을 지정해야 합니다.특정 데이터베이스에 대한 모든 권한 회수
사용자가 특정 데이터베이스에 대해 가지고 있는 모든 권한을 제거하려면 다음과 같이 합니다.
REVOKE ALL PRIVILEGES ON `old_db`.* FROM 'old_app'@'%';경고:
*.*에 대한REVOKE ALL PRIVILEGES는 모든 전역 권한을 회수하며, 여기에는SUPER,CREATE USER등이 포함될 수 있습니다. 전역적으로 이 범위를 사용할 때는 주의하세요.사용자 계정 삭제
사용자나 애플리케이션이 더 이상 필요하지 않으면 사용자를 완전히 제거하는 것이 좋습니다.
DROP USER 'report_tool'@'%';이 명령은 사용자와 관련된 모든 권한을 제거합니다.
권한 회수 팁
- 범위 일치: 회수할 때 객체 범위(
*.*,database_name.*등)가 원래 권한이 부여된 방식과 정확히 일치하는지 확인하세요.database_name.*에SELECT를 부여했다면database_name.table_name이 아닌database_name.*에서 회수해야 합니다. - 확인: 권한을 부여하거나 회수한 후 항상
SHOW GRANTS FOR 'user'@'host';를 사용하여 변경 사항을 확인하세요. - 불필요한 플러시 건너뛰기:
GRANT,REVOKE,CREATE USER,DROP USER후에FLUSH PRIVILEGES가 필요하지 않습니다. MySQL은 이러한 문을 즉시 적용합니다. - 연쇄 효과 고려:
GRANT OPTION이 있는 사용자가 다른 사람에게 권한을 부여한 경우, 해당 사용자의GRANT OPTION을 회수해도 그들이 부여한 권한이 자동으로 회수되지는 않습니다. 별도로 회수해야 합니다.
MySQL 사용자 권한 관리 모범 사례
강력한 권한 관리 전략을 구현하는 것은 데이터베이스 보안에 중요합니다.
1. 최소 권한 원칙 (PoLP)
이것은 황금률입니다. 사용자나 애플리케이션이 의도된 기능을 수행하는 데 필요한 최소한의 권한만 부여하세요. 예:
- 보고 도구는
SELECT가 필요합니다. - 웹 애플리케이션은 일반적으로
SELECT,INSERT,UPDATE,DELETE가 필요합니다. - ETL 프로세스는
INSERT,UPDATE,DELETE,CREATE TABLE,DROP TABLE이 필요할 수 있습니다 (단, 특정 스테이징 스키마에만 해당).
2. 전용 사용자 계정
- 공유 계정 피하기: 각 애플리케이션, 서비스 또는 관리 사용자는 고유한 MySQL 사용자 계정을 가져야 합니다. 이는 감사 및 활동 추적에 도움이 됩니다.
- 애플리케이션에
root사용 금지: 애플리케이션이root사용자로 연결되도록 구성하지 마세요.root사용자는 무제한 액세스 권한을 가지며 인간 관리자가 중요한 관리 작업에만 사용해야 합니다.
3. 강력한 비밀번호 및 비밀번호 순환
- 모든 MySQL 사용자 계정에 대해 강력하고 고유한 비밀번호를 적용하세요. 가능하면 MySQL의 비밀번호 검증 플러그인을 활용하세요.
- 특히 높은 권한을 가진 계정에 대해 정기적인 비밀번호 순환 정책을 구현하세요.
4. 호스트 제한
- 가능하면 사용자 연결을 특정 IP 주소나 호스트 이름으로 제한하세요.
'%'를localhost, 애플리케이션 서버 IP 또는 네트워크 서브넷('user'@'192.168.1.%')으로 대체하세요. 이는 알 수 없는 위치에서의 무단 액세스 시도를 방지합니다.
5. 정기적인 감사 및 검토
- 모든 사용자 계정과 관련 권한을 정기적으로 검토하세요. 사용되지 않는 계정이나 불필요한 권한을 제거하세요.
SHOW GRANTS FOR 'user'@'host';를 사용하여 권한을 검사하세요.- 대규모 환경 감사를 위한 자동화 도구를 고려하세요.
6. 권한 문서화
- 데이터베이스 사용자, 역할 및 각 사용자에게 부여된 권한에 대한 명확한 문서를 유지하세요. 이는 일관성을 유지하고 보안 감사를 용이하게 합니다.
7. 개발, 스테이징 및 프로덕션 환경 분리
- 개발 또는 스테이징 환경에서 프로덕션 자격 증명을 절대 사용하지 마세요. 각 환경은 고유한 사용자와 권한 집합을 가져야 합니다.
8. 꼭 필요한 경우가 아니면 GRANT OPTION 피하기
WITH GRANT OPTION을 부여하면 권한 관리가 해당 사용자에게 위임되어 중앙 보안 정책을 우회할 수 있습니다. 매우 신뢰할 수 있는 관리 사용자에게만 가장 제한적인 범위로 예약하세요.
현재 권한 보기
사용자에게 할당된 권한을 확인하려면 SHOW GRANTS 명령을 사용하세요:
SHOW GRANTS FOR 'username'@'host';
예:
SHOW GRANTS FOR 'app_user'@'localhost';
출력은 다음과 같을 수 있습니다:
+-------------------------------------------------------------+
| Grants for app_user@localhost |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'app_user'@'localhost' |
| GRANT SELECT, INSERT, UPDATE ON `myapp_db`.* TO 'app_user'@'localhost' |
+-------------------------------------------------------------+
GRANT USAGE ON *.* 줄은 사용자에게 전역 권한이 없으며 연결 기능만 있음을 나타냅니다.
핵심 요점
MySQL 권한 관리를 좁고 검토 가능하게 유지하세요. 전용 계정을 만들고, 호스트를 제한하며, 가장 작은 유용한 범위에서 필요한 작업만 부여하고, 모든 변경 사항을 SHOW GRANTS로 확인하세요. 앱이나 사람이 더 이상 액세스할 필요가 없으면 권한을 회수하거나 계정을 삭제하여 오래된 자격 증명을 남기지 마세요.