Cấu hình SSL/TLS cho giao tiếp nội bộ và Client
Thực hiện tạo chứng chỉ tự ký (Self-signed CA) và chứng chỉ cho từng nút (node) để bảo mật kênh truyền tải dữ liệu giữa các thành viên trong cụm Raft và giữa Client với Database.
Mục đích: Đảm bảo tính bảo mật (Encryption) và xác thực (Authentication) cho mọi gói tin mạng, ngăn chặn tấn công Man-in-the-Middle (MitM) trong quá trình đồng bộ dữ liệu nhạy cảm.
Kết quả mong đợi: PostgreSQL chấp nhận kết nối chỉ khi trình bày chứng chỉ hợp lệ, các kết nối không an toàn bị từ chối.
Trước tiên, tạo thư mục chứa chứng chỉ trên tất cả các nút (Leader và Follower) để đồng bộ cấu trúc.
mkdir -p /var/lib/ssl/cluster
chmod 700 /var/lib/ssl/cluster
Kết quả: Thư mục được tạo với quyền truy cập hạn chế (chỉ root hoặc user postgres) để bảo vệ khóa riêng tư.
Tiếp theo, tạo Certificate Authority (CA) trên nút Leader. Đây là bước tạo "căn cước công dân" cho toàn bộ cụm.
cd /var/lib/ssl/cluster
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=VN/ST=HCM/C=PostgreSQL Cluster/O=DBA Team"
Kết quả: File ca.key và ca.crt được tạo, dùng để ký cho các chứng chỉ của nút và client.
Tạo chứng chỉ riêng cho mỗi nút (Node1, Node2, Node3). Thay thế bằng hostname thực tế của từng máy.
openssl req -new -keyout node1.key -out node1.csr -subj "/CN=node1"
openssl x509 -req -days 365 -in node1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out node1.crt -extfile
Lặp lại lệnh trên cho node2 và node3, thay đổi CN và IP address tương ứng trong phần subjectAltName.
Kết quả: Mỗi nút có cặp file .key và .crt riêng, được ký bởi CA chung, chứa thông tin định danh đúng của nút đó.
Cấu hình file postgresql.conf để kích hoạt SSL cho cả kết nối client và giao tiếp nội bộ (Raft). Áp dụng trên tất cả các nút.
cat >> /var/lib/postgresql/data/postgresql.conf
Kết quả: File cấu hình được cập nhật, yêu cầu TLSv1.2 trở lên cho mọi kết nối.
Cấu hình file pg_hba.conf để yêu cầu xác thực bằng chứng chỉ (cert) cho các kết nối nội bộ và client.
cat > /var/lib/postgresql/data/pg_hba.conf
Kết quả: Bất kỳ kết nối nào không sử dụng SSL hoặc không có chứng chỉ hợp lệ sẽ bị từ chối ngay lập tức.
Khởi động lại dịch vụ PostgreSQL để áp dụng cấu hình mới.
systemctl restart postgresql
Kiểm tra trạng thái SSL và xác thực chứng chỉ.
psql -h node1 -U replicator -c "SELECT ssl, version();" -c "SHOW ssl_cert_file;"
Kết quả: Cột ssl trả về giá trị "t" (true), xác nhận kết nối được mã hóa.
Triển khai Role-Based Access Control (RBAC) chi tiết
Xây dựng hệ thống phân quyền chi tiết (RBAC) để áp dụng nguyên tắc Least Privilege (tối thiểu đặc quyền) trong môi trường phân tán.
Mục đích: Ngăn chặn truy cập trái phép, đảm bảo người dùng chỉ có quyền truy cập vào dữ liệu cần thiết cho vai trò cụ thể của họ, đặc biệt quan trọng khi dữ liệu đã được mã hóa TDE.
Kết quả mong đợi: Các role được phân tách rõ ràng (Admin, App, Replicator), không có role nào có quyền vượt quá mức cần thiết.
Tạo các Role cơ bản: một role cho quản trị viên (superuser), một role cho ứng dụng (app_user), và một role cho sao chép (replicator).
psql -U postgres -c "CREATE ROLE db_admin WITH LOGIN SUPERUSER PASSWORD 'StrongPassword@2024';"
psql -U postgres -c "CREATE ROLE app_user WITH LOGIN PASSWORD 'AppSecurePass!';"
psql -U postgres -c "CREATE ROLE replicator WITH LOGIN REPLICATION PASSWORD 'RaftSyncKey#99';"
Kết quả: Các role được tạo trong catalog của PostgreSQL, sẵn sàng để cấp quyền.
Cấp quyền cụ thể cho role app_user. Chỉ cho phép SELECT, INSERT, UPDATE, DELETE trên các bảng nghiệp vụ, không cho phép DROP TABLE hay ALTER DATABASE.
psql -U postgres -c "GRANT USAGE ON SCHEMA public TO app_user;"
psql -U postgres -c "GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;"
psql -U postgres -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;"
psql -U postgres -c "REVOKE ALL ON DATABASE cluster_db FROM app_user;"
Kết quả: Role app_user chỉ thao tác được dữ liệu, không thể thay đổi cấu trúc database.
Cấu hình quyền cho role replicator. Chỉ cho phép quyền REPLICATION để tham gia vào cụm Raft, không cho phép truy cập dữ liệu thông thường.
psql -U postgres -c "GRANT CONNECT ON DATABASE cluster_db TO replicator;"
psql -U postgres -c "GRANT REPLICATION TO replicator;"
psql -U postgres -c "REVOKE ALL ON SCHEMA public FROM replicator;"
Kết quả: Role replicator có thể tham gia vào quá trình đồng bộ dữ liệu nhưng không thể đọc/truy vấn dữ liệu nghiệp vụ (SELECT * FROM ...).
Thiết lập default privileges để các bảng mới được tạo trong tương lai tự động thừa hưởng quyền của app_user.
psql -U postgres -c "ALTER DEFAULT PRIVILEGES FOR ROLE db_admin IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;"
psql -U postgres -c "ALTER DEFAULT PRIVILEGES FOR ROLE db_admin IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO app_user;"
Kết quả: Khi db_admin tạo bảng mới, app_user sẽ tự động có quyền truy cập bảng đó mà không cần cấp quyền lại.
Verify quyền truy cập bằng cách đăng nhập với role app_user và thử thực hiện lệnh bị cấm.
PGPASSWORD='AppSecurePass!' psql -h localhost -U app_user -c "DROP TABLE public.users;"
Kết quả mong đợi: Lệnh bị từ chối với thông báo lỗi "permission denied for table users" hoặc "permission denied for schema public".
PGPASSWORD='RaftSyncKey#99' psql -h localhost -U replicator -c "SELECT * FROM public.users;"
Kết quả mong đợi: Lệnh bị từ chối với thông báo lỗi "permission denied for table users", chứng tỏ replicator không thể đọc dữ liệu nghiệp vụ.
Bật và cấu hình Log Audit cho các hành động nhạy cảm
Kích hoạt và tinh chỉnh cơ chế ghi log (Audit Log) của PostgreSQL để theo dõi các hoạt động nhạy cảm như thay đổi cấu trúc, đăng nhập thất bại, và truy cập dữ liệu TDE.
Mục đích: Tạo "dấu vết" (trail) để phục vụ điều tra sự cố (Forensics) và phát hiện các hành vi bất thường trong hệ thống phân tán.
Kết quả mong đợi: File log ghi lại chi tiết từng lệnh SQL, người dùng thực thi, thời gian và kết quả, định dạng dễ phân tích.
Cấu hình file postgresql.conf để bật các tham số logging quan trọng cho Audit.
cat >> /var/lib/postgresql/data/postgresql.conf
Giải thích:
- log_statement = 'ddl': Ghi lại mọi lệnh tạo, sửa, xóa cấu trúc (CREATE, ALTER, DROP).
- log_connections/disconnections: Ghi lại thời điểm đăng nhập và thoát.
- log_line_prefix: Định dạng log để dễ dàng parse bằng công cụ SIEM sau này.
Kết quả: File log sẽ bắt đầu ghi lại các sự kiện hệ thống và DDL.
Sử dụng extension pgAudit để ghi log chi tiết hơn, bao gồm cả DML (SELECT, INSERT, UPDATE, DELETE) nếu cần thiết. Đây là bước nâng cao so với log mặc định.
psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS pgaudit;"
psql -U postgres -c "ALTER SYSTEM SET pgaudit.log = 'read, write, ddl, role';"
psql -U postgres -c "ALTER SYSTEM SET pgaudit.log_catalog = 'on';"
psql -U postgres -c "ALTER SYSTEM SET pgaudit.log_client = 'on';"
psql -U postgres -c "SELECT pg_reload_conf();"
Kết quả: Extension pgAudit được kích hoạt, log sẽ ghi lại cả các lệnh đọc (SELECT) và viết (INSERT/UPDATE) cùng với thông tin role.
Cấu hình log rotation để đảm bảo file log không tràn ổ cứng, sử dụng logrotate.
cat > /etc/logrotate.d/postgresql-audit &1
endscript
}
EOF
Kết quả: File log sẽ được tự động nén và xóa sau 30 ngày, tránh việc hệ thống bị đầy dung lượng.
Verify kết quả bằng cách thực hiện một lệnh nhạy cảm và kiểm tra log.
psql -U postgres -c "CREATE TABLE audit_test (id int);"
Liền sau đó kiểm tra file log (thường nằm ở /var/log/postgresql/).
grep "CREATE TABLE" /var/log/postgresql/postgresql-*.log
Kết quả mong đợi: Thấy dòng log chứa lệnh "CREATE TABLE audit_test" kèm theo timestamp và username thực thi.
psql -U app_user -c "SELECT * FROM audit_test;"
Kiểm tra log với pgAudit.
grep "SELECT" /var/log/postgresql/postgresql-*.log | grep "audit_test"
Kết quả mong đợi: Thấy dòng log ghi lại hành động SELECT, xác nhận pgAudit đang hoạt động.
Tích hợp với SIEM để giám sát thời gian thực
Cấu hình gửi log audit từ PostgreSQL về hệ thống SIEM (Security Information and Event Management) như Wazuh, Splunk, hoặc ELK Stack để giám sát và cảnh báo thời gian thực.
Mục đích: Chuyển đổi log từ dạng file tĩnh sang stream dữ liệu thời gian thực, cho phép phát hiện tấn công ngay khi nó xảy ra (Real-time detection).
Kết quả mong đợi: Log từ PostgreSQL được thu thập và hiển thị trên dashboard SIEM, các cảnh báo (Alert) được kích hoạt khi phát hiện mẫu tấn công.
Triển khai agent thu thập log (ví dụ: Filebeat hoặc Wazuh Agent) trên tất cả các nút Database. Cấu hình agent để đọc file log của PostgreSQL.
cat > /etc/filebeat/filebeat.yml
Kết quả: Filebeat được cấu hình để đọc log PostgreSQL và đẩy về Elasticsearch (trước mắt của SIEM).
Khởi động dịch vụ Filebeat để bắt đầu gửi log.
systemctl enable filebeat
systemctl start filebeat
Kiểm tra trạng thái của Filebeat.
filebeat test config
filebeat test output
Kết quả mong đợi: Filebeat báo cáo cấu hình hợp lệ và kết nối thành công với server SIEM.
Tạo quy tắc cảnh báo (Rule) trên SIEM để phát hiện các hành vi bất thường. Ví dụ: Phát hiện nhiều lần đăng nhập thất bại (Brute Force) hoặc lệnh DROP DATABASE.
Ví dụ cấu hình rule trong Wazuh (dạng JSON) để cảnh báo khi có lệnh DROP DATABASE.
cat > /var/ossec/rules/local_rules.xml
Kết quả: SIEM sẽ tự động phân tích log và tạo sự kiện cảnh báo khi phát hiện các mẫu nguy hiểm.
Verify tích hợp bằng cách thực hiện một hành động kích hoạt cảnh báo và kiểm tra trên dashboard SIEM.
psql -U postgres -c "DROP TABLE audit_test;"
Kiểm tra console hoặc API của SIEM để xem alert.
curl -u elastic:changeme "http://siem-server:9200/alerts/_search?q=rule.id:100001" | jq .hits.hits[]._source
Kết quả mong đợi: SIEM trả về sự kiện cảnh báo với mức độ nguy hiểm (Level 12) mô tả hành động DROP TABLE vừa xảy ra, xác nhận quy trình giám sát hoạt động chính xác.
Điều hướng series:
Mục lục: Series: Xây dựng Database phân tán an toàn với PostgreSQL, Raft và TDE
« Phần 5: Kết hợp Raft và TDE: Xử lý khóa mã hóa trong môi trường phân tán
Phần 7: Sao lưu, khôi phục và Disaster Recovery cho cụm phân tán mã hóa »