Nếu bạn muốn chạy PostgreSQL trong môi trường production, việc thiết lập Transport Layer Security (TLS) là bắt buộc để ngăn chặn các cuộc tấn công trung gian (man-in-the-middle). Trong hướng dẫn từng bước này, tôi sẽ chỉ cho bạn cách kết nối đến cơ sở dữ liệu một cách an toàn bằng cách sử dụng Certificate Authority (CA) cục bộ của bạn. Nếu bạn cần giải thích chi tiết hơn về các thiết lập, hãy tham khảo tài liệu chính thức của PostgreSQL về TLS.
Trong ví dụ này, chúng ta chỉ cho phép kết nối mã hóa và thiết lập sslmode thành verify-full, mức nghiêm ngặt nhất trong các chế độ kết nối của PostgreSQL.
Yêu cầu trước khi bắt đầu
Bạn cần cài đặt Docker. Nếu bạn dùng macOS hoặc Windows, hãy cài Docker Desktop và chắc chắn nó đang chạy nền. Kiểm tra bằng lệnh:
docker ps
Nếu Docker đang chạy, bạn sẽ thấy danh sách container hoặc ít nhất là không có lỗi.
Thiết lập PostgreSQL với TLS bằng OpenSSL và Docker
Bước 1: Tạo Certificate Authority (CA)
Tất cả các file chứng chỉ (CA, server, client) nên được coi là bí mật. Không đẩy lên Git, không log, không nhúng vào Docker image. Chỉ dùng thông qua biến môi trường tại runtime.
Tạo CA root:
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 365 -out rootCA.crt -subj "/CN=MyLocalCA"
Bước 2: Tạo các file chứng chỉ máy chủ (server)
Bạn cần cung cấp domain nơi PostgreSQL sẽ chạy. Ví dụ: localhost
, hoặc thay bằng hostname thực tế.
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=localhost"
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 365 -sha256
Bước 3: Tạo các file chứng chỉ client
Client chỉ có thể kết nối nếu chứng chỉ được ký bởi cùng CA như server.
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/CN=postgres"
openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 365 -sha256
Bước 4: Script khởi tạo để bật TLS trong PostgreSQL
Tạo file ssl-config.sh
:
#!/bin/bash # Add certificate files
echo "$SERVER_CRT" > /var/lib/postgresql/server.crt
echo "$SERVER_KEY" > /var/lib/postgresql/server.key
echo "$ROOT_CA_CRT" > /var/lib/postgresql/rootCA.crt # Set permissions for the certificate files
chmod 600 /var/lib/postgresql/server.* /var/lib/postgresql/rootCA.crt
chown postgres:postgres /var/lib/postgresql/server.* /var/lib/postgresql/rootCA.crt # Configure PostgreSQL to use SSL
echo "ssl = on" >> /var/lib/postgresql/data/postgresql.conf
echo "ssl_cert_file = '/var/lib/postgresql/server.crt'" >> /var/lib/postgresql/data/postgresql.conf
echo "ssl_key_file = '/var/lib/postgresql/server.key'" >> /var/lib/postgresql/data/postgresql.conf
echo "ssl_ca_file = '/var/lib/postgresql/rootCA.crt'" >> /var/lib/postgresql/data/postgresql.conf # Force SSL
echo "hostssl all all all cert clientcert=verify-full" > /var/lib/postgresql/data/pg_hba.conf
Các biến môi trường cần thiết:
SERVER_CRT
SERVER_KEY
ROOT_CA_CRT
Bước 5: Tạo Docker Image bật TLS
Tạo Dockerfile
:
FROM postgres:17.5 COPY ssl-config.sh /docker-entrypoint-initdb.d/ssl-config.sh
Bước 6: Kết nối tới PostgreSQL
Đảm bảo server.crt
có CN=localhost
nếu đang test local.
Build image:
docker build -t postgres-tls .
Chạy container:
docker run \ -e POSTGRES_PASSWORD=secret \ -e SERVER_CRT="$(cat server.crt)" \ -e SERVER_KEY="$(cat server.key)" \ -e ROOT_CA_CRT="$(cat rootCA.crt)" \ -p 5432:5432 --name pgv pgv
Kết nối:
# This command should get you into the PostgreSQL shell:
psql "host=localhost dbname=postgres user=postgres sslmode=verify-full sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key" # This should fail, because we enforce tls:
psql "host=localhost dbname=postgres user=postgres sslmode=disable"
Triển khai với Sliplane
- Tạo GitHub repo chứa
Dockerfile
vàssl-config.sh
- Đăng nhập Sliplane với GitHub
- Tạo Project > Deploy Service
- Tạo Server mới (bắt đầu từ base)
- Chọn nguồn deploy từ Repository
- Chọn repo PostgreSQL vừa tạo
- Chọn protocol là TCP và nhấn "Deploy"
Deploy sẽ lỗi lần đầu vì thiếu biến môi trường — cần để có domain
.sliplane.app
để tạo chứng chỉ.
Sau khi có domain:
-
Tạo chứng chỉ server dùng domain
YOUR_APP.sliplane.app
-
Thêm các biến môi trường:
POSTGRES_PASSWORD
SERVER_CRT
SERVER_KEY
ROOT_CA_CRT
Lưu xong, deploy mới sẽ được kích hoạt và thành công nếu đúng.
Bạn đã hoàn tất!
Giờ bạn có thể kết nối an toàn đến PostgreSQL qua TLS:
psql "host=YOUR_APP.sliplane.app dbname=postgres user=postgres sslmode=verify-full sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"
Thay YOUR_APP.sliplane.app
bằng domain thật của bạn.
Hy vọng các bạn thấy bài viết này hữu ích