Kết quả cần đạt: website trên VPS Vultr chạy Ubuntu và Nginx có chứng chỉ Let’s Encrypt đúng tên miền, truy cập được qua HTTPS và quy trình gia hạn đã được kiểm tra bằng sudo certbot renew --dry-run. Bài viết phù hợp với người có quyền SSH và sudo. Các lệnh có tiền tố sudo chạy trong phiên SSH trên VPS; các lệnh dig có thể chạy trên máy tính cá nhân hoặc VPS.
Quy trình này dùng xác thực HTTP-01. Vì vậy, tên miền phải trỏ đến VPS và máy chủ phải nhận được kết nối từ Internet qua TCP 80. HTTPS cần thêm TCP 443. Let’s Encrypt cấp chứng chỉ có thời hạn 90 ngày; cài được chứng chỉ chưa đồng nghĩa với việc quy trình gia hạn đã hoạt động.
Phạm vi, điều kiện và giá trị cần thay thế
- VPS Vultr chạy Ubuntu 22.04 hoặc Ubuntu 24.04.
- Nginx đã cài hoặc sẽ được cài trong bài này.
- Tài khoản SSH có quyền
sudo. - Bạn có quyền chỉnh DNS của tên miền và Vultr Firewall Group nếu VPS đang dùng nhóm firewall này.
- Trong các lệnh dưới đây, thay
example.combằng tên miền thật. Nếu không dùngwww, bỏ tham số-d www.example.comvà các bản ghi DNS tương ứng.
Chứng chỉ TLS không phụ thuộc vào PHP. Nếu website là ứng dụng PHP hoặc WordPress, PHP-FPM và các tiện ích PHP phải hoạt động riêng; không cần thay đổi upload_max_filesize, memory_limit hay max_execution_time chỉ để cấp chứng chỉ. Có thể kiểm tra phần PHP sau khi HTTPS hoạt động.
1. Trỏ DNS và kiểm tra Nginx trước khi cấp chứng chỉ
Cấu hình bản ghi DNS
Tại nhà đăng ký tên miền hoặc dịch vụ DNS đang quản lý tên miền, tạo các bản ghi tối thiểu sau:
| Loại | Tên | Giá trị | Mục đích |
|---|---|---|---|
| A | @ | IPv4 của VPS Vultr | Tên miền chính |
| A | www | IPv4 của VPS Vultr | Tên miền www |
Nếu có bản ghi AAAA, chỉ giữ bản ghi đó khi VPS thực sự có IPv6 và Nginx/firewall phục vụ được IPv6. Một AAAA trỏ sai có thể khiến máy chủ xác thực truy cập nhầm nơi dù bản ghi A đã đúng.
Chạy từ máy tính cá nhân hoặc từ VPS:
dig +short A example.com
dig +short A www.example.com
dig +short AAAA example.com
dig +short AAAA www.example.com
Kết quả bản ghi A phải là IPv4 của VPS. Nếu có AAAA, địa chỉ đó phải là IPv6 thật của VPS. DNS mới thay đổi có thể chưa được cập nhật ở mọi nơi do TTL và bộ nhớ đệm DNS; không chạy Certbot cho đến khi kết quả phân giải phù hợp.
Kiểm tra Nginx và server block
Trên VPS, chạy:
sudo systemctl status nginx --no-pager
sudo nginx -t
curl -I http://example.com
Kết quả mong đợi là Nginx đang chạy, nginx -t báo cấu hình hợp lệ và curl nhận được phản hồi HTTP. Server block phải chứa đúng tên miền, chẳng hạn:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
Đoạn trên chỉ là ví dụ cho website tĩnh. Nếu đang dùng PHP-FPM, reverse proxy hoặc WordPress, giữ nguyên các chỉ thị location đang phục vụ ứng dụng; không thay toàn bộ server block bằng ví dụ này.
Với website PHP, có thể kiểm tra thêm trên VPS:
php -v
php -m
systemctl list-units --type=service --all 'php*-fpm.service' --no-pager
Nếu ứng dụng dùng PHP-FPM, tên dịch vụ thường có dạng php8.1-fpm hoặc php8.3-fpm, tùy phiên bản đã cài. Lỗi PHP-FPM không phải lỗi cấp chứng chỉ, nhưng có thể làm website trả về 502 sau khi bật HTTPS.
2. Mở TCP 80 và 443 ở cả hai lớp firewall
HTTP-01 cần TCP 80; website HTTPS cần TCP 443. Kiểm tra cả Vultr Firewall Group và firewall trong Ubuntu. Tài liệu liên quan của Vultr có thể xem tại How Do I Install an SSL Certificate on a Vultr Compute Instance?.
Trong bảng điều khiển Vultr, mở Firewall Group gắn với VPS và cho phép:
- TCP 22 từ IP quản trị của bạn, hoặc cổng SSH thực tế nếu đã đổi cổng.
- TCP 80 từ Internet.
- TCP 443 từ Internet.
Trên VPS, thay 22 bằng cổng SSH thực tế nếu bạn không dùng cổng mặc định. Chạy từng lệnh:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Nếu UFW chưa từng được bật, lệnh sudo ufw enable có thể hỏi xác nhận. Chỉ tiếp tục sau khi đã cho phép đúng cổng SSH; nếu không, bạn có thể tự khóa phiên quản trị. Kết quả kiểm tra phải hiển thị các quy tắc cho SSH, HTTP và HTTPS.
Nếu muốn kiểm tra từ một mạng bên ngoài VPS, dùng máy tính cá nhân hoặc một máy chủ khác:
curl -I http://example.com
Nếu lệnh bị timeout, kiểm tra DNS, Vultr Firewall, UFW và firewall khác trước khi chạy Certbot.
3. Sao lưu cấu hình và cài Certbot
Sao lưu trước khi Certbot chỉnh Nginx
Trên VPS, tạo bản sao lưu có dấu thời gian:
BACKUP_DIR="/root/nginx-backup-$(date +%F-%H%M%S)"
sudo cp -a /etc/nginx "$BACKUP_DIR"
printf '%sn' "$BACKUP_DIR"
Lệnh cuối in ra đường dẫn bản sao lưu. Ghi lại đường dẫn này; sẽ dùng khi cần rollback. Kiểm tra thư mục đã tồn tại:
sudo test -d "$BACKUP_DIR" && echo "Da tao backup: $BACKUP_DIR"
Cài Nginx nếu VPS chưa có
Nếu Nginx đã chạy và sudo nginx -t thành công, bỏ qua bước cài Nginx. Với VPS mới, chạy trên VPS:
sudo apt update
sudo apt install -y nginx snapd
sudo systemctl enable --now nginx
sudo nginx -t
Kết quả cuối phải báo cấu hình hợp lệ. Nếu Nginx chưa có server block cho tên miền, quay lại bước DNS và cấu hình server block trước khi yêu cầu chứng chỉ.
Cài Certbot qua Snap
Trên VPS, chạy lần lượt:
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -sfn /snap/bin/certbot /usr/local/bin/certbot
certbot --version
Lệnh cuối phải in ra phiên bản Certbot. Không nên đồng thời cài nhiều bản Certbot từ Snap, APT và pip nếu không cần, vì bạn có thể kiểm tra nhầm chương trình hoặc nhầm tác vụ gia hạn.
4. Cấp chứng chỉ và bật HTTPS cho Nginx
Trên VPS, chạy lệnh sau và thay tên miền mẫu bằng tên miền thật:
sudo certbot --nginx -d example.com -d www.example.com
Certbot sẽ hỏi email, điều khoản sử dụng và tùy chọn chuyển hướng HTTP sang HTTPS. Với website công khai, có thể chọn chuyển hướng nếu ứng dụng không phụ thuộc vào HTTP thuần. Không yêu cầu chứng chỉ cho tên miền chưa phân giải về VPS.
Plugin Nginx sẽ tìm server block phù hợp, thêm cấu hình TLS và có thể tải lại Nginx. Nếu lệnh thất bại, không xóa chứng chỉ hoặc cấu hình cũ; ghi lại thông báo lỗi rồi kiểm tra DNS, cổng 80 và server block.
Certbot dùng đường dẫn quản lý riêng trong /etc/letsencrypt. Không tự xóa các tệp ở đó. Sau khi lệnh thành công, kiểm tra:
sudo nginx -t
sudo systemctl reload nginx
sudo certbot certificates
certbot certificates phải hiển thị đúng tên miền, ngày hết hạn và đường dẫn chứng chỉ. Nếu nginx -t thất bại, không reload Nginx cho đến khi sửa xong lỗi cú pháp.
5. Kiểm tra HTTPS, HTTP redirect và ứng dụng
Trên VPS hoặc máy tính cá nhân, chạy:
curl -I http://example.com
curl -I https://example.com
curl -sS -o /dev/null -w '%{http_code}n' https://example.com
Kết quả mong đợi:
- HTTP trả về
301hoặc308đến HTTPS nếu đã chọn chuyển hướng. - HTTPS trả về phản hồi của website và không báo lỗi chứng chỉ.
- Tên miền trong chứng chỉ bao gồm mọi tên miền bạn truy cập, chẳng hạn cả
example.comvàwww.example.com.
Mã 200, 301 hoặc mã do ứng dụng chủ động trả về đều có thể hợp lệ tùy cấu hình. Nếu HTTPS trả về 502, kiểm tra PHP-FPM hoặc upstream:
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx -n 50 --no-pager
systemctl list-units --type=service --all 'php*-fpm.service' --no-pager
Nếu website dùng PHP, hãy kiểm tra đúng phiên bản PHP-FPM và các tiện ích mà ứng dụng yêu cầu. Không coi việc chỉnh php.ini là bước bắt buộc của SSL; các giới hạn tải tệp, bộ nhớ và thời gian chạy chỉ cần điều chỉnh khi ứng dụng có yêu cầu riêng.
6. Kiểm tra cơ chế gia hạn tự động
Kiểm tra timer hoặc cron
Certbot thường cài systemd timer hoặc một cron job để định kỳ kiểm tra chứng chỉ sắp hết hạn. Trên VPS, tìm timer:
systemctl list-timers --all | grep -i certbot || true
systemctl list-unit-files | grep -i certbot || true
systemctl status snap.certbot.renew.timer --no-pager
Tên timer có thể khác tùy phiên bản và phương thức cài đặt. Nếu snap.certbot.renew.timer không tồn tại, dùng kết quả của hai lệnh đầu để tìm đúng đơn vị; không tự tạo thêm cron job khi đã có timer.
Nếu không tìm thấy timer, kiểm tra cron:
sudo grep -R "certbot renew" /etc/cron.d /etc/cron.daily /var/spool/cron 2>/dev/null || true
Cần phân biệt hai việc: timer/cron chỉ khởi chạy lệnh; DNS, firewall, Nginx và cấu hình tên miền vẫn phải còn đúng thì gia hạn mới thành công.
Mô phỏng một lần gia hạn
Đây là kiểm tra quan trọng nhất sau khi cấp chứng chỉ. Trên VPS, chạy:
sudo certbot renew --dry-run
--dry-run dùng môi trường thử nghiệm và không thay thế chứng chỉ đang phục vụ. Kết quả thành công phải cho thấy quá trình gia hạn thử nghiệm hoàn tất mà không có lỗi xác thực hoặc triển khai. Nếu thất bại, đọc toàn bộ đầu ra để xác định lỗi DNS, HTTP-01, firewall, Nginx hoặc hook triển khai.
Sau khi thử nghiệm thành công, kiểm tra lại Nginx và website:
sudo nginx -t
sudo systemctl reload nginx
curl -sS -o /dev/null -w '%{http_code}n' https://example.com
Không cần chạy certbot renew thủ công hằng tháng. Chỉ dùng lệnh đó khi có lý do vận hành rõ ràng; timer sẽ tự kiểm tra theo lịch.
7. Chẩn đoán lỗi theo triệu chứng
| Triệu chứng | Nguyên nhân thường gặp | Kiểm tra và xử lý |
|---|---|---|
| Timeout khi xác thực | TCP 80 bị chặn ở Vultr Firewall, UFW hoặc firewall khác. | Kiểm tra sudo ufw status verbose, Firewall Group và chạy curl -I http://example.com từ mạng bên ngoài. |
| IP xác thực không đúng | Bản ghi A hoặc AAAA trỏ sang máy chủ khác. | Chạy dig +short A example.com và dig +short AAAA example.com; sửa DNS hoặc xóa AAAA sai. |
| 404 ở đường dẫn ACME | Rewrite, reverse proxy hoặc ứng dụng xử lý sai /.well-known/acme-challenge/. | Kiểm tra server block và quy tắc rewrite; bảo đảm tên miền qua cổng 80 đến đúng Nginx. |
| Nginx không reload | Cấu hình TLS có lỗi cú pháp hoặc xung đột với cấu hình cũ. | Chạy sudo nginx -t, sửa đúng tệp được báo lỗi rồi mới chạy sudo systemctl reload nginx. |
--dry-run thất bại | DNS, firewall, tên miền hoặc cấu hình web đã thay đổi. | Đọc đầu ra Certbot và log, sửa nguyên nhân rồi chạy lại; không xóa chứng chỉ cũ trong lúc điều tra. |
| Chứng chỉ không khớp tên miền | Chứng chỉ không bao gồm biến thể đang truy cập, chẳng hạn www. | Chạy sudo certbot certificates; nếu cần, cấp lại với đầy đủ tham số -d. |
| HTTPS trả về 502 | PHP-FPM hoặc upstream phía sau Nginx không hoạt động. | Kiểm tra trạng thái dịch vụ PHP-FPM/upstream và log Nginx; đây không nhất thiết là lỗi chứng chỉ. |
Let’s Encrypt dùng HTTP-01 bằng cách đặt token tại /.well-known/acme-challenge/ rồi truy cập token đó từ Internet. Vì vậy, chỉ mở TCP 443 là chưa đủ cho phương thức này. Xem thêm Challenge Types — Let’s Encrypt.
8. Rollback an toàn khi cấu hình Nginx lỗi
Nếu sau khi Certbot chỉnh sửa mà Nginx không kiểm tra được hoặc website lỗi, trước hết không chạy thêm lệnh cấp/gia hạn. Xác định lỗi:
sudo nginx -t
sudo certbot certificates
sudo ls -la /etc/letsencrypt/live/example.com/
Thay example.com bằng tên miền thật. Nếu cần khôi phục bản sao lưu đã tạo ở bước 3, đặt đúng đường dẫn trước khi chạy:
BACKUP_DIR="/root/nginx-backup-YYYY-MM-DD-HHMMSS"
if sudo test -d "$BACKUP_DIR"; then
sudo mv /etc/nginx "/etc/nginx.failed-$(date +%F-%H%M%S)"
sudo cp -a "$BACKUP_DIR" /etc/nginx
sudo nginx -t
sudo systemctl reload nginx
else
echo "Khong tim thay thu muc sao luu: $BACKUP_DIR" >&2
exit 1
fi
Thay YYYY-MM-DD-HHMMSS bằng tên thư mục sao lưu thật. Đoạn lệnh có kiểm tra thư mục trước khi khôi phục để tránh dùng nhầm đường dẫn. Không xóa /etc/letsencrypt trong lúc điều tra; thư mục đó chứa chứng chỉ, khóa và dữ liệu cần cho Certbot. Chỉ triển khai lại chứng chỉ sau khi đã sửa nguyên nhân và sudo nginx -t thành công.
Checklist nghiệm thu
- Bản ghi A của các tên miền cần dùng trỏ đúng IPv4 VPS.
- AAAA không tồn tại hoặc trỏ đúng IPv6 mà VPS thực sự phục vụ.
- Vultr Firewall và UFW cho phép TCP 80, TCP 443; SSH vẫn truy cập được.
sudo nginx -tthành công trước và sau khi chạy Certbot.sudo certbot certificateshiển thị đúng tên miền và ngày hết hạn.- HTTPS mở được và chứng chỉ khớp mọi tên miền cần dùng.
- HTTP chuyển hướng đúng nếu đã chọn tùy chọn chuyển hướng.
- Systemd timer hoặc cron của Certbot tồn tại và không bị vô hiệu hóa.
sudo certbot renew --dry-runhoàn tất không lỗi.- Có đường dẫn bản sao lưu cấu hình Nginx và đã biết cách khôi phục.
Nếu quản lý nhiều website hoặc nhiều VPS, nên ghi lại tên miền, nơi kết thúc TLS, phương thức xác thực, cơ chế timer/cron và ngày chạy --dry-run. Bạn có thể xem thêm bài viết bật HTTPS và sửa lỗi CAA cho Blogger, nhóm bảo mật blog và hướng dẫn Hosting và máy chủ khi cần tham khảo các cấu hình HTTPS khác.
Kết luận
Để cài Let’s Encrypt trên VPS Vultr đáng tin cậy, cần hoàn thành đủ chuỗi: DNS đúng, TCP 80 và 443 mở ở cả hai lớp firewall, Nginx có server block đúng tên miền, Certbot cấp được chứng chỉ và sudo certbot renew --dry-run chạy thành công. Sau mỗi thay đổi DNS, firewall hoặc Nginx, nên kiểm tra lại quy trình thử nghiệm thay vì chỉ nhìn biểu tượng khóa trên trình duyệt.
Nguồn tham khảo
- How Do I Install an SSL Certificate on a Vultr Compute Instance? — Vultr Docs.
- Obtain TLS certificates — Ubuntu Server documentation.
- Certbot Instructions — Certbot.
- Challenge Types — Let’s Encrypt.
- Firewall — Ubuntu Server documentation.

