Cách cài SSL Let's Encrypt cho VPS

SSH vào VPS mới, việc đầu tiên sau khi cài web server thường là bật HTTPS. Let's Encrypt là CA (Certificate Authority) cấp chứng chỉ SSL miễn phí, tự động gia hạn, được cả thế giới tin dùng. Bài này mình sẽ hướng dẫn chi tiết cách cài SSL Let's Encrypt cho VPS chạy Nginx trên Ubuntu 24.04 LTS hoặc Debian 12, dùng certbot, kèm cách tự động gia hạn và xử lý lỗi hay gặp.
- Cài đặt certbot và plugin Nginx chỉ với vài lệnh.
- Cấu hình Nginx để trỏ domain về VPS, mở port 80/443.
- Lệnh cấp chứng chỉ tự động nhận diện cấu hình web server.
- Tự động gia hạn bằng systemd timer, không cần can thiệp thủ công.
Yêu cầu trước khi bắt đầu
Trước khi chạy lệnh cài SSL, bạn cần chuẩn bị đủ những thứ sau. Thiếu một món, quá trình cấp chứng chỉ sẽ thất bại ngay bước kiểm tra domain.
- Một VPS chạy Ubuntu 24.04 LTS hoặc Debian 12, đã cài sẵn Nginx và đang phục vụ website.
- User có quyền sudo (không nên dùng root trực tiếp).
- Tên miền đã trỏ DNS record A về địa chỉ IPv4 của VPS. Bản ghi phải đã có hiệu lực trước khi cấp chứng chỉ.
- Cổng 80 (HTTP) và 443 (HTTPS) mở trên firewall. Let's Encrypt luôn kiểm tra qua cổng 80 trước khi cấp chứng chỉ.
Vì sao nên dùng Let's Encrypt thay vì chứng chỉ trả phí?
Let's Encrypt cung cấp chứng chỉ SSL/TLS miễn phí với thời hạn 90 ngày. Con số này nghe có vẻ ngắn, nhưng vì có cơ chế tự động gia hạn, nó không phải là vấn đề. Ngược lại, chứng chỉ trả phí thường có thời hạn 1 năm, nhưng bạn phải tự gia hạn thủ công mỗi năm một lần. Quên gia hạn là website rơi vào cảnh báo "Not Secure" ngay lập tức.
Về mặt kỹ thuật, chứng chỉ Let's Encrypt có mức bảo mật tương đương chứng chỉ DV (Domain Validation) trả phí. Cả hai đều mã hóa dữ liệu truyền tải giữa trình duyệt và máy chủ bằng giao thức TLS. Sự khác biệt chính nằm ở chỗ chứng chỉ trả phí có thêm gói hỗ trợ khách hàng và một số tùy chọn như bảo hiểm bồi thường, còn với cá nhân và phần lớn doanh nghiệp nhỏ, Let's Encrypt là đủ dùng.
Thực tế mình đã chuyển toàn bộ website cá nhân và cả website cho khách hàng sang Let's Encrypt từ nhiều năm nay. Chưa từng gặp vấn đề về tương thích trình duyệt. Ngay cả Google và Mozilla cũng liệt kê Let's Encrypt là CA đáng tin cậy trong danh sách gốc của họ.
Bước 1 - Cài đặt Certbot và plugin Nginx
Certbot là công cụ chính thức của Electronic Frontier Foundation (EFF) để làm việc với Let's Encrypt. Trên Ubuntu 24.04 và Debian 12, bạn có thể cài trực tiếp từ kho lưu trữ chính thức của hệ điều hành. Bản trong kho đã được kiểm tra kỹ, không cần thêm PPA bên ngoài.
sudo apt update
sudo apt install certbot python3-certbot-nginx
Gói python3-certbot-nginx là plugin giúp certbot tự động chỉnh sửa file cấu hình Nginx. Nó sẽ tìm kiếm cấu hình của domain trong /etc/nginx/sites-available/, cấp chứng chỉ, rồi tự động thêm khối cấu hình SSL vào. Bạn không cần phải viết tay từng dòng cấu hình SSL phức tạp.
Kiểm tra xem certbot đã cài thành công chưa:
certbot --version
Output mong đợi sẽ hiển thị phiên bản certbot, ví dụ certbot 2.9.0 hoặc mới hơn. Nếu gặp lỗi "command not found", hãy kiểm tra lại xem bạn đã chạy đúng lệnh sudo apt install chưa.
Bước 2 - Cấu hình Nginx và mở firewall
Certbot chỉ hoạt động khi Nginx đã có cấu hình server block cho domain của bạn. Nếu chưa có, hãy tạo một server block đơn giản trỏ về thư mục gốc của website.
sudo nano /etc/nginx/sites-available/example.com
Dán nội dung sau vào, thay example.com bằng domain thật của bạn và /var/www/example.com bằng đường dẫn thư mục chứa mã nguồn website:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
Kích hoạt server block bằng cách tạo symlink vào thư mục sites-enabled:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
Lệnh nginx -t kiểm tra cú pháp cấu hình. Nếu output hiển thị syntax is ok và test is successful, bạn có thể tải lại Nginx để áp dụng thay đổi:
sudo systemctl reload nginx
Tiếp theo, cấu hình firewall. Nếu bạn dùng UFW (mặc định trên Ubuntu), cần cho phép cả HTTP và HTTPS:
sudo ufw allow 'Nginx Full'
sudo ufw status
Lệnh ufw status sẽ hiển thị trạng thái firewall cùng các rule đang có. Nếu Nginx Full xuất hiện trong danh sách, port 80 và 443 đã được mở. Với VPS chạy AlmaLinux/Rocky dùng firewalld, lệnh sẽ khác đi, kiểm tra thêm hướng dẫn riêng.
Bước 3 - Cấp chứng chỉ SSL Let's Encrypt
Đây là bước quan trọng nhất. Lệnh dưới đây sẽ yêu cầu certbot cấp chứng chỉ cho domain của bạn và tự động cấu hình Nginx:
sudo certbot --nginx -d example.com -d www.example.com
Trong đó:
--nginx: báo cho certbot dùng plugin Nginx, tự động sửa cấu hình server block.-d example.com -d www.example.com: danh sách domain cần cấp chứng chỉ. Bạn có thể thêm nhiều domain hoặc subdomain vào đây.
Lần đầu chạy, certbot sẽ hỏi một vài câu hỏi:
- Nhập email khẩn cấp: Email để nhận thông báo khi chứng chỉ sắp hết hạn hoặc có vấn đề bảo mật.
- Đồng ý điều khoản dịch vụ: Gõ
Yđể đồng ý. - Chia sẻ email với EFF: Không bắt buộc, có thể chọn
N. - Chọn redirect HTTP sang HTTPS: Nên chọn
2để tự động chuyển hướng toàn bộ truy cập HTTP sang HTTPS.
Sau khi hoàn tất, certbot sẽ hiển thị thông báo thành công kèm đường dẫn tới chứng chỉ và ngày hết hạn. Cấu hình Nginx của bạn sẽ được tự động thêm khối listen 443 ssl cùng các dòng trỏ tới file chứng chỉ.
Verify ngay: Mở trình duyệt truy cập https://example.com. Nếu thấy biểu tượng ổ khóa màu xanh lá cạnh địa chỉ, chứng chỉ đã hoạt động. Bạn cũng có thể kiểm tra nhanh bằng lệnh:
curl -I https://example.com
Output mong đợi sẽ có dòng HTTP/2 200 cùng header strict-transport-security nếu bạn đã bật HSTS.
Bước 4 - Tự động gia hạn chứng chỉ
Chứng chỉ Let's Encrypt chỉ có giá trị 90 ngày. Đó là lý do bạn cần tự động gia hạn. May mắn là certbot đã tích hợp sẵn cơ chế này qua systemd timer trên Ubuntu và Debian.
Kiểm tra trạng thái timer gia hạn:
sudo systemctl status certbot.timer
Output mong đợi hiển thị trạng thái active (waiting). Timer này sẽ chạy hai lần mỗi ngày và tự động gia hạn bất kỳ chứng chỉ nào sắp hết hạn trong vòng 30 ngày.
Để chắc chắn quá trình gia hạn hoạt động, bạn có thể chạy thử ở chế độ dry-run, không cấp chứng chỉ thật:
sudo certbot renew --dry-run
Nếu không có lỗi nào xuất hiện và output kết thúc bằng dòng Congratulations, all simulated renewals succeeded, bạn không cần làm gì thêm. Hệ thống sẽ tự động gia hạn chứng chỉ trước khi hết hạn.
Trong trường hợp timer không hoạt động (ví dụ bạn dùng bản cài certbot từ nguồn khác), có thể tạo cron job thủ công:
echo "0 3 * * * /usr/bin/certbot renew --quiet" | sudo crontab -
Lệnh này chạy kiểm tra gia hạn lúc 3 giờ sáng mỗi ngày. Cờ --quiet giúp chỉ gửi email khi có lỗi, không spam khi gia hạn thành công.
Bước 5 - Xử lý lỗi thường gặp
Dù quy trình trên đã được tối giản, vẫn có những lỗi mà mình thấy người dùng hay gặp. Dưới đây là 3 lỗi phổ biến nhất và cách xử lý.
Lỗi "Domain name doesn't resolve" hoặc "DNS problem: NXDOMAIN"
Lỗi này có nghĩa là Let's Encrypt không thể phân giải domain của bạn về IP của VPS. Nguyên nhân thường do bản ghi DNS chưa có hiệu lực, hoặc trỏ sai địa chỉ IP. Kiểm tra lại bằng lệnh:
dig +short example.com
Output phải là địa chỉ IPv4 của VPS. Nếu không, hãy vào trang quản lý DNS của nhà đăng ký tên miền, sửa lại bản ghi A và đợi vài phút cho DNS propagation.
Lỗi "Failed to connect to host for DVSNI challenge"
Lỗi này thường do port 80 bị chặn bởi firewall, hoặc Nginx không chạy. Kiểm tra xem Nginx đã chạy chưa:
sudo systemctl status nginx
Và kiểm tra port 80 đã lắng nghe chưa:
sudo ss -tlnp | grep :80
Nếu không thấy output, Nginx chưa chạy. Nếu thấy nhưng vẫn lỗi, kiểm tra firewall. Trên VPS của một số nhà cung cấp, bạn cần mở port cả ở firewall hệ điều hành lẫn firewall của hạ tầng đám mây (nếu có). Với thuê VPS Linux tại thueVPS, firewall thường được cấu hình sẵn, chỉ cần mở thêm qua UFW hoặc firewalld.
Lỗi "Too many certificates issued for this exact set of domains"
Let's Encrypt giới hạn số lần cấp chứng chỉ cho một domain trong tuần. Điều này xảy ra khi bạn chạy lệnh cấp chứng chỉ quá nhiều lần trong thời gian ngắn. Giải pháp là chờ vài ngày hoặc dùng --dry-run để kiểm tra mà không tạo chứng chỉ mới. Mình từng gặp lỗi này khi thử nghiệm cấu hình, giờ cứ dùng lệnh renew --dry-run trước khi làm thật.
Kiểm tra log để hiểu rõ lỗi khi cần:
sudo journalctl -u certbot.timer -f
Lệnh này hiển thị log của timer gia hạn. Bạn sẽ thấy chi tiết lỗi nếu quá trình gia hạn thất bại.
Bảo mật thêm: HSTS và cấu hình SSL tốt hơn
Sau khi có chứng chỉ SSL hoạt động, bạn nên bật thêm HSTS (HTTP Strict Transport Security) để trình duyệt luôn sử dụng HTTPS, hiếm khi quay lại HTTP. Thêm dòng sau vào khối server trong file cấu hình Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Dòng này báo trình duyệt luôn dùng HTTPS cho domain và các subdomain trong vòng 1 năm. Chỉ nên bật HSTS khi bạn đã chắc chắn HTTPS hoạt động ổn định, vì nếu có lỗi, trình duyệt sẽ từ chối kết nối HTTP.
Ngoài ra, bạn có thể kiểm tra chất lượng cấu hình SSL bằng công cụ SSL Labs của Qualys. Truy cập https://www.ssllabs.com/ssltest/ và nhập domain của bạn. Điểm A hoặc A+ là mức tốt. Nếu điểm thấp, thường do phiên bản TLS cũ được bật. Bạn có thể chỉ cho phép TLS 1.2 và TLS 1.3 trong Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
Thêm dòng này vào khối server hoặc khối http trong /etc/nginx/nginx.conf, rồi reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
TLS 1.0 và TLS 1.1 đã bị coi là không an toàn từ năm 2021, nên việc tắt chúng là cần thiết. Hầu hết trình duyệt hiện đại đều hỗ trợ TLS 1.2 và 1.3, nên bạn không cần lo về việc người dùng không truy cập được.
Câu hỏi thường gặp
Let's Encrypt có thực sự miễn phí không?
Có, Let's Encrypt hoàn toàn miễn phí. Bạn chỉ cần trả tiền cho tên miền và VPS, còn chứng chỉ SSL thì không mất phí. Tuy nhiên, nếu bạn cần chứng chỉ wildcard hoặc EV (Extended Validation) để hiển thị tên doanh nghiệp trong thanh địa chỉ, bạn sẽ phải dùng dịch vụ trả phí khác.
Chứng chỉ Let's Encrypt có tương thích với mọi trình duyệt không?
Let's Encrypt là CA được công nhận bởi tất cả trình duyệt lớn: Chrome, Firefox, Safari, Edge. Chứng chỉ của họ dùng chuẩn tương thích rộng, hoạt động với mọi hệ điều hành và thiết bị hiện đại. Vấn đề chỉ xảy ra với thiết bị rất cũ không cập nhật danh sách CA gốc.
Sau khi cài SSL, website của tôi có bị chậm không?
Có một chút, nhưng không đáng kể. Quá trình mã hóa và giải mã TLS tốn một ít CPU. Trên VPS hiện đại với NVMe SSD và CPU đủ mạnh, bạn khó nhận ra sự khác biệt. Nếu website nặng, bạn có thể bật HTTP/2 hoặc HTTP/3 để bù lại, vì các giao thức này hoạt động tốt hơn khi kết hợp với HTTPS.
Tôi có cần mua chứng chỉ SSL từ nhà cung cấp dịch vụ VPS không?
Không bắt buộc. Bạn có thể tự cài Let's Encrypt hoàn toàn miễn phí trên mọi VPS có quyền root. Nếu bạn dùng dịch vụ VPS Linux full root hoặc VPS Windows Server, bạn đều có thể tự cài chứng chỉ. Một số nhà cung cấp có bán kèm SSL trả phí, nhưng với nhu cầu thông thường, Let's Encrypt là đủ.
Làm sao kiểm tra chứng chỉ SSL còn hạn không?
Dùng lệnh sau để xem thông tin chứng chỉ:
sudo certbot certificates
Lệnh này hiển thị tất cả chứng chỉ certbot đang quản lý, kèm ngày hết hạn và đường dẫn file. Nếu chứng chỉ gần hết hạn mà timer gia hạn không chạy, hãy kiểm tra lại systemd timer như hướng dẫn ở Bước 4.
Bài viết liên quan
- Cấu hình Nginx reverse proxy và SSL Let's Encrypt cho n8n
- Cài đặt Nginx làm reverse proxy trên VPS chi tiết 2026
- Bật HTTP/3 và nén Brotli trên Nginx 2026
- Tự động cấp và gia hạn SSL wildcard với acme.sh


