Kết nối Spring Boot với PostgreSQL sử dụng xác thực SCRAM-SHA-256
Khi PostgreSQL được cấu hình với xác thực SCRAM-SHA-256, ứng dụng Spring Boot cần thực hiện một số điều chỉnh để thiết lập kết nối thành công. Bài viết này hướng dẫn chi tiết các bước cần thực hiện.
Cấu hình phía máy chủ PostgreSQL
- Thay đổi phương thức mã hóa mật khẩu
Trong tệp postgresql.conf, thêm cấu hình:
password_encryption = scram-sha-256
Áp dụng thay đổi bằng cách thực thi pg_ctl reload hoặc khởi động lại dịch vụ.
2. Cập nhật mật khẩu người dùng
Đảm bảo tất cả mật khẩu người dùng được mã hóa bằng SCRAM-SHA-256:
ALTER USER ten_dang_nhap WITH PASSWORD 'mat_khau_moi';
Hoặc sử dụng lệnh \password để sửa đổi mật khẩu tương tác.
3. Xác minh phương thức mã hóa
Kiểm tra xem mật khẩu người dùng đã được nâng cấp chưa:
SELECT rolname, rolpassword FROM pg_authid WHERE rolcanlogin;
Nếu trường rolpassword bắt đầu bằng SCRAM-SHA-256$, chứng tỏ đã được nâng cấp.
4. Điều chỉnh cấu hình xác thực phía client
Trong pg_hba.conf, thay đổi phương thức xác thực thành scram-sha-256:
host all all 0.0.0.0/0 scram-sha-256
Tải lại cấu hình:
SELECT pg_reload_conf();
Cấu hình ứng dụng Spring Boot
- Nâng cấp trình điều khiển JDBC PostgreSQL
Trong tệp pom.xml, sử dụng phiên bản trình điều khiển hỗ trợ SCRAM-SHA-256 (≥ 42.2.0):
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.14.0</version> <!-- Hoặc phiên bản mới hơn -->
</dependency>
- Cấu hình nguồn dữ liệu
Trong tệp application.yml hoặc application.properties, thiết lập các tham số kết nối:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/ten_cso_dl?ssl=true&sslmode=require
username: ten_dang_nhap
password: mat_khau
driver-class-name: org.postgresql.Driver
- Giải thích các tham số quan trọng:
ssl=true&sslmode=require: Kích hoạt SSL (khuyến nghị dùng kết hợp với SCRAM-SHA-256).- Nếu sử dụng connection pool (ví dụ: HikariCP), đảm bảo cấu hình tương thích với SCRAM (mặc định đã hỗ trợ).
- Ví dụ mã (cấu hình bằng Java)
Nếu cấu hình nguồn dữ liệu qua mã Java:
@Bean
public DataSource dataSourceConfig() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/ten_cso_dl?ssl=true&sslmode=require");
dataSource.setUsername("ten_dang_nhap");
dataSource.setPassword("mat_khau");
dataSource.setDriverClassName("org.postgresql.Driver");
return dataSource;
}
Giải quyết các vấn đề thường gặp
- Xác thực thất bại (Password authentication failed)
- Nguyên nhân: Mật khẩu chưa được cập nhật định dạng SCRAM-SHA-256, hoặc phiên bản JDBC quá cũ.
- Cách khắc phục:
- Xác minh mật khẩu người dùng đã được cập nhật qua lệnh
ALTER USERhoặc\password. - Kiểm tra phiên bản trình điều khiển có ≥ 42.2.0 không.
- Lỗi cấu hình SSL
- Nguyên nhân: Máy chủ PostgreSQL chưa kích hoạt SSL hoặc chứng chỉ không hợp lệ.
- Cách khắc phục:
- Kích hoạt SSL trong
postgresql.conf:``` ssl = on ssl_cert_file = '/duong/den/server.crt' ssl_key_file = '/duong/den/server.key'
- Điều chỉnh chế độ SSL trong Spring Boot (ví dụ: `sslmode=verify-full` để xác thực chứng chỉ).
3. **Tương thích connection pool**
- **Hiện tượng**: Kết nối thất bại khi sử dụng connection pool cũ (như DBCP2).
- **Cách khắc phục**: Nâng cấp connection pool lên phiên bản mới nhất (ví dụ: HikariCP 3.x+).
### **Xác minh kết nối**
1. **Sử dụng `psql` để kiểm tra**
Thực thi trong terminal:
psql "host=localhost port=5432 dbname=ten_cso_dl user=ten_dang_nhap password=mat_khau sslmode=require"
Nếu kết nối thành công, chứng tỏ cấu hình máy chủ đúng.
2. **Log khởi động ứng dụng Spring Boot**
Kiểm tra log có thông tin tương tự:
Tomcat khởi động với cổng: 8080 (http) HikariPool-1 - Đang khởi động... HikariPool-1 - Khởi động hoàn tất.
Không có lỗi xác thực tức là kết nối thành công.
### **Thực hành khuyến nghị**
1. **Bắt buộc SCRAM-SHA-256**
Trong `pg_hba.conf`, từng bước loại bỏ `md5`, chỉ giữ lại `scram-sha-256`:
host all all 0.0.0.0/0 scram-sha-256
2. **Thay đổi mật khẩu định kỳ**
Sử dụng lệnh `ALTER USER` để cập nhật mật khẩu định kỳ, đảm bảo hash mã hóa được cập nhật liên tục.
3. **Theo dõi log xác thực**
Theo dõi các sự kiện xác thực thất bại trong log PostgreSQL:
log_connections = on log_disconnections = on log_hostname = on
Thông qua các bước trên, ứng dụng Spring Boot có thể kết nối an toàn với cơ sở dữ liệu PostgreSQL đã kích hoạt xác thực SCRAM-SHA-256, cân bằng giữa bảo mật và tính tương thích.
### **Xem xét về SCRAM-SHA-256 và SSL**
**Xác thực SCRAM-SHA-256 của PostgreSQL không bắt buộc phải bật SSL**, nhưng**rất nên**kích hoạt SSL đồng thời để có bảo mật toàn diện. Phân tích cụ thể như sau:
### **1. Tính bảo mật của xác thực SCRAM-SHA-256**
- **Cơ chế cốt lõi**: SCRAM-SHA-256 là giao thức xác thực dạng thách-thử dựa trên giá trị muối (Salt) và băm nhiều lần, có thể ngăn chặn việc nghe lén hoặc tấn công lặp lại trong quá trình xác thực. Ngay cả khi kẻ tấn công chặn được luồng xác thực, cũng không thể lấy được mật khẩu người dùng.
- **Tính độc lập**: SCRAM-SHA-256 không phụ thuộc vào SSL/TLS, ngay cả khi không bật SSL, giai đoạn xác thực vẫn an toàn hơn các phiên bản MD5 cũ hoặc mật khẩu dạng văn bản.
### **2. Tại sao nên dùng kết hợp SSL?**
- **Mã hóa truyền dữ liệu**: SCRAM-SHA-256 chỉ bảo mật mật khẩu trong quá trình xác thực, nhưng các dữ liệu khác của cơ sở dữ liệu (như nội dung truy vấn, cấu trúc bảng) vẫn được truyền dưới dạng văn bản. SSL/TLS có thể mã hóa toàn bộ lưu lượng mạng, ngăn chặn tấn công trung gian hoặc rò rỉ dữ liệu.
- **Phòng vệ đa tầng**: Kết hợp SSL và SCRAM-SHA-256 tạo ra nhiều lớp bảo vệ:
- **SSL/TLS**: Bảo mật tính bảo mật và toàn vẹn ở tầng truyền tải.
- **SCRAM-SHA-256**: Đảm bảo tính xác thực danh tính người dùng.
- **Yêu cầu tuân thủ**: Nhiều ngành (tài chính, y tế) có tiêu chuẩn bảo mật (như PCI DSS, HIPAA) yêu cầu kết nối cơ sở dữ liệu phải được mã hóa, lúc này SSL là bắt buộc.
### **3. Đề xuất cấu hình thực tế**
- **Cấu hình phía server**:
- Kích hoạt SSL trong `postgresql.conf`:```
ssl = on
ssl_cert_file = '/duong/den/server.crt'
ssl_key_file = '/duong/den/server.key'
- Trong
pg_hba.conf, bắt buộc xác thực SCRAM-SHA-256, ưu tiên sử dụnghostssl(chỉ kết nối SSL):```
Cho phép client kết nối SSL sử dụng SCRAM-SHA-256
hostssl all all 0.0.0.0/0 scram-sha-256
Từ chối kết nối không SSL (tùy chọn, tùy nhu cầu bảo mật)
hostnossl all all 0.0.0.0/0 reject
- **Cấu hình phía client**:
- Trong `application.yml` của Spring Boot, kích hoạt SSL:```
spring:
datasource:
url: jdbc:postgresql://localhost:5432/ten_cso_dl?ssl=true&sslmode=require
username: ten_nguoi_dung
password: mat_khau_nguoi_dung
- Sử dụng phiên bản mới nhất của trình điều khiển JDBC PostgreSQL (≥ 42.2.0) để hỗ trợ SCRAM-SHA-256 và SSL.
4. Xác minh cấu hình
- Kiểm tra kết nối SSL:``` -- Thực thi trong PostgreSQL SELECT ssl, version() FROM pg_stat_ssl WHERE pid = pg_backend_pid();
Nếu `ssl` là `true`, kết nối đã được mã hóa.
- **Kiểm tra phương thức xác thực**:```
-- Xem phương thức mã hóa mật khẩu người dùng
SELECT rolname, rolpassword FROM pg_authid WHERE rolname = 'ten_nguoi_dung';
Nếu rolpassword bắt đầu bằng SCRAM-SHA-256$, cấu hình đúng.
5. Xử lý các trường hợp đặc biệt
- Tương thích client cũ: Nếu client không hỗ trợ SCRAM-SHA-256 hoặc SSL, có thể tạm thời sử dụng dòng
hostcho phép kết nối không SSL, nhưng cần đánh giá rủi ro bảo mật. - Tác động hiệu năng: Mã hóa SSL sẽ gây ra một chút chi phí CPU, nhưng trên phần cứng hiện đại thường có thể bỏ qua. Có thể tối ưu hiệu năng bằng cách điều chỉnh bộ mật mã SSL (ví dụ: vô hiệu hóa thuật toán yếu).