1. Khái niệm về mã hóa dữ liệu lưu trữ (TDE) trong PostgreSQL
PostgreSQL bản thân không có tính năng Transparent Data Encryption (TDE) tích hợp sẵn ở mức engine như các RDBMS thương mại. Mã hóa dữ liệu tại chỗ (Encryption at Rest) trong PostgreSQL thường được thực hiện ở mức hệ thống (OS-level) hoặc filesystem.
Trong ngữ cảnh Post-Quantum Cryptography (PQC), chúng ta không thể đơn giản dùng thuật toán RSA hay ECC để mã hóa key master. Thay vào đó, chúng ta sử dụng LUKS2 (Linux Unified Key Setup) với các thuật toán PQC (như Kyber hoặc Dilithium) được tích hợp qua OpenSSL 3.2 để tạo key encryption key (KEK).
Mục tiêu là đảm bảo khi ổ đĩa bị vật lý đánh cắp, dữ liệu trong thư mục data directory và file WAL (Write-Ahead Log) vẫn không thể giải mã được nếu không có key PQC tương ứng.
Verify kết quả
Hiểu rõ cơ chế: Dữ liệu được mã hóa ở tầng block device, PostgreSQL chỉ đọc/giải mã dữ liệu đã được OS cung cấp. Nếu OS không mount được volume, Postgres không thể khởi động.
2. Chuẩn bị Volume LUKS2 với Key PQC
Bước này tạo một partition hoặc file image, sau đó mã hóa nó bằng LUKS2. Chúng ta sẽ sử dụng keyfile được tạo bằng thuật toán PQC (Kyber768) để khóa volume này.
Tạo keyfile PQC trước khi mã hóa volume. Key này sẽ đóng vai trò là Keyslot trong LUKS2.
cd /root/pqc-keys
openssl pkey -genpkey -pkeyopt provider:default -pkeyopt algorithm:Kyber768 -out pq_key.der -outform DER
Kết quả mong đợi: File pq_key.der được tạo thành công, chứa key cặp công khai/riêng tư dùng cho thuật toán Kyber768.
Định dạng một file image (giả lập disk) với LUKS2, sử dụng keyfile PQC vừa tạo làm password slot. Lệnh này yêu cầu xác nhận passphrase cho slot mặc định (slot 0) và thêm keyfile vào slot 1.
dd if=/dev/zero of=/var/lib/pgdata-encrypted.img bs=1M count=1024
cryptsetup luksFormat --type luks2 --key-file /root/pqc-keys/pq_key.der --pbkdf argon2 /var/lib/pgdata-encrypted.img
Kết quả mong đợi: Volume được định dạng LUKS2 thành công. Slot 1 chứa keyfile PQC.
Mount volume đã mã hóa để chuẩn bị thư mục dữ liệu cho PostgreSQL. Cần mở khóa volume bằng keyfile PQC.
cryptsetup open --key-file /root/pqc-keys/pq_key.der /var/lib/pgdata-encrypted.img pg_pqc_volume
Kết quả mong đợi: Thiết bị ảo /dev/mapper/pg_pqc_volume được tạo ra và sẵn sàng nhận dữ liệu.
3. Cấu hình thư mục Data Directory và File WAL
Định dạng filesystem trên volume đã mở khóa. Sử dụng XFS hoặc ext4 với các tùy chọn bảo mật.
mkfs.xfs -f /dev/mapper/pg_pqc_volume
Kết quả mong đợi: Filesystem được tạo thành công trên volume mã hóa.
Tạo thư mục mount point và mount volume vào đó. Đây sẽ là nơi chứa thư mục data của PostgreSQL.
mkdir -p /var/lib/pgsql/data
mount /dev/mapper/pg_pqc_volume /var/lib/pgsql/data
Kết quả mong đợi: Thư mục /var/lib/pgsql/data giờ chứa filesystem đã mã hóa. Dữ liệu ghi vào đây sẽ tự động được mã hóa ở tầng block.
Khởi tạo (initdb) cơ sở dữ liệu vào thư mục đã mount. Đảm bảo quyền sở hữu thuộc về user postgres.
su - postgres -c "initdb -D /var/lib/pgsql/data --auth=md5"
Kết quả mong đợi: Thư mục data được tạo với các file cơ bản (PG_VERSION, base/, pg_wal/, ...). Tất cả file này đều đã được mã hóa trên disk.
Cấu hình postgresql.conf để đảm bảo WAL được lưu trữ đúng chỗ và kích hoạt logging để theo dõi hoạt động ghi.
cat > /var/lib/pgsql/data/postgresql.conf
Kết quả mong đợi: File config được ghi đè, PostgreSQL sẽ bắt buộc ghi WAL liên tục vào volume đã mã hóa.
4. Cấu hình tự động mount và khởi động (Persistence)
Để hệ thống tự động mở khóa volume khi khởi động (boot), chúng ta cần cấu hình /etc/crypttab và /etc/fstab.
Cấu hình crypttab để tự động mở khóa volume bằng keyfile PQC khi boot. Sử dụng tùy chọn nofail để tránh treo boot nếu keyfile bị lỗi, nhưng trong môi trường production nên đảm bảo keyfile có sẵn.
echo 'pg_pqc_volume /var/lib/pgdata-encrypted.img /root/pqc-keys/pq_key.der nofail,discard' >> /etc/crypttab
Kết quả mong đợi: Hệ thống biết cách mở khóa volume pg_pqc_volume bằng keyfile PQC khi khởi động.
Cấu hình fstab để mount volume sau khi cryptsetup đã mở khóa.
echo '/dev/mapper/pg_pqc_volume /var/lib/pgsql/data xfs defaults,noatime,nodiratime 0 2' >> /etc/fstab
Kết quả mong đợi: Volume sẽ tự động được mount vào đúng thư mục data sau khi cryptsetup chạy.
Khởi động lại dịch vụ mã hóa (cryptdisks) để áp dụng ngay lập tức mà không cần reboot.
systemctl start cryptdisks@pg_pqc_volume
systemctl enable cryptdisks@pg_pqc_volume
Kết quả mong đợi: Volume pg_pqc_volume đã được mở khóa và mount thành công.
5. Kiểm tra tính toàn vẹn và khả năng khôi phục
Khởi động PostgreSQL và kiểm tra xem nó có thể đọc dữ liệu từ volume mã hóa hay không.
systemctl start postgresql
pg_isready
Kết quả mong đợi: PostgreSQL chạy và trả về /var/run/postgresql:5432 - accepting connections.
Chèn dữ liệu thử nghiệm để tạo WAL và file data mới, sau đó kiểm tra xem file đó có được mã hóa trên disk hay không.
psql -U postgres -c "CREATE TABLE pq_test (id serial, secret text); INSERT INTO pq_test (secret) VALUES ('Quantum-Safe Data'); VACUUM pq_test;"
Kết quả mong đợi: Dữ liệu được ghi vào table. File pg_wal và file table 2602 (hoặc tương tự) sẽ được cập nhật.
Thử nghiệm mất key: Unmount volume, xóa keyfile giả lập mất key, sau đó cố gắng mount lại để chứng minh dữ liệu không thể truy cập.
cryptsetup close pg_pqc_volume
mv /root/pqc-keys/pq_key.der /root/pqc-keys/pq_key.der.bak
cryptsetup open --key-file /root/pqc-keys/pq_key.der.bak /var/lib/pgdata-encrypted.img pg_pqc_volume
Kết quả mong đợi: Lệnh cryptsetup open sẽ thành công nếu dùng key backup. Nếu bạn cố dùng keyfile không tồn tại hoặc sai, lệnh sẽ báo lỗi bad key và volume không mở được.
Khôi phục lại keyfile để đảm bảo hệ thống hoạt động bình thường.
mv /root/pqc-keys/pq_key.der.bak /root/pqc-keys/pq_key.der
cryptsetup open --key-file /root/pqc-keys/pq_key.der /var/lib/pgdata-encrypted.img pg_pqc_volume
mount /dev/mapper/pg_pqc_volume /var/lib/pgsql/data
systemctl restart postgresql
Kết quả mong đợi: PostgreSQL khởi động lại thành công, dữ liệu trong bảng pq_test vẫn còn nguyên vẹn và có thể truy vấn.
Verify tính toàn vẹn của dữ liệu sau khi khôi phục key.
psql -U postgres -c "SELECT * FROM pq_test;"
Kết quả mong đợi: Trả về dòng dữ liệu Quantum-Safe Data mà bạn đã chèn trước đó.
Điều hướng series:
Mục lục: Series: Triển khai Database Quantum-safe với Postgres và Ubuntu 24.04
« Phần 4: Cấu hình kết nối bảo mật TLS với PQC cho Client
Phần 6: Đánh giá hiệu năng và kiểm thử bảo mật cho hệ thống »