1. Vai trò của Certbot trong chiến lược HTTPS
Trong chiến lược HTTPS đã xác định ở Bài 10, toàn bộ chứng chỉ SSL được:
Quản lý tập trung tại Reverse Proxy,
Không phân tán xuống các backend,
Gia hạn tự động, hạn chế tối đa thao tác thủ công.
Để hiện thực hóa chiến lược này, Certbot (Let’s Encrypt) là công cụ phù hợp nhất vì:
Miễn phí,
Được hỗ trợ rộng rãi,
Tích hợp tốt với Nginx,
Có khả năng tự động gia hạn.
Tuy nhiên, khi số lượng domain lớn, Certbot phải được triển khai có chiến lược, không dùng theo kiểu “cài nhanh – chạy thử”.
2. Nguyên tắc triển khai Certbot trong hệ thống này
Trước khi cấu hình, cần thống nhất các nguyên tắc sau:
Chỉ cài Certbot trên Reverse Proxy
Mỗi domain có server block rõ ràng trước khi xin chứng chỉ
Không để Certbot tự động chỉnh sửa cấu hình một cách không kiểm soát
Gia hạn hoàn toàn tự động
Có khả năng mở rộng cho hàng trăm domain
Tài liệu này không sử dụng chế độ Certbot “tự động sửa toàn bộ cấu hình Nginx” để tránh:
Cấu hình bị thay đổi khó kiểm soát,
Phá vỡ cấu trúc folder/snippets đã chuẩn hóa.
3. Cài đặt Certbot trên Debian 12
3.1. Cập nhật hệ thống
3.2. Cài Certbot và plugin Nginx
Kiểm tra phiên bản:
4. Chuẩn bị Nginx trước khi xin chứng chỉ
4.1. Điều kiện bắt buộc
Trước khi chạy Certbot:
Domain phải trỏ DNS về IP Reverse Proxy (
192.168.1.88NAT ra Internet).Nginx đã chạy HTTP (port 80) cho domain đó.
Có server block HTTP hợp lệ.
4.2. Ví dụ server block HTTP chuẩn
server {
listen 80;
server_name qlcl.example.com;
location / {
proxy_pass http://10.10.10.66;
include snippets/proxy/proxy-common.conf;
}
}Kiểm tra:
5. Xin chứng chỉ HTTPS cho một domain
5.1. Chạy Certbot ở chế độ kiểm soát
Certbot sẽ:
Xác thực domain bằng HTTP-01 challenge,
Tạo chứng chỉ tại:
Đề nghị redirect HTTP → HTTPS (có thể chọn hoặc từ chối).
Khuyến nghị:
Không để Certbot tự động chỉnh sửa redirect, mà tự cấu hình redirect trong Nginx theo chuẩn hệ thống.
6. Cấu trúc file chứng chỉ Let’s Encrypt
Sau khi thành công:
/etc/letsencrypt/live/qlcl.example.com/
├── cert.pem
├── chain.pem
├── fullchain.pem
└── privkey.pemTrong Nginx, chỉ sử dụng:
fullchain.pemprivkey.pem
7. Cấu hình HTTPS server block chuẩn
7.1. Ví dụ server block HTTPS cho web app
server {
listen 443 ssl;
server_name qlcl.example.com;
ssl_certificate /etc/letsencrypt/live/qlcl.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/qlcl.example.com/privkey.pem;
include snippets/ssl/ssl-common.conf;
include snippets/ssl/ssl-params.conf;
include snippets/headers/security-headers.conf;
include snippets/proxy/proxy-common.conf;
include snippets/proxy/proxy-webapp.conf;
location / {
proxy_pass http://10.10.10.66;
}
}7.2. Redirect HTTP → HTTPS (tự kiểm soát)
8. Xin chứng chỉ cho nhiều domain
8.1. Xin nhiều domain trong một lệnh
8.2. Chứng chỉ riêng cho từng domain (khuyến nghị)
Dễ quản lý.
Dễ thu hồi hoặc debug.
Không ảnh hưởng domain khác khi lỗi.
9. Gia hạn chứng chỉ tự động
9.1. Cơ chế gia hạn mặc định
Certbot cài sẵn systemd timer:
Gia hạn chạy:
2 lần/ngày
Chỉ gia hạn khi còn < 30 ngày
9.2. Test gia hạn (bắt buộc)
Nếu không lỗi → hệ thống sẵn sàng production.
10. Reload Nginx sau khi gia hạn
Certbot mặc định reload Nginx.
Có thể kiểm soát bằng hook:
11. Quản lý hàng trăm domain: lưu ý quan trọng
Không xóa tay thư mục
/etc/letsencryptKhông copy chứng chỉ giữa các server
Backup
/etc/letsencryptđịnh kỳTheo dõi log gia hạn
Log:
12. Những lỗi thường gặp và cách tránh
12.1. Certbot không xác thực được domain
DNS chưa trỏ đúng.
Port 80 chưa mở hoặc bị firewall chặn.
12.2. Certbot sửa cấu hình Nginx ngoài ý muốn
Luôn review file
.confsau khi chạy.Ưu tiên cấu hình thủ công server block HTTPS.
13. Mối liên hệ với failover backend (QMS ↔ AI)
Vì HTTPS terminate tại Reverse Proxy:
Đổi backend IP không ảnh hưởng SSL.
Không cần xin lại chứng chỉ.
Thời gian khôi phục nhanh.
Kết luận
Certbot là công cụ mạnh, nhưng chỉ thực sự phát huy hiệu quả khi:
Được đặt đúng vị trí trong kiến trúc,
Được sử dụng có kiểm soát,
Gắn với chiến lược vận hành lâu dài.
Trong hệ thống nhiều website và web application, HTTPS + Certbot phải là nền tảng ổn định, không phải điểm gây rủi ro.
Ví dụ 1 — Web application (khuyến nghị cho QLCL/KHTH/Nhân sự/Thiết bị…)
##
# WebApp: QLCL
# Backend: QMS (10.10.10.66)
# Notes:
# - HTTPS terminate at Reverse Proxy
# - HTTP -> HTTPS redirect
# - Uses standardized snippets
##
# --------- 80 / HTTP: redirect to HTTPS ----------
server {
listen 80;
server_name qlcl.example.com;
# Optional (recommended): allow ACME challenge path if later you use webroot method
location ^~ /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
allow all;
}
return 301 https://$host$request_uri;
}
# --------- 443 / HTTPS: reverse proxy to backend ----------
server {
listen 443 ssl http2;
server_name qlcl.example.com;
# --- Let's Encrypt certificate (created by certbot) ---
ssl_certificate /etc/letsencrypt/live/qlcl.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/qlcl.example.com/privkey.pem;
# --- SSL policy (your standardized snippets) ---
include snippets/ssl/ssl-common.conf;
include snippets/ssl/ssl-params.conf;
# --- Security headers (standardized) ---
include snippets/headers/security-headers.conf;
# --- Reverse proxy baseline ---
include snippets/proxy/proxy-common.conf;
# --- WebApp-specific proxy tuning: timeouts, upload size ---
include snippets/proxy/proxy-webapp.conf;
# If behind Cloudflare for this domain, enable these (otherwise keep commented)
# include snippets/ssl/ssl-cloudflare.conf;
# include snippets/headers/real-ip.conf;
location / {
proxy_pass http://10.10.10.66; # QMS primary
}
}Ví dụ 2 — Website thường (CMS/website cơ sở y tế)
##
# Website: benhvienabc.vn
# Type: Public website (CMS)
# Backend: QMS (10.10.10.66)
##
server {
listen 80;
server_name benhvienabc.vn www.benhvienabc.vn;
location ^~ /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
allow all;
}
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name benhvienabc.vn www.benhvienabc.vn;
ssl_certificate /etc/letsencrypt/live/benhvienabc.vn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/benhvienabc.vn/privkey.pem;
include snippets/ssl/ssl-common.conf;
include snippets/ssl/ssl-params.conf;
include snippets/headers/security-headers.conf;
include snippets/proxy/proxy-common.conf;
location / {
proxy_pass http://10.10.10.66;
}
}Các file cấu hình include snippets đã đề cập ở bài trước: Bài 8.2. Chuẩn hóa snippets và cấu hình dùng chung cho hàng trăm website
- Đăng nhập để gửi ý kiến