Xây dựng quy trình khôi phục khóa TDE khi bị mất
Trong môi trường phân tán, việc mất khóa mã hóa TDE (Transparent Data Encryption) là kịch bản thảm họa nếu không có bản sao dự phòng. Chúng ta sẽ thiết lập cơ chế lưu trữ khóa dự phòng an toàn trên một máy chủ riêng biệt (HSM hoặc Server Vault) và thực hành quy trình khôi phục.
Tạo thư mục chứa khóa dự phòng trên máy chủ quản lý an ninh (Security Vault Server) và thiết lập quyền truy cập cực kỳ nghiêm ngặt chỉ cho nhóm quản trị viên cấp cao.
mkdir -p /secure-vault/tde-backup
chmod 700 /secure-vault/tde-backup
chown root:dba /secure-vault/tde-backup
Kết quả mong đợi: Thư mục được tạo với quyền truy cập chỉ dành cho chủ sở hữu (root) và nhóm dba, ngăn chặn truy cập từ người dùng thông thường.
Sao chép khóa TDE hiện hành đang được Database sử dụng vào thư mục an toàn này. Giả định khóa hiện nằm tại `/var/lib/mysql/tde/master.key`.
cp /var/lib/mysql/tde/master.key /secure-vault/tde-backup/master.key.bak.$(date +%F).key
Kết quả mong đợi: Một file khóa dự phòng được tạo với đuôi tên là ngày tháng hiện tại, đảm bảo lịch sử các phiên bản khóa.
Viết script tự động để kích hoạt khôi phục khóa khi phát hiện lỗi "Encryption Key Not Found". Script sẽ đọc khóa từ Vault và đưa vào vị trí cần thiết.
cat > /usr/local/bin/restore-tde-key.sh
Kết quả mong đợi: Script được tạo và cấp quyền thực thi, sẵn sàng để gọi khi cần khôi phục.
Verify kết quả khôi phục
Xóa khóa hiện tại để mô phỏng sự cố, sau đó chạy script khôi phục và kiểm tra trạng thái Database.
rm /var/lib/mysql/tde/master.key
/usr/local/bin/restore-tde-key.sh
systemctl status mysql
Kết quả mong đợi: Database khởi động thành công, không báo lỗi về khóa mã hóa, và có thể truy xuất dữ liệu cũ.
Mô phỏng tấn công truy cập trái phép vào file dữ liệu
Chúng ta sẽ thực hiện kiểm thử bảo mật (Penetration Testing) bằng cách giả lập một kẻ tấn công đã vượt qua lớp bảo vệ ứng dụng và cố gắng đọc trực tiếp file dữ liệu trên disk. Mục tiêu là chứng minh TDE hoạt động đúng và dữ liệu vẫn là mã hóa (ciphertext).
Định danh file dữ liệu vật lý (data file) của Database đang được mã hóa. Trong ví dụ này, giả sử file là `ibdata1` của MySQL hoặc file `.db` của SQLite/Postgres.
ls -l /var/lib/mysql/ibdata1
Kết quả mong đợi: Hiển thị thông tin file, quyền sở hữu và kích thước file dữ liệu thực tế.
Thực hiện đọc trực tiếp nội dung file bằng lệnh `xxd` để xem dưới dạng hex. Nếu TDE hoạt động, nội dung sẽ là các ký tự ngẫu nhiên, không thể đọc được văn bản thuần túy.
sudo xxd /var/lib/mysql/ibdata1 | head -n 20
Kết quả mong đợi: Đầu ra hiển thị các chuỗi hex ngẫu nhiên (ví dụ: `00 00 00 00 00 00 00 00...` hoặc các byte hỗn độn), không có từ khóa SQL, tên bảng, hay dữ liệu người dùng rõ ràng.
Cố gắng mount file dữ liệu này sang một máy chủ khác (hoặc tạo file clone) và chạy lệnh `strings` để tìm kiếm văn bản. Đây là kỹ thuật phổ biến của kẻ tấn công để tìm password hoặc dữ liệu nhạy cảm.
cp /var/lib/mysql/ibdata1 /tmp/ibdata1.stolen
sudo strings /tmp/ibdata1.stolen | grep -i "password\|credit\|secret"
Kết quả mong đợi: Lệnh `grep` không trả về kết quả gì hoặc trả về các chuỗi ngẫu nhiên vô nghĩa. Điều này chứng minh TDE đã bảo vệ dữ liệu ngay cả khi file bị đánh cắp.
Verify kết quả kiểm thử
So sánh kết quả với một file dữ liệu chưa mã hóa (nếu có) hoặc file log để thấy sự khác biệt rõ ràng.
sudo strings /var/log/mysql/error.log | head -n 5
Kết quả mong đợi: File log hiển thị văn bản rõ ràng (ví dụ: "InnoDB: Starting shutdown..."), trong khi file dữ liệu vẫn là mã hóa, xác nhận tính hiệu quả của TDE.
Kiểm tra khả năng phát hiện của Audit khi có hành vi lạ
Phần này tập trung vào việc xác minh rằng Linux Kernel Audit đã được cấu hình đúng để ghi lại mọi nỗ lực truy cập trái phép vào các file nhạy cảm mà chúng ta vừa mô phỏng ở trên.
Thêm quy tắc (rule) vào Audit để giám sát mọi hành động đọc (`read`), ghi (`write`) hoặc thay đổi quyền (`chmod`) đối với file dữ liệu của Database.
auditctl -w /var/lib/mysql/ibdata1 -p rwxa -k db_data_access
Kết quả mong đợi: Không có lỗi trả về, quy tắc được thêm vào danh sách hiện hành. Thẻ `rwxa` đảm bảo ghi log cho Read, Write, Execute và Attribute change.
Thực hiện lại hành vi đọc file trái phép bằng lệnh `cat` hoặc `xxd` dưới quyền root (giả lập kẻ tấn công đã có quyền root nhưng vẫn bị audit theo dõi).
sudo cat /var/lib/mysql/ibdata1 > /dev/null
Kết quả mong đợi: Lệnh chạy thành công, nhưng hệ thống Audit đã ghi lại sự kiện này vào log.
Truy vấn log Audit để xem chi tiết sự kiện vừa xảy ra. Sử dụng `ausearch` với key `db_data_access` để lọc log.
ausearch -k db_data_access -i | tail -n 50
Kết quả mong đợi: Hiển thị chi tiết sự kiện bao gồm:
- `type=SYSCALL` hoặc `type=EXECVE`: Xác nhận lệnh đã được thực thi.
- `comm=cat`: Tên lệnh thực hiện.
- `exe=/usr/bin/cat`: Đường dẫn nhị phân của lệnh.
- `pid=...`: ID tiến trình.
- `a0=...`: Tham số đầu vào (đường dẫn file).
- `success=1`: Hành động thành công (cho thấy file bị đọc).
Tìm kiếm trong log để xác định ai là người thực hiện hành động đó thông qua `uid`.
ausearch -k db_data_access -i | grep "uid="
Kết quả mong đợi: Hiển thị `uid=root` (hoặc UID của user đang chạy), xác nhận danh tính kẻ truy cập trái phép.
Verify kết quả giám sát
Thiết lập cảnh báo tự động bằng cách chạy lệnh tìm kiếm log liên tục để đảm bảo Audit Daemon hoạt động tốt.
ausearch -k db_data_access --start recent | wc -l
Kết quả mong đợi: Số lượng dòng log tăng lên sau mỗi lần bạn thực hiện lệnh `cat` hoặc `xxd` vào file dữ liệu, chứng tỏ hệ thống ghi log hoạt động liên tục.
Tối ưu hiệu năng của TDE và Raft khi có lượng request lớn
Mã hóa dữ liệu (TDE) và cơ chế đồng thuận (Raft) đều tạo ra chi phí tính toán (CPU) và độ trễ (Latency). Chúng ta cần điều chỉnh các tham số để cân bằng giữa bảo mật và hiệu năng trong môi trường tải cao.
Điều chỉnh tham số `sync_binlog` hoặc cơ chế journaling của Database để giảm tần suất đồng bộ hóa disk I/O mà vẫn đảm bảo tính nhất quán (durability) của Raft. Lưu ý: Giảm giá trị này có thể làm tăng rủi ro mất dữ liệu khi mất điện.
mysql -u root -p -e "SET GLOBAL sync_binlog = 1;"
Kết quả mong đợi: Database chấp nhận thay đổi tham số. Giá trị `1` yêu cầu ghi disk sau mỗi transaction, đảm bảo an toàn cho Raft nhưng chậm. Nếu muốn tốc độ cao hơn, có thể thử `0` (risky) hoặc `1000` (batch).
Tối ưu hóa thuật toán mã hóa TDE bằng cách sử dụng phần cứng hỗ trợ (AES-NI) hoặc tăng kích thước buffer để giảm số lần gọi hàm mã hóa. Kiểm tra xem CPU có hỗ trợ AES-NI không.
grep -m 1 aes /proc/cpuinfo
Kết quả mong đợi: Xuất hiện dòng chứa `aes` trong danh sách flags, xác nhận CPU hỗ trợ phần cứng mã hóa, giúp TDE chạy nhanh hơn gấp 10-20 lần so với phần mềm.
Giảm độ trễ của Raft bằng cách tăng `election_timeout` và `heartbeat_interval` nếu mạng có độ trễ cao, tránh việc xảy ra bầu chọn (election) không cần thiết khi mạng chập chờn.
cat > /etc/raft-config/raft-tuning.conf
Kết quả mong đợi: Dịch vụ Raft khởi động lại với cấu hình mới, giảm số lượng message bầu chọn trong log khi có nhiễu mạng.
Chạy benchmark đơn giản để đo lường thông lượng (throughput) trước và sau khi tối ưu.
sysbench --test=oltp --oltp-table-size=100000 --num-threads=16 --max-requests=100000 --report-interval=1 run
Kết quả mong đợi: Xuất hiện báo cáo với chỉ số `transactions/sec`. So sánh con số này với phiên bản chưa tối ưu để thấy sự cải thiện.
Verify kết quả tối ưu
Giám sát tải CPU và Disk I/O trong khi chạy test để đảm bảo không bị nghẽn cổ chai (bottleneck).
vmstat 1 10
Kết quả mong đợi: Cột `bi` (blocks in) và `bo` (blocks out) ổn định, cột `us` (user CPU) không đạt 100% liên tục, chứng tỏ hệ thống xử lý hiệu quả.
Đánh giá lại lỗ hổng bảo mật sau khi triển khai
Sau khi đã tích hợp TDE, Audit và tối ưu Raft, chúng ta cần chạy một quy trình kiểm toán cuối cùng để đảm bảo không còn lỗ hổng nào bị bỏ sót do các thay đổi cấu hình.
Sử dụng công cụ `lynis` (hoặc `openvas` nếu có) để quét hệ thống Linux, tập trung vào các mục liên quan đến Database và Audit.
lynis audit system --quick
Kết quả mong đợi: Xuất ra báo cáo với các mức cảnh báo (Low, Medium, High). Tập trung vào các mục "File Permissions", "Audit", và "Database Security".
Kiểm tra đặc biệt xem có file nào trong thư mục dữ liệu Database có quyền quá rộng (world-readable/writable) không.
find /var/lib/mysql -type f \( -perm -005 -o -perm -007 \) -ls
Kết quả mong đợi: Không có file nào được liệt kê. Nếu có file nào xuất hiện, đó là lỗ hổng bảo mật nghiêm trọng cần sửa ngay bằng `chmod 600`.
Xác minh lại tính toàn vẹn của file cấu hình Audit để đảm bảo không bị kẻ tấn công xóa log (log tampering).
ausearch -i | wc -l
Kết quả mong đợi: Số lượng dòng log lớn và tăng dần theo thời gian, chứng tỏ log đang được ghi liên tục và không bị xóa.
Kiểm tra trạng thái của cluster Raft để đảm bảo không có node nào bị tách biệt (split-brain) do cấu hình an ninh quá chặt gây mất kết nối mạng.
raft-cli cluster-status
Kết quả mong đợi: Hiển thị tất cả các node đều ở trạng thái `LEADER` hoặc `FOLLOWER` và `Connected`, không có cảnh báo về `Disconnected` hay `Quorum lost`.
Verify kết quả đánh giá
Tạo bản tóm tắt các điểm yếu còn lại và hành động khắc phục.
echo "Security Audit Summary: TDE Active, Audit Logging Active, Raft Consistent. No critical vulnerabilities found." > /var/log/security-audit-summary.txt
Kết quả mong đợi: File báo cáo được tạo, xác nhận quy trình bảo mật đã hoàn tất và hệ thống ở trạng thái an toàn.
Điều hướng series:
Mục lục: Series: Triển khai Database phân tán an toàn với Raft, TDE và Linux Kernel Audit
« Phần 4: Thiết lập Linux Kernel Audit để giám sát truy cập
Phần 6: Troubleshooting và tối ưu hóa nâng cao »