본문으로 건너뛰기

9.6 감사 (pgaudit)

pgaudit은 PostgreSQL의 표준 감사 로그 확장입니다. PostgreSQL 기본 로그(log_statement)는 쿼리 텍스트만 남기지만, 컴플라이언스 감사에는 누가, 언제, 어떤 객체에, 어떤 작업을했는지의 구조화된 정보가 필요합니다. pgaudit가 이를 채웁니다.

기본 log_statement와의 차이

항목log_statementpgaudit
로깅 단위쿼리 텍스트 전체객체별 구조화
카테고리 분류없음READ, WRITE, FUNCTION, ROLE, DDL, MISC
객체별 필터없음가능
트랜잭션 ID·세션 정보log_line_prefix 필요항상 포함
SQL 텍스트 정규화없음parameterized 가능

설치

PGDG 패키지에 포함합니다.

sudo dnf install -y pgaudit_17       # RHEL/Rocky
sudo apt-get install -y postgresql-17-pgaudit   # Debian/Ubuntu

postgresql.conf:

shared_preload_libraries = 'pgaudit'   # 다른 라이브러리와 콤마로

restart 후 데이터베이스 단위 활성:

CREATE EXTENSION pgaudit;

두 가지 모드

모드동작
session세션 단위 — pgaudit.log 파라미터로 카테고리 지정
object객체 단위 — pgaudit.role 역할에 GRANT된 객체만

session audit

ALTER SYSTEM SET pgaudit.log = 'write, ddl, role';
SELECT pg_reload_conf();
카테고리포함
READSELECT, COPY FROM
WRITEINSERT, UPDATE, DELETE, COPY TO
FUNCTION함수 호출
ROLEGRANT, REVOKE, CREATE ROLE 등
DDLCREATE/DROP/ALTER
MISCDISCARD, FETCH, CHECKPOINT
ALL위 전부
-READREAD 제외

운영 권장 출발: write, ddl, role — 변경 작업만 기록. READ까지 켜면 로그가 폭증합니다.

object audit

특정 역할에게 GRANT된 객체에만 감사 로그 생성합니다.

-- 감사 역할
CREATE ROLE audit_role NOLOGIN;
ALTER SYSTEM SET pgaudit.role = 'audit_role';
SELECT pg_reload_conf();

-- 감사 대상 객체 — audit_role에 GRANT
GRANT SELECT, INSERT, UPDATE, DELETE ON sensitive_data TO audit_role;

이제 sensitive_data 테이블의 모든 변경이 자동 로깅. 민감 테이블만 선별 감사 가능합니다.

로그 형식

2026-05-23 10:00:00.000 KST [12345] alice@app_main LOG:  AUDIT: SESSION,1,1,WRITE,UPDATE,TABLE,public.users,UPDATE users SET email = $1 WHERE id = $2,"<not logged>"
컬럼의미
AUDIT: SESSION 또는 OBJECT모드
1,1session id, statement id
WRITE카테고리
UPDATE명령
TABLE객체 종류
public.users객체
UPDATE users ...SQL (parameterized)
"<not logged>"파라미터 — pgaudit.log_parameter로 켤 수 있음

자주 쓰는 설정

# postgresql.conf
shared_preload_libraries = 'pgaudit'
pgaudit.log = 'write, ddl, role'
pgaudit.log_catalog = off              # pg_catalog 자동 쿼리 제외
pgaudit.log_client = on                # 클라이언트 IP 포함
pgaudit.log_level = log                # log/info/notice/warning
pgaudit.log_parameter = off            # 파라미터 노출 (개인정보 위험 시 off)
pgaudit.log_relation = on              # 객체 정보 명시
pgaudit.log_statement_once = on        # 같은 statement 중복 로그 방지

log_parameter = on은 SQL injection 진단·재현에 유용하지만 비밀번호·개인정보가 로그에 평문으로 흐를 수 있어 신중히 진행합니다.

로그 라우팅

pgaudit은 PostgreSQL의 일반 로그와 같은 곳으로 출력된다(postgresql-*.log). 별도 파일이 필요하면 log_destination을 분리하거나 외부 수집기(Fluent Bit, Loki, Datadog)에 라우팅.

log_destination = 'stderr, csvlog'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'

CSV 로그는 구조화라 분석 도구가 더 잘 다룹니다.

운영 시 주의

주의메모
READ까지 켜면 로그 폭증TPS 큰 시스템에서 1TB/일 가능
log_parameter = on은 개인정보 노출컴플라이언스에서 마스킹 필요
로그 디스크 분리 권장데이터 디스크와 같으면 IO 경합
외부 수집 권장로컬 로그는 회전·압축·보존 정책
감사 로그 자체에 대한 권한일반 사용자 읽기 불가

컴플라이언스와의 매핑

표준pgaudit 활용
PCI-DSS카드 데이터 테이블 object audit
HIPAA의료 데이터 SELECT/WRITE 모두 audit
GDPR개인정보 컬럼이 든 테이블 object audit
한국 개인정보보호법접속·접근 로그 1년 보존

대안과 짝

도구보완하는 것
기본 log_statement가벼운 디버깅 — pgaudit 없이도 사용 가능
auto_explain슬로우 쿼리의 EXPLAIN 자동
외부 SIEM (Splunk, ELK)pgaudit 로그를 수집·분석
클라우드 매니지드 auditRDS/NCP/Azure는 자체 감사 기능 — pgaudit 통합 여부 확인
pgaudit은 감사 로그를 만들 뿐 — 보안 위반을 막지는 않습니다. 침입 탐지·예방은 별도 — pg_hba.conf, RLS, GRANT, TLS와 같이 운영해야 의미.

자동화 — 감사 대상 변경 감지

-- 감사 대상 객체 목록
SELECT table_schema, table_name
  FROM information_schema.table_privileges
 WHERE grantee = 'audit_role';

월 단위 점검 — 새로 만들어진 민감 테이블이 audit_role에 GRANT됐는지 확인합니다.

정리

  • pgaudit = 구조화된 감사 로그. PostgreSQL 기본 로그의 한계 보완
  • 두 모드: session(카테고리 기반) + object(역할 기반)
  • 운영 출발: write, ddl, role — READ는 신중히
  • log_parameter는 보안 vs 디버깅 트레이드오프
  • 로그 라우팅·디스크 분리·보존 정책 동반 필요
  • 감사 로그는 기록일 뿐, 예방은 RLS·GRANT·TLS와 함께

다음 절(9.7)에서는 외부 ID 제공자 통합 — LDAP, Kerberos, PAM, OAuth를 봅니다.