Hướng dẫn triển khai giao thức HTTPS với chứng chỉ SSL tự ký trên Nginx

Việc sử dụng HTTPS là tiêu chuẩn bắt buộc để bảo mật dữ liệu truyền tải giữa người dùng và máy chủ. Trong môi trường phát triển (development) hoặc thử nghiệm (staging), chúng ta có thể sử dụng chứng chỉ SSL tự ký (self-signed certificate) để thiết lập kết nối mã hóa mà không cần mua từ các tổ chức CA (Certificate Authority).

1. Quy trình khởi tạo chứng chỉ SSL tự ký

Trước tiên, hãy đảm bảo hệ thống đã cài đặt OpenSSL. Chúng ta sẽ thực hiện tạo các tệp tin cần thiết trong thư mục cấu hình của Nginx.

# Tạo thư mục lưu trữ chứng chỉ
mkdir -p /etc/nginx/certs
cd /etc/nginx/certs

Bước 1: Tạo khóa riêng (Private Key)

Chúng ta sẽ tạo một khóa RSA 2048-bit có đặt mật khẩu bảo vệ:

openssl genrsa -des3 -out server_secure.key 2048

Bước 2: Tạo yêu cầu ký số (CSR)

Điền các thông tin định danh cho chứng chỉ. Lưu ý phần Common Name phải khớp với tên miền bạn sử dụng.

openssl req -new -key server_secure.key -out server_request.csr

Bước 3: Loại bỏ mật khẩu khỏi khóa riêng

Để Nginx có thể tự động khởi động mà không yêu cầu nhập mật khẩu thủ công mỗi lần, chúng ta cần tạo một phiên bản khóa không có passphrase:

openssl rsa -in server_secure.key -out server_nopass.key

Bước 4: Tự ký chứng chỉ (Self-sign)

Sử dụng CSR và khóa riêng để tạo chứng chỉ có thời hạn 10 năm (3650 ngày):

openssl x509 -req -days 3650 -in server_request.csr -signkey server_secure.key -out server_final.crt

2. Cấu hình Nginx để kích hoạt HTTPS

Sau khi có chứng chỉ, chúng ta cần chỉnh sửa tệp cấu hình của Nginx để lắng nghe trên cổng 443.

server {
    listen 443 ssl http2;
    server_name dev.example.com;

    # Đường dẫn tới chứng chỉ và khóa riêng
    ssl_certificate "/etc/nginx/certs/server_final.crt";
    ssl_certificate_key "/etc/nginx/certs/server_nopass.key";

    # Tối ưu hóa bảo mật SSL
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

3. Tự động chuyển hướng từ HTTP sang HTTPS

Để đảm bảo mọi truy cập đều qua giao thức mã hóa, hãy thêm một block server lắng nghe cổng 80:

server {
    listen 80;
    server_name dev.example.com;
    return 301 https://$host$request_uri;
}

4. Cấu hình Reverse Proxy HTTPS tới Backend

Trong thực tế, Nginx thường đóng vai trò Proxy ngược cho các ứng dụng như Tomcat, Node.js hoặc Python. Dưới đây là cách cấu hình chuyển tiếp yêu cầu động tới backend đang chạy ở cổng 8080.

location /api/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Xử lý vấn đề redirect từ backend
    proxy_redirect http:// $scheme://;
}

5. Các thiết lập bảo mật bổ sung (Security Headers)

Để tăng cường tính an toàn cho website, bạn nên thêm các HTTP Header sau vào block server:

# Ngăn chặn clickjacking
add_header X-Frame-Options "SAMEORIGIN";

# Chống XSS (Cross-Site Scripting)
add_header X-XSS-Protection "1; mode=block";

# Ngăn chặn trình duyệt đoán định loại nội dung (MIME sniffing)
add_header X-Content-Type-Options "nosniff";

# Kích hoạt HSTS (Hỗ trợ trình duyệt luôn dùng HTTPS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

6. Kiểm tra thời hạn chứng chỉ bằng Script

Vì chứng chỉ SSL có thời hạn, bạn có thể sử dụng đoạn mã Bash sau để kiểm tra số ngày còn lại của chứng chỉ trên máy chủ:

#!/bin/bash

TARGET_HOST="dev.example.com"
TARGET_PORT="443"

expiration_date=$(echo | openssl s_client -servername "$TARGET_HOST" -connect "$TARGET_HOST:$TARGET_PORT" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)

if [ -n "$expiration_date" ]; then
    exp_epoch=$(date -d "$expiration_date" +%s)
    now_epoch=$(date +%s)
    days_left=$(( (exp_epoch - now_epoch) / 86400 ))
    echo "Tên miền: $TARGET_HOST còn $days_left ngày hiệu lực."
fi

Sau khi hoàn tất thay đổi cấu hình, đừng quên kiểm tra cú pháp và khởi động lại dịch vụ Nginx:

nginx -t
systemctl restart nginx

Thẻ: nginx ssl HTTPS openssl reverse-proxy

Đăng vào ngày 4 tháng 6 lúc 06:09