도입
애플리케이션이 root로 접속하면 SQL Injection이나 인증 정보 유출 한 번으로 서버 전체가 위험해진다. 필요한 작업별 역할을 만들고, 계정의 접속 출발지와 TLS를 제한하면 사고의 범위를 줄일 수 있다.
아래 SQL은 실습용 app DB와 예시 사설망 10.20.30.%를 사용한다. 실제 망 구성에 맞게 더 좁은 호스트를 지정한다.
역할을 작업 단위로 분리
CREATE ROLE app_read;
CREATE ROLE app_write;
CREATE ROLE app_migrate;
GRANT SELECT ON app.* TO app_read;
GRANT SELECT, INSERT, UPDATE, DELETE ON app.* TO app_write;
GRANT CREATE, ALTER, INDEX, DROP ON app.* TO app_migrate;
일반 요청 계정에 DROP, ALTER, GRANT OPTION, 전역 FILE 권한을 주지 않는다. 마이그레이션 역할도 항상 켜 두기보다 배포 작업에만 사용한다.
호스트와 TLS를 제한한 계정
CREATE USER 'app_runtime'@'10.20.30.%'
IDENTIFIED BY 'REPLACE_WITH_RANDOM_SECRET'
REQUIRE SSL;
GRANT app_write TO 'app_runtime'@'10.20.30.%';
SET DEFAULT ROLE app_write FOR 'app_runtime'@'10.20.30.%';
'app_runtime'@'localhost'와 'app_runtime'@'10.20.30.%'는 다른 계정이다. 편의를 위해 'user'@'%'를 만들면 예상하지 못한 출발지까지 허용할 수 있다. 가능하면 애플리케이션 호스트 하나 또는 좁은 서브넷을 지정한다.
읽기 전용 작업은 별도 계정으로 분리한다.
CREATE USER 'report_reader'@'10.20.40.15'
IDENTIFIED BY 'REPLACE_WITH_ANOTHER_SECRET'
REQUIRE SSL;
GRANT app_read TO 'report_reader'@'10.20.40.15';
SET DEFAULT ROLE app_read FOR 'report_reader'@'10.20.40.15';
허용과 거부를 모두 시험
설정 문장만 보고 완료하지 않는다.
SHOW GRANTS FOR 'app_runtime'@'10.20.30.%';
SHOW CREATE USER 'app_runtime'@'10.20.30.%';
SHOW GRANTS FOR app_write;
애플리케이션 계정으로 TLS 접속한 뒤 확인한다.
SELECT CURRENT_USER(), CURRENT_ROLE();
SELECT * FROM app.orders LIMIT 1;
UPDATE app.orders SET status = status WHERE order_id = 1;
다음 문장은 실패해야 한다.
DROP DATABASE app;
CREATE USER 'unexpected'@'%';
SELECT * FROM mysql.user;
거부 테스트가 성공하면 권한 설계는 실패한 것이다. 클라이언트에서도 TLS 사용 여부와 인증서 검증 옵션을 확인한다. REQUIRE SSL은 암호화 연결을 요구하지만, 서버 신원 검증까지 어떻게 할지는 클라이언트의 CA 및 검증 설정과 함께 설계해야 한다.
마이그레이션 계정의 수명 제한
CREATE USER 'app_deployer'@'10.20.30.20'
IDENTIFIED BY 'REPLACE_WITH_DEPLOY_SECRET'
REQUIRE SSL ACCOUNT LOCK;
GRANT app_migrate TO 'app_deployer'@'10.20.30.20';
배포 승인 뒤 잠금을 풀고, 작업이 끝나면 다시 잠근다.
ALTER USER 'app_deployer'@'10.20.30.20' ACCOUNT UNLOCK;
-- 승인된 스키마 변경 수행
ALTER USER 'app_deployer'@'10.20.30.20' ACCOUNT LOCK;
자동화 환경에서는 장기 고정 비밀번호보다 비밀 관리 시스템과 교체 절차를 사용한다. 새 인증 정보로 접속을 확인한 뒤 기존 값을 폐기해야 서비스 중단을 피할 수 있다.
계정 폐기 절차
- 사용 주체와 최근 접속을 확인한다.
- 계정을 잠그고 영향 여부를 관찰한다.
- 연결 문자열과 secret을 교체한다.
- 충분한 관찰 뒤 계정을 삭제한다.
- 변경 명령과 승인자를 감사 로그에 남긴다.
계정 삭제는 복구가 어려우므로 잠금과 관찰을 먼저 사용한다.
점검 체크리스트
- 런타임과 배포 계정이 분리되어 있는가?
- 권한이
*.*가 아니라 필요한 DB·테이블 범위인가? - 계정의 host가 실제 접속 출발지로 제한되어 있는가?
- TLS가 강제되고 클라이언트가 서버 인증서를 검증하는가?
SHOW GRANTS뿐 아니라 허용·거부 쿼리를 시험했는가?- 인증 정보 교체와 계정 잠금 절차가 있는가?
함께 읽기
참고 자료
확인일: 2026-07-29
한 줄 요약
최소 권한은 역할만 만드는 일이 아니라 DB 범위, 접속 호스트, TLS, 거부 테스트와 계정 수명까지 함께 제한하는 일이다.
댓글 0