Chứng chỉ HTTPS hết hạn lúc nửa đêm và cách để không bị bất ngờ
Let's Encrypt đã ngừng gửi email nhắc hết hạn từ tháng 6/2025, và thời hạn chứng chỉ đang rút dần về 45 ngày. Cách kiểm việc tự gia hạn, đặt cảnh báo, thêm bản ghi CAA và tránh chạm giới hạn cấp chứng chỉ.
Trình duyệt của khách hiện trang đỏ “Kết nối của bạn không phải là kết nối riêng tư”. App mobile báo lỗi mạng chung chung. Webhook của cổng thanh toán gửi tới mà thất bại liên tục. Tất cả bắt đầu lúc 0 giờ, khi chứng chỉ HTTPS hết hạn, và bạn biết chuyện lúc 7 giờ sáng qua tin nhắn của khách.
Nhiều người tin Let’s Encrypt sẽ gửi email nhắc trước. Điều đó không còn đúng: Let’s Encrypt đã ngừng dịch vụ email nhắc hết hạn từ ngày 4/6/2025, với lý do phần lớn người dùng đã tự động gia hạn, và việc giữ hàng triệu địa chỉ email gắn với lịch sử cấp chứng chỉ vừa tốn tiền vừa không tốt cho quyền riêng tư.
Vì sao “tự gia hạn” vẫn hỏng
Certbot, Caddy, Traefik, cert-manager đều tự gia hạn. Chứng chỉ vẫn hết hạn vì những lý do rất đời thường:
Cổng 80 bị chặn. Cách xác thực HTTP-01 cần Let’s Encrypt gọi được vào http://ten-mien/.well-known/acme-challenge/. Ai đó bật tường lửa chặn cổng 80 “cho an toàn”, hoặc thêm redirect sai, là lần gia hạn sau thất bại.
DNS đã chuyển. Tên miền trỏ sang Cloudflare hay máy chủ mới, nhưng máy chủ cũ vẫn là nơi chạy certbot.
Token API DNS hết hạn. Xác thực DNS-01 (bắt buộc cho chứng chỉ wildcard) dùng token của nhà cung cấp DNS. Token bị xoay hoặc thu hồi, việc gia hạn im lặng thất bại.
Gia hạn xong nhưng chưa nạp. Certbot ghi file mới nhưng Nginx vẫn giữ chứng chỉ cũ trong bộ nhớ cho tới khi reload.
Máy chủ phụ bị quên. Trang chính dùng Vercel tự lo, còn api., admin., mail server, máy chủ staging thì nằm trên VPS cài tay từ hai năm trước.
Thời hạn đang ngắn lại
Bây giờ chuyện này còn quan trọng hơn. Tháng 4/2025, CA/Browser Forum (nơi các hãng trình duyệt và tổ chức cấp chứng chỉ thống nhất luật chung) thông qua lịch rút thời hạn tối đa của chứng chỉ công khai từ 398 ngày xuống 47 ngày, bắt đầu từ tháng 3/2026 và xong vào tháng 3/2029.
Let’s Encrypt đi nhanh hơn. Theo thông báo của họ:
Từ 13/5/2026, profile tlsserver (tự chọn) cấp chứng chỉ 45 ngày.
Từ 10/2/2027, profile mặc định classic cấp chứng chỉ 64 ngày.
Từ 16/2/2028, profile mặc định cấp chứng chỉ 45 ngày.
Hệ quả thực tế: cron gia hạn cố định mỗi 60 ngày sẽ không kịp. Let’s Encrypt khuyên dùng ARI (ACME Renewal Information) để server của họ báo khi nào nên gia hạn, hoặc gia hạn khi chứng chỉ đã đi được khoảng hai phần ba thời hạn. Và gia hạn bằng tay thì không còn là lựa chọn.
Kiểm việc tự gia hạn
Với certbot:
sudo certbot certificates # xem từng chứng chỉ, ngày hết hạnsudo certbot renew --dry-run # chạy thử gia hạn với môi trường stagingsystemctl list-timers | grep certbot # có timer chạy định kỳ không
Thêm lệnh nạp lại web server sau mỗi lần gia hạn thành công:
Caddy tự gia hạn và tự nạp, nhưng vẫn cần cổng 80 hoặc 443 mở ra ngoài. Traefik nhớ giữ file acme.json trên volume, nếu không mỗi lần container khởi động lại là xin chứng chỉ mới từ đầu.
Đặt cảnh báo, đừng chờ email
Cảnh báo nên chạy từ bên ngoài máy chủ, vì máy chủ hỏng thì nó cũng không tự báo được. Vài cách miễn phí:
Dịch vụ theo dõi uptime như Uptime Kuma (tự cài), Better Stack, UptimeRobot thường có tùy chọn báo khi chứng chỉ sắp hết hạn.
Let’s Encrypt gợi ý Red Sift Certificates Lite, miễn phí cho tối đa 250 chứng chỉ.
Tự viết một job chạy hằng ngày ở chỗ khác (GitHub Actions có lịch chạy, một máy khác):
(Trên macOS thay date -d bằng gdate -d sau khi cài coreutils.)
Đặt ngưỡng cảnh báo khoảng 14 ngày với chứng chỉ 90 ngày. Khi chuyển sang 45 ngày thì hạ xuống 7 đến 10 ngày, vì gia hạn bình thường đã diễn ra khi còn khoảng 15 ngày.
Bản ghi CAA: chỉ cho đúng nơi được cấp
CAA là bản ghi DNS nói “chỉ những tổ chức này được cấp chứng chỉ cho tên miền của tôi”. Tổ chức cấp chứng chỉ phải kiểm bản ghi này trước khi cấp. Nó không chặn được mọi thứ, nhưng làm khó hơn chuyện ai đó lợi dụng một tổ chức cấp chứng chỉ khác để xin chứng chỉ cho tên miền của bạn.
Dòng thứ hai cấm cấp chứng chỉ wildcard, bỏ đi nếu bạn có dùng. Nếu đặt tên miền sau Cloudflare proxy, Cloudflare tự cấp chứng chỉ ở phía họ qua một số tổ chức khác, nên thêm cả các tổ chức đó theo tài liệu của Cloudflare, nếu không chứng chỉ phía Cloudflare sẽ không cấp được.
Kiểm bằng: dig CAA app-cua-ban.com +short.
Đừng chạm giới hạn của Let’s Encrypt
Lúc hoảng, người ta hay xóa thư mục chứng chỉ rồi xin lại liên tục. Let’s Encrypt có giới hạn:
50 chứng chỉ mới cho mỗi tên miền đăng ký trong 7 ngày.
5 chứng chỉ trùng hệt danh sách tên miền trong 7 ngày, không xin nới được.
5 lần xác thực thất bại cho mỗi tên miền, mỗi tài khoản trong một giờ.
Chạm giới hạn thứ hai là phải chờ, trang của bạn đỏ suốt thời gian đó. Vì vậy khi thử cấu hình, luôn dùng môi trường staging (--dry-run hoặc --test-cert với certbot), và lưu thư mục /etc/letsencrypt hay acme.json vào chỗ bền.
Kiểm tra app của bạn trong vài phút
Liệt kê mọi tên miền con đang chạy HTTPS: tên miền chính, api, admin, staging, mail. Một cách nhanh là tra lịch sử chứng chỉ của tên miền trên crt.sh.
HTTPSmáy chủhạ tầng/anh/web/chung-chi-https-het-han-luc-nua-dem-480.webpHTTPS · máy chủ · hạ tầng
Chung chi HTTPS het han luc nua dem va cach de khong bi bat ngo Let's Encrypt da ngung gui email nhac het han tu thang 6/2025, va thoi han chung chi dang rut dan ve 45 ngay. Cach kiem viec tu gia han, dat canh bao, them ban ghi CAA va tranh cham gioi han cap chung chi. HTTPS may chu ha tang Trinh duyet cua khach hien trang do "Ket noi cua ban khong phai la ket noi rieng tu". App mobile bao loi mang chung chung. Webhook cua cong thanh toan gui toi ma that bai lien tuc. Tat ca bat dau luc 0 gio, khi chung chi HTTPS het han, va ban biet chuyen luc 7 gio sang qua tin nhan cua khach.
Nhieu nguoi tin Let's Encrypt se gui email nhac truoc. Dieu do khong con dung: Let's Encrypt da ngung dich vu email nhac het han tu ngay 4/6/2025, voi ly do phan lon nguoi dung da tu dong gia han, va viec giu hang trieu dia chi email gan voi lich su cap chung chi vua ton tien vua khong tot cho quyen rieng tu.

## Vi sao "tu gia han" van hong
Certbot, Caddy, Traefik, cert-manager deu tu gia han. Chung chi van het han vi nhung ly do rat doi thuong:
- **Cong 80 bi chan.** Cach xac thuc HTTP-01 can Let's Encrypt goi duoc vao `http://ten-mien/.well-known/acme-challenge/`. Ai do bat tuong lua chan cong 80 "cho an toan", hoac them redirect sai, la lan gia han sau that bai.
- **DNS da chuyen.** Ten mien tro sang Cloudflare hay may chu moi, nhung may chu cu van la noi chay certbot.
- **Token API DNS het han.** Xac thuc DNS-01 (bat buoc cho chung chi wildcard) dung token cua nha cung cap DNS. Token bi xoay hoac thu hoi, viec gia han im lang that bai.
- **Gia han xong nhung chua nap.** Certbot ghi file moi nhung Nginx van giu chung chi cu trong bo nho cho toi khi reload.
- **May chu phu bi quen.** Trang chinh dung Vercel tu lo, con `api.`, `admin.`, mail server, may chu staging thi nam tren VPS cai tay tu hai nam truoc.
## Thoi han dang ngan lai
Bay gio chuyen nay con quan trong hon. Thang 4/2025, CA/Browser Forum (noi cac hang trinh duyet va to chuc cap chung chi thong nhat luat chung) thong qua lich rut thoi han toi da cua chung chi cong khai tu 398 ngay xuong 47 ngay, bat dau tu thang 3/2026 va xong vao thang 3/2029.
Let's Encrypt di nhanh hon. Theo thong bao cua ho:
- Tu 13/5/2026, profile `tlsserver` (tu chon) cap chung chi 45 ngay.
- Tu 10/2/2027, profile mac dinh `classic` cap chung chi 64 ngay.
- Tu 16/2/2028, profile mac dinh cap chung chi 45 ngay.
He qua thuc te: cron gia han co dinh moi 60 ngay se khong kip. Let's Encrypt khuyen dung ARI (ACME Renewal Information) de server cua ho bao khi nao nen gia han, hoac gia han khi chung chi da di duoc khoang hai phan ba thoi han. Va gia han bang tay thi khong con la lua chon.
## Kiem viec tu gia han
Voi certbot:
```bash
sudo certbot certificates # xem tung chung chi, ngay het han
sudo certbot renew --dry-run # chay thu gia han voi moi truong staging
systemctl list-timers | grep certbot # co timer chay dinh ky khong
```
Them lenh nap lai web server sau moi lan gia han thanh cong:
```bash
# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/sh
systemctl reload nginx
```
Caddy tu gia han va tu nap, nhung van can cong 80 hoac 443 mo ra ngoai. Traefik nho giu file `acme.json` tren volume, neu khong moi lan container khoi dong lai la xin chung chi moi tu dau.
## Dat canh bao, dung cho email
Canh bao nen chay tu ben ngoai may chu, vi may chu hong thi no cung khong tu bao duoc. Vai cach mien phi:
- Dich vu theo doi uptime nhu Uptime Kuma (tu cai), Better Stack, UptimeRobot thuong co tuy chon bao khi chung chi sap het han.
- Let's Encrypt goi y Red Sift Certificates Lite, mien phi cho toi da 250 chung chi.
- Tu viet mot job chay hang ngay o cho khac (GitHub Actions co lich chay, mot may khac):
```bash
for d in app-cua-ban.com api.app-cua-ban.com admin.app-cua-ban.com; do
end=$(echo | openssl s_client -servername "$d" -connect "$d:443" 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days=$(( ( $(date -d "$end" +%s) - $(date +%s) ) / 86400 ))
[ "$days" -lt 14 ] && echo "CANH BAO: $d con $days ngay"
done
```
(Tren macOS thay `date -d` bang `gdate -d` sau khi cai `coreutils`.)
Dat nguong canh bao khoang 14 ngay voi chung chi 90 ngay. Khi chuyen sang 45 ngay thi ha xuong 7 den 10 ngay, vi gia han binh thuong da dien ra khi con khoang 15 ngay.
## Ban ghi CAA: chi cho dung noi duoc cap
CAA la ban ghi DNS noi "chi nhung to chuc nay duoc cap chung chi cho ten mien cua toi". To chuc cap chung chi phai kiem ban ghi nay truoc khi cap. No khong chan duoc moi thu, nhung lam kho hon chuyen ai do loi dung mot to chuc cap chung chi khac de xin chung chi cho ten mien cua ban.
```
app-cua-ban.com. CAA 0 issue "letsencrypt.org"
app-cua-ban.com. CAA 0 issuewild ";"
app-cua-ban.com. CAA 0 iodef "mailto:security@app-cua-ban.com"
```
Dong thu hai cam cap chung chi wildcard, bo di neu ban co dung. Neu dat ten mien sau Cloudflare proxy, Cloudflare tu cap chung chi o phia ho qua mot so to chuc khac, nen them ca cac to chuc do theo tai lieu cua Cloudflare, neu khong chung chi phia Cloudflare se khong cap duoc.
Kiem bang: `dig CAA app-cua-ban.com +short`.
## Dung cham gioi han cua Let's Encrypt
Luc hoang, nguoi ta hay xoa thu muc chung chi roi xin lai lien tuc. Let's Encrypt co gioi han:
- 50 chung chi moi cho moi ten mien dang ky trong 7 ngay.
- 5 chung chi trung het danh sach ten mien trong 7 ngay, khong xin noi duoc.
- 5 lan xac thuc that bai cho moi ten mien, moi tai khoan trong mot gio.
Cham gioi han thu hai la phai cho, trang cua ban do suot thoi gian do. Vi vay khi thu cau hinh, luon dung moi truong staging (`--dry-run` hoac `--test-cert` voi certbot), va luu thu muc `/etc/letsencrypt` hay `acme.json` vao cho ben.
## Kiem tra app cua ban trong vai phut
1. Liet ke moi ten mien con dang chay HTTPS: ten mien chinh, `api`, `admin`, staging, mail. Mot cach nhanh la tra lich su chung chi cua ten mien tren crt.sh.
2. Xem ngay het han cua tung cai: `echo | openssl s_client -servername ten-mien -connect ten-mien:443 2>/dev/null | openssl x509 -noout -enddate`.
3. Tren moi VPS tu quan: chay `certbot renew --dry-run` va xem co loi khong.
4. Kiem co deploy hook nap lai Nginx hoac Apache chua.
5. Dat mot canh bao chay tu ben ngoai, bao truoc it nhat 7 ngay.
6. Them ban ghi CAA, roi `dig CAA` de chac no da co.
---
Ban da bao gio bi chung chi het han ma khong biet chua, va ly do la gi? Vao [cong dong Vibe Code & Bao Mat](https://www.facebook.com/groups/1867387324580254) ke cho moi nguoi cung tranh nhe.
## Nguon
- [Expiration notification service has ended](https://letsencrypt.org/2025/06/26/expiration-notification-service-has-ended/) va [Ending Expiration Emails](https://letsencrypt.org/2025/01/22/ending-expiration-emails/), Let's Encrypt
- [Decreasing Certificate Lifetimes to 45 Days](https://letsencrypt.org/2025/12/02/from-90-to-45/), Let's Encrypt
- [Rate Limits](https://letsencrypt.org/docs/rate-limits/), Let's Encrypt
- [Ballot SC-081v3: Introduce Schedule of Reducing Validity and Data Reuse Periods](https://cabforum.org/2025/04/11/ballot-sc081v3-introduce-schedule-of-reducing-validity-and-data-reuse-periods/), CA/Browser Forum
- [Certificate Authority Authorization (CAA)](https://letsencrypt.org/docs/caa/), Let's Encrypt