Tại sao log mặc định của PostgreSQL là chưa đủ?
Làm DevOps hay quản trị Database (DBA), chắc hẳn bạn đã từng rơi vào cảnh dở khóc dở cười: Sáng ra thấy bảng users quan trọng biến mất, hoặc dữ liệu đơn hàng bị sửa lung tung mà check log hệ thống thì chỉ thấy thông tin chung chung. PostgreSQL có tham số log_statement, nhưng nếu bật nó lên mức all, file log có thể cán mốc hàng chục GB chỉ sau vài giờ vì nó ghi lại tất cả mọi thứ, kể cả các câu lệnh nội bộ của hệ thống.
Vấn đề là chúng ta cần sự chi tiết nhưng phải có tính chọn lọc. Chúng ta cần biết chính xác Ai đã xóa bảng, Lúc nào họ thực hiện, và tác động lên Bản ghi nào. Đây là yêu cầu bắt buộc để phục vụ việc truy vết (audit) hoặc đáp ứng các tiêu chuẩn bảo mật khắt khe như PCI-DSS hay SOC2. Đó là lý do mình chọn pgaudit (PostgreSQL Audit Extension) làm giải pháp thay thế.
pgaudit – “Mắt thần” soi mọi ngóc ngách Database
Khác với cơ chế logging thông thường, pgaudit cho phép ghi lại các hành động trên database cực kỳ chi tiết thông qua hạ tầng logging tiêu chuẩn của PostgreSQL. Theo kinh nghiệm triển khai của mình, pgaudit thường chỉ gây ra khoảng 5-7% overhead về hiệu năng, con số hoàn toàn chấp nhận được so với lợi ích bảo mật nó mang lại.
Có hai chế độ cốt lõi mà anh em cần phân biệt rõ:
- Session Audit Logging: Ghi lại mọi hoạt động của một User cụ thể trong suốt phiên làm việc. Đây là cách phổ biến nhất để giám sát các tài khoản có quyền cao (Superuser).
- Object Audit Logging: Tập trung vào các bảng nhạy cảm. Ví dụ, bạn chỉ muốn theo dõi ai đã sờ vào bảng
credit_cards, còn các bảnglogs_vặtkhác thì bỏ qua cho nhẹ máy.
Một điểm cộng lớn là pgaudit không thay thế cơ chế log cũ mà nó chạy song hành, giúp việc quản lý log tập trung qua các công cụ như ELK trở nên cực kỳ đơn giản.
Bắt tay vào cài đặt pgaudit lên server
Dưới đây là các bước mình thực hiện trên Ubuntu 22.04 và PostgreSQL 15. Với các phiên bản khác, anh em chỉ cần thay đổi số phiên bản tương ứng là xong.
1. Cài đặt package
Đầu tiên, hãy tải extension này từ repository chính thức của hệ điều hành:
sudo apt update
sudo apt install postgresql-15-pgaudit
2. Khai báo trong cấu hình hệ thống
Cài xong thì pgaudit vẫn chưa hoạt động ngay. Bạn cần ép Postgres phải “load” nó lên mỗi khi khởi động bằng cách sửa file postgresql.conf (thường nằm tại /etc/postgresql/15/main/postgresql.conf).
Tìm dòng shared_preload_libraries và thêm pgaudit vào:
shared_preload_libraries = 'pgaudit'
Sau đó, khởi động lại service để thay đổi có hiệu lực. Nhớ kiểm tra trạng thái service sau khi restart nhé:
sudo systemctl restart postgresql
3. Kích hoạt Extension trong Database
Bước cuối cùng là login vào psql và tạo extension cho database mục tiêu:
CREATE EXTENSION pgaudit;
Gõ lệnh \dx để chắc chắn rằng cái tên pgaudit đã xuất hiện trong danh sách extension đã cài đặt.
Cấu hình chi tiết để “soi” đúng người, đúng việc
Đây là phần quan trọng nhất để tránh bị ngập lụt trong log. pgaudit chia các lệnh thành nhiều nhóm: READ, WRITE, FUNCTION, ROLE, DDL, MISC…
Case thực tế mình hay dùng là chỉ log các lệnh thay đổi cấu trúc và thay đổi dữ liệu để tiết kiệm dung lượng ổ cứng:
-- Chỉ ghi log các lệnh DDL (tạo/xóa bảng), WRITE (insert/update) và ROLE (tạo user)
ALTER SYSTEM SET pgaudit.log = 'write, ddl, role';
-- Đừng quên reload để Postgres áp dụng cấu hình mới
SELECT pg_reload_conf();
Lưu ý: Nếu bạn bật READ cho các bảng có hàng triệu lượt truy vấn mỗi phút, file log sẽ phình ra với tốc độ chóng mặt. Hãy cân nhắc kỹ!
Mẹo nhỏ cho anh em: Khi phải xử lý đống log khổng lồ hoặc cần convert dữ liệu khách hàng từ CSV sang JSON để kiểm tra lỗi truy vấn, mình hay dùng công cụ tại toolcraft.app/vi/tools/data/csv-to-json. Nó chạy thuần trên trình duyệt nên dữ liệu nhạy cảm không bị đẩy lên server, cực kỳ an toàn cho dân làm DB.
Test thử xem “camera” đã chạy chưa
Hãy thử tạo một cái bảng và xóa nó đi xem log hiện ra những gì:
CREATE TABLE secret_info (id serial, content text);
INSERT INTO secret_info (content) VALUES ('Dữ liệu nhạy cảm của khách hàng');
DROP TABLE secret_info;
Mở file log tại /var/log/postgresql/postgresql-15-main.log, bạn sẽ thấy những dòng “vàng ngọc” như thế này:
AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.secret_info,CREATE TABLE secret_info (id serial, content text);,<not logged>
AUDIT: SESSION,2,1,WRITE,INSERT,TABLE,public.secret_info,INSERT INTO secret_info (content) VALUES ('Dữ liệu nhạy cảm của khách hàng');,<not logged>
AUDIT: SESSION,3,1,DDL,DROP TABLE,TABLE,public.secret_info,DROP TABLE secret_info;,<not logged>
Thông tin cực kỳ minh bạch: Bạn biết rõ câu lệnh nào đã xóa bảng secret_info và vào thời điểm nào. Hết đường chối cãi!
Bí kíp sống còn về hiệu suất và lưu trữ
Đừng vì quá ham bảo mật mà làm sập server. Việc ghi log liên tục sẽ vắt kiệt I/O của ổ cứng nếu bạn không biết cách tối ưu:
- Lọc log thông minh: Chỉ bật
pgaudit.log = 'all'khi thực sự cần debug lỗi nghiêm trọng trong thời gian ngắn. - Cấu hình Log Rotation: Đảm bảo PostgreSQL tự động cắt file log theo ngày hoặc khi đạt dung lượng (ví dụ 100MB). Nếu không, server sẽ chết đứng vì đầy ổ cứng chỉ sau một đêm.
- Chuyển log đi nơi khác: Với hệ thống Production, hãy dùng
rsysloghoặcFluentdđể đẩy log về tập trung tại ELK hoặc Grafana Loki. Việc này giúp bạn tra cứu nhanh mà không làm nặng server database.
Lời kết
Triển khai pgaudit là bước đi chuyên nghiệp để nâng cấp bảo mật cho hệ thống PostgreSQL. Nó giúp bạn loại bỏ sự mập mờ, giúp việc điều tra sự cố nhanh hơn gấp nhiều lần so với việc mò mẫm log mặc định.
Hy vọng bài viết này giúp anh em tự tin hơn khi làm việc với Database Auditing. Nếu gặp lỗi gì lúc cài đặt, cứ thoải mái để lại comment, mình sẽ hỗ trợ giải đáp ngay!

