Cấu hình PostgreSQL để ghi nhận sự kiện truy cập dữ liệu đã mã hóa
Để PostgreSQL ghi nhận các truy vấn truy cập vào dữ liệu đã mã hóa (encrypted columns), ta cần kích hoạt module pgaudit và cấu hình chính sách ghi log cụ thể cho các bảng hoặc cột chứa dữ liệu nhạy cảm.
Tại sao cần làm điều này: Mặc dù TDE (Transparent Data Encryption) bảo vệ dữ liệu khi lưu trữ (at rest), nhưng khi dữ liệu được tải vào RAM để xử lý, nó sẽ ở dạng plain text. Audit log giúp xác định ai đã truy cập dữ liệu nhạy cảm đó, vào thời điểm nào và bằng câu lệnh gì.
Thay đổi cấu hình file /etc/postgresql/15/main/postgresql.conf (giả sử version 15, điều chỉnh theo version thực tế của bạn).
shared_preload_libraries = 'pgaudit,pgcrypto'
pgaudit.log = 'DML,DDL,ROLE'
pgaudit.log_parameter = on
pgaudit.log_client_cert = on
Kết quả mong đợi: Sau khi restart PostgreSQL, mọi lệnh INSERT, UPDATE, DELETE (DML) và thay đổi cấu trúc (DDL) đều được ghi vào log file với thông tin chi tiết.
Cấu hình Log Rotation và Nén Audit Log tự động
Log audit có thể phát triển rất nhanh, đặc biệt khi bật logging cho toàn bộ DML. Cần sử dụng logrotate để tự động cắt, nén và xóa log cũ nhằm tránh đầy ổ đĩa.
Tạo file cấu hình rotation riêng cho audit log tại đường dẫn /etc/logrotate.d/postgresql-audit.
/var/log/postgresql/postgresql-15-main.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 postgres postgres
postrotate
/usr/lib/postgresql/15/bin/pg_ctl reload -D /var/lib/postgresql/15/main > /dev/null 2>&1
endscript
}
Giải thích: File này cấu hình quay vòng log hàng ngày, giữ lại 14 ngày, nén file cũ (gzip) và trigger reload PostgreSQL để nó nhận diện file log mới.
Thử nghiệm cấu hình bằng lệnh kiểm tra syntax:
logrotate -d /etc/logrotate.d/postgresql-audit
Kết quả mong đợi: Không có lỗi (no errors) và thông báo mô phỏng quá trình quay vòng file log.
Tích hợp quy trình kiểm tra tính toàn vẹn dữ liệu sau mã hóa
Sau khi dữ liệu được mã hóa và truy cập, cần có quy trình để đảm bảo dữ liệu không bị thay đổi trái phép (tampering) hoặc log audit bị xóa.
Tạo script kiểm tra định kỳ tại /usr/local/bin/check_tde_audit_integrity.sh.
#!/bin/bash
# Script kiểm tra tính toàn vẹn của log audit và dữ liệu TDE
AUDIT_LOG="/var/log/postgresql/postgresql-15-main.log"
CHECKSUM_FILE="/var/log/postgresql/audit_checksum.log"
DB_USER="postgres"
DB_NAME="production_db"
# 1. Kiểm tra tính liên tục của log (gap detection)
# So sánh timestamp dòng cuối cùng với dòng hiện tại
if [ -f "$AUDIT_LOG" ]; then
LAST_LINE=$(tail -n 1 $AUDIT_LOG)
CURRENT_TIME=$(date +"%Y-%m-%d %H:%M:%S")
# Logic đơn giản: Nếu log quá 5 phút không cập nhật (tùy môi trường)
# Ở đây chỉ demo việc ghi checksum mới
md5sum "$AUDIT_LOG" > "$CHECKSUM_FILE.new"
if [ -f "$CHECKSUM_FILE" ]; then
if diff "$CHECKSUM_FILE" "$CHECKSUM_FILE.new" > /dev/null; then
echo "AUDIT OK: Log file checksum matches."
else
echo "AUDIT ALERT: Log file has been modified or rotated."
# Gửi cảnh báo (ví dụ: mail, slack)
# echo "AUDIT ALERT..." | mail -s "Audit Alert" admin@example.com
fi
fi
mv "$CHECKSUM_FILE.new" "$CHECKSUM_FILE"
else
echo "ERROR: Audit log file not found."
exit 1
fi
# 2. Kiểm tra dữ liệu TDE trong DB (Sample check)
# Chạy query để đảm bảo cột encrypted vẫn tồn tại và có dữ liệu
RESULT=$(psql -U $DB_USER -d $DB_NAME -t -c "SELECT COUNT(*) FROM sensitive_data WHERE encrypted_column IS NOT NULL;")
if [ "$RESULT" -gt 0 ]; then
echo "TDE OK: $RESULT encrypted records found in sensitive_data table."
else
echo "TDE WARNING: No encrypted records found in sensitive_data."
fi
Cấp quyền thực thi cho script:
chmod +x /usr/local/bin/check_tde_audit_integrity.sh
Thêm vào crontab để chạy hàng giờ:
0 * * * * /usr/local/bin/check_tde_audit_integrity.sh >> /var/log/tde_audit_check.log 2>&1
Kết quả mong đợi: File log /var/log/tde_audit_check.log xuất hiện các dòng "AUDIT OK" và "TDE OK" sau mỗi giờ, xác nhận dữ liệu và log đang an toàn.
Verify toàn bộ quy trình vận hành
Thực hiện các bước kiểm tra cuối cùng để đảm bảo Audit và TDE hoạt động đồng bộ.
1. Tạo dữ liệu thử nghiệm và kiểm tra log
Chèn một bản ghi vào bảng đã mã hóa và kiểm tra xem log có ghi nhận không.
psql -U postgres -d production_db -c "INSERT INTO sensitive_data (id, encrypted_column) VALUES (999, pgcrypto.pgen_random_bytea(32));"
Kiểm tra log ngay lập tức:
grep "INSERT" /var/log/postgresql/postgresql-15-main.log | tail -n 5
Kết quả mong đợi: Xuất hiện dòng log chứa USER=postgres, DATABASE=production_db và câu lệnh INSERT INTO sensitive_data.
2. Kiểm tra tính bảo mật của log đã nén
Đảm bảo file log đã nén (sau khi rotate) chỉ có thể đọc bởi user postgres.
ls -la /var/log/postgresql/*.gz
Kết quả mong đợi: File có quyền -rw-r----- (640) và owner là postgres postgres.
3. Xác minh tính toàn vẹn dữ liệu
Chạy thủ công script kiểm tra và xem kết quả ngay lập tức.
/usr/local/bin/check_tde_audit_integrity.sh
Kết quả mong đợi: Màn hình xuất hiện AUDIT OK và TDE OK kèm số lượng bản ghi mã hóa.
Điều hướng series:
Mục lục: Series: Triển khai Database an toàn với Transparent Data Encryption và Audit trên Linux
« Phần 3: Triển khai Transparent Data Encryption (TDE) với pgcrypto
Phần 5: Kiểm tra, Troubleshooting và tối ưu hóa hiệu năng »