LLM WikiAccess-protected knowledge portal
← 스터디 홈
5편 · 약 20분

감사와 추적성: audit log, query log, access review

누가, 언제, 무엇을 했는가

보안 사고가 발생했을 때 가장 먼저 필요한 것은 타임라인이다. 어느 계정이 어느 테이블에 언제 접근했고, 어떤 쿼리를 실행했는가. 이 정보가 없으면 침해 범위를 파악할 수 없고, 규정 감사(audit)도 통과할 수 없다.

DBA와 데이터 엔지니어는 "로그는 남기고 있다"고 생각하지만 실제로 필요한 순간에 로그가 없거나, 저장 기간이 너무 짧거나, 구조화되지 않아 검색이 불가능한 경우가 많다.

이 장은 데이터베이스 감사 로그(audit log), 쿼리 로그(query log), 그리고 접근 검토(access review)를 운영 관점에서 다룬다.


1. 감사 로그(Audit Log)란 무엇인가

감사 로그는 데이터베이스에서 발생한 이벤트를 구조화된 형태로 기록한 것이다. 단순 오류 로그나 느린 쿼리 로그와는 목적이 다르다.

로그 종류목적포함 정보
Error log장애 진단에러 메시지, 시작/중단 이벤트
Slow query log성능 분석임계값 초과 쿼리, 실행 시간
General query log전수 쿼리 기록모든 SQL (성능 부담 큼)
Audit log보안·컴플라이언스접근 주체, 객체, 행위, 결과

감사 로그가 포함해야 할 핵심 필드는 다음과 같다.

  • who: 어떤 계정(user, application account)
  • from where: 어느 호스트/IP
  • what: 어떤 객체(database, table, view)에
  • how: 어떤 행위(SELECT, INSERT, UPDATE, DELETE, DDL, login, logout, privilege change)
  • when: 타임스탬프 (가능하면 UTC, 나노초)
  • result: 성공/실패, 영향받은 행 수
인프라 레이어 (DB 외부) 클라우드 API 로그 인스턴스 생성/삭제 설정 변경, 백업 트리거 네트워크/VPC 로그 접속 IP, 포트, 허용/차단 Security Group 변경 워크플로 레이어 (DB 내부) 스키마 변경 감사 DDL: CREATE/ALTER/DROP 권한 변경 GRANT/REVOKE 데이터 접근 감사 SELECT/INSERT/UPDATE 로그인 성공/실패 중앙 로그 수집 / SIEM CloudTrail / Stackdriver OpenSearch / Splunk / Datadog 보존: 최소 1년 (PCI DSS 3개월 hot + 1년 cold) 두 레이어를 함께 봐야 완전한 감사 타임라인이 완성된다 — 어느 한 쪽만으로는 "인스턴스를 누가 재시작했는가" 또는 "어느 계정이 어떤 행을 읽었는가"를 모두 답할 수 없다
감사 로그 아키텍처: 두 레이어 모델

2. MySQL 감사 로그 설정

2.1 General Query Log

general_log는 DB가 수신한 모든 SQL을 기록한다. 완전한 추적이 가능하지만 디스크 I/O와 성능 부담이 크다. 프로덕션 상시 활성화는 권장하지 않는다. 침해 의심 시나 감사 기간에 한시적으로 활성화하는 것이 일반적이다.

-- general log 활성화 (런타임 설정, 재시작 불필요)
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/general.log';

-- 확인
SHOW VARIABLES LIKE 'general_log%';

2.2 MySQL Enterprise Audit

MySQL Enterprise Edition은 audit_log 플러그인을 제공한다. Community Edition에서는 server_audit 플러그인(MariaDB Audit Plugin)으로 유사한 기능을 구현할 수 있다.

-- MySQL Enterprise: audit log 플러그인 설치 확인
SHOW PLUGINS;

-- audit_log_policy 설정 예시
-- ALL: 모든 이벤트, LOGINS: 로그인만, QUERIES: 쿼리만
SET GLOBAL audit_log_policy = 'ALL';

AWS RDS/Aurora MySQL: RDS에서는 general_log, slow_query_log를 파라미터 그룹에서 활성화한다. 로그는 CloudWatch Logs로 스트리밍해 장기 보존한다.


3. PostgreSQL 감사 로그 설정

3.1 기본 로깅 vs pgAudit

PostgreSQL 기본 로깅(postgresql.conf)은 에러, 연결, DDL 같은 서버 이벤트를 기록하지만 특정 테이블에 대한 SELECT 같은 세밀한 데이터 접근을 기록하지 않는다.

pgAudit 확장은 감사 목적의 상세 SQL 로깅을 추가한다. SOX, HIPAA, PCI DSS 감사를 통과하기 위한 표준 도구다.

-- pgAudit 설치 (postgresql.conf에 shared_preload_libraries 추가 필요)
-- shared_preload_libraries = 'pgaudit'

CREATE EXTENSION IF NOT EXISTS pgaudit;

-- 세션 수준: 모든 DDL과 데이터 쓰기 감사
SET pgaudit.log = 'ddl, write';

-- 특정 역할에 대한 객체 수준 감사
SET ROLE auditor;
GRANT SELECT ON TABLE users TO auditor;
SET pgaudit.role = 'auditor';
-- 이제 users 테이블에 대한 SELECT가 감사 로그에 남는다
pgaudit.log 카테고리포함 내용
readSELECT, COPY (읽기)
writeINSERT, UPDATE, DELETE, TRUNCATE
ddlCREATE, ALTER, DROP
roleGRANT, REVOKE, CREATE ROLE
function함수 호출
all전부 (성능 주의)

3.2 log_min_duration_statement와 slow query

# postgresql.conf
log_min_duration_statement = 1000  # 1초 이상 쿼리 기록 (ms)
log_connections = on               # 연결 이벤트
log_disconnections = on            # 종료 이벤트
log_line_prefix = '%t [%p] %u@%d '# 타임스탬프, pid, 사용자, DB

pg_stat_statements는 실시간 쿼리 통계를 누적한다. 감사 로그가 아닌 성능 분석 용도지만, 어떤 쿼리 패턴이 실행되었는지 파악하는 데 보완적으로 사용된다.


4. 쿼리 로그(Query Log)를 보안 감사에 활용하기

쿼리 로그는 원래 성능 분석용이지만 이상 접근 탐지에도 유용하다.

4.1 탐지할 수 있는 이상 패턴

대량 SELECT (full scan)
WHERE 없는 SELECT * FROM users
내부자에 의한 전체 고객 DB 다운로드 가능성
이전 접근 패턴 대비 급증 알림
로그인 실패 반복
5분 내 동일 IP에서 수십 회
brute force 시도 또는 잘못된 credential
즉시 IP 차단 자동화 검토
야간 또는 주말 DDL
DROP TABLE / ALTER 실행
변경 관리 정책 위반 또는 침해 시도
변경 관리 티켓과 대조
평소에 없던 계정의 접근
service-account-X가 users 테이블에 처음 SELECT
권한 남용 또는 침해된 서비스 계정
최소 권한 정책과 대조
쿼리 로그 기반 이상 탐지 패턴

4.2 로그를 구조화 데이터로 취급하기

로그를 텍스트 파일로 쌓으면 검색이 어렵다. 구조화 로그(JSON/structured format) 로 수집해 검색 엔진(OpenSearch, Elasticsearch, Loki)에 인덱싱해야 한다.

{
  "timestamp": "2026-07-04T08:23:11.342Z",
  "db_host": "db-prod-01.internal",
  "user": "analytics-svc",
  "client_ip": "10.0.4.22",
  "db_name": "orders",
  "query_type": "SELECT",
  "table": "users",
  "rows_examined": 1250000,
  "duration_ms": 3420,
  "query_hash": "a7f3e2c1"
}

rows_examined가 비정상적으로 크거나, 평소에 접근하지 않는 계정이 접근하는 패턴을 임계값 알림으로 설정한다.


5. 접근 검토 (Access Review)

감사 로그가 "무슨 일이 있었는가"를 기록한다면, 접근 검토는 "지금 누가 무엇에 접근할 수 있는가"를 주기적으로 검증하는 프로세스다.

5.1 왜 접근 검토가 필요한가

권한은 누적된다. 직무가 바뀌거나 퇴사해도 DB 계정이 남는다. 프로젝트가 끝난 서비스 계정에 여전히 DML 권한이 있다. 개발자가 장애 대응을 위해 임시로 받은 production 권한이 반납되지 않는다.

5.2 분기별 접근 검토 절차

① 권한 목록 추출 DB user 전체 테이블별 권한 목록 마지막 접속 일시 ② 소유자 대조 계정 소유 팀/인물 현재 직무 확인 퇴사·이직 여부 ③ 불필요 권한 식별 90일 이상 미접속 계정 과잉 권한(ALL PRIVILEGES) 임시 권한 만료 확인 ④ 정리 실행 REVOKE / DROP USER 권한 최소화 변경 이력 티켓 기록 ⑤ 증적 보관 검토 전/후 권한 승인자 서명 컴플라이언스 보관 분기 1회 수행 권장 (SOC 2, PCI DSS 등 규정에 따라 빈도 조정)
분기별 접근 검토 흐름

5.3 MySQL에서 권한 목록 추출

-- 전체 사용자 권한 조회
SELECT user, host, account_locked, password_expired
FROM mysql.user
ORDER BY user;

-- 특정 사용자 권한
SHOW GRANTS FOR 'analytics-svc'@'%';

-- 테이블 수준 권한 전체 조회
SELECT grantee, table_schema, table_name, privilege_type
FROM information_schema.TABLE_PRIVILEGES
ORDER BY grantee, table_schema, table_name;

-- 마지막 접속 시간 (performance_schema 활성화 필요)
SELECT user, host, CURRENT_CONNECTIONS, TOTAL_CONNECTIONS
FROM performance_schema.accounts
WHERE user NOT LIKE 'mysql%';

5.4 PostgreSQL에서 권한 목록 추출

-- 전체 역할 목록
SELECT rolname, rolsuper, rolcreatedb, rollogin, rolvaliduntil
FROM pg_roles
ORDER BY rolname;

-- 테이블별 권한 목록
SELECT grantee, table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee NOT IN ('PUBLIC', 'postgres')
ORDER BY grantee, table_name;

-- 역할 멤버십 확인
SELECT r.rolname AS role, m.rolname AS member
FROM pg_auth_members am
JOIN pg_roles r ON r.oid = am.roleid
JOIN pg_roles m ON m.oid = am.member
ORDER BY r.rolname;

6. 감사 로그 보존과 변조 방지

6.1 보존 기간 요건

규정최소 보존 기간
PCI DSS1년 (최근 3개월 즉시 조회 가능)
HIPAA6년
SOC 21년
GDPR명시 없음, 목적에 필요한 기간

6.2 로그 변조 방지

감사 로그가 침해 이후 삭제되면 사고 조사가 불가능해진다.

Write-Once 스토리지: S3 Object Lock(Compliance mode), AWS CloudTrail Digest, GCS Retention Policy처럼 삭제/수정이 불가능한 스토리지에 저장한다.

로그를 DB와 분리: 감사 로그를 감사 대상 DB 서버에 저장하면 DB 침해 시 로그도 함께 삭제될 수 있다. 중앙 로그 시스템(CloudWatch Logs, Loki, OpenSearch)으로 즉시 스트리밍한다.

로그 무결성 검증: CloudTrail은 로그 파일 해시를 포함한 Digest 파일을 매 시간 생성한다. 로그가 변조되었는지 aws cloudtrail validate-logs 명령으로 검증할 수 있다.

6.3 로그 접근 권한 분리

감사 로그를 조작할 수 있는 계정과 DB를 운영하는 계정은 분리되어야 한다. DBA가 자신의 작업을 감사 로그에서 지울 수 없는 구조가 되어야 한다.


7. 운영 체크리스트

항목확인 방법
MySQL/PostgreSQL 감사 로그가 활성화되어 있는가?SHOW VARIABLES LIKE '%audit%', pgAudit extension
로그에 접속 계정, 클라이언트 IP, 실행 쿼리가 포함되는가?로그 샘플 확인
로그가 중앙 시스템으로 실시간 스트리밍되는가?CloudWatch Logs, OpenSearch 수집 상태
로그 보존 기간이 규정 요건을 충족하는가?S3 lifecycle 또는 로그 시스템 retention 정책
로그 저장소가 변조·삭제로부터 보호되는가?S3 Object Lock, Write-Once 설정
로그인 실패 반복, 대량 SELECT 알림이 설정되어 있는가?SIEM 알림 규칙, Datadog monitor
분기별 접근 검토가 수행되고 그 결과가 보관되는가?검토 문서, 티켓 이력
90일 이상 미접속 DB 계정이 잠금 또는 삭제되는가?information_schema.PROCESSLIST, pg_roles 조회

8. 흔한 실수

"로그는 쌓고 있다, 그런데 본 적은 없다": 로그가 있어도 정기적으로 검토하지 않으면 침해를 수개월 후에야 발견한다. 주요 이상 패턴에 대한 자동 알림을 반드시 설정해야 한다.

"audit log를 DB 서버 로컬 디스크에만 저장": DB 서버가 침해되거나 디스크가 꽉 차면 로그가 사라진다. 외부로 즉시 스트리밍해야 한다.

"DBA도 감사 로그를 삭제할 수 있다": DBA 자신의 행위를 DBA가 지울 수 있으면 감사 로그가 무의미하다. 로그 저장소는 DBA의 쓰기 권한 밖에 있어야 한다.

"접근 검토를 한 번도 안 했다": SOC 2나 PCI DSS 감사에서 접근 검토 기록을 요구한다. 기록이 없으면 통제 실패로 처리된다.


마무리: 감사 로그는 보험이 아니라 운영 도구다

감사 로그는 "규정 때문에 켜두는 것"이 아니다. 비정상 접근을 조기에 탐지하고, 사고 발생 시 원인을 파악하고, 접근 검토로 권한 과잉을 예방하는 일상 운영 도구다.

DBA와 데이터 플랫폼 엔지니어는 로그를 켜는 것에서 끝내지 않고, 로그를 검색하고 경보하고 보존하는 체계까지 갖추어야 한다. 사고가 났을 때 "로그가 없어서 모르겠다"는 상황은 기술적 실패이기 전에 운영 실패다.

다음 장에서는 백업 자체를 보호하는 방법인 immutable backup, 랜섬웨어 대응, 복구 권한 분리를 다룬다.

References

  • pgAudit GitHub Repository: https://github.com/pgaudit/pgaudit
  • PostgreSQL Documentation, "pgAudit": https://www.postgresql.org/about/news/pgaudit-10-released-1542/
  • MySQL Documentation, "The Audit Log Plugin": https://dev.mysql.com/doc/refman/8.0/en/audit-log.html
  • Neon Blog, "The Difference Between Postgres Logging and PGAudit": https://neon.com/blog/postgres-logging-vs-pgaudit
  • Bytebase, "Database Audit Logging: Two Layers, One Trail": https://www.bytebase.com/blog/database-audit-logging/
  • StrongDM, "Audit Log Review and Management Explained": https://www.strongdm.com/blog/audit-log-review-management
  • AWS Documentation, "AWS CloudTrail Log File Validation": https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-intro.html
  • PCI DSS v4.0 Requirements 10: Logging and Monitoring: https://www.pcisecuritystandards.org/document_library/
  • Datadog, "What is Audit Logging?": https://www.datadoghq.com/knowledge-center/audit-logging/