Điều Gì Đang Xảy Ra
Bạn mở một trang web trong trình duyệt và gặp phải thông báo chặn:
You cannot visit this site right now because it uses HSTS.
Network errors and attacks are usually temporary, so this page will probably work later.
Trình duyệt không bị lỗi. Nó đang làm đúng những gì được lập trình. HSTS (HTTP Strict Transport Security) là một chính sách bảo mật ra lệnh cho trình duyệt: không bao giờ kết nối đến domain này qua HTTP thông thường, chỉ dùng HTTPS. Một khi chỉ thị đó được thiết lập — từ lần truy cập trước hoặc từ danh sách HSTS preload được tích hợp sẵn trong trình duyệt — nó sẽ bắt buộc dùng HTTPS tuyệt đối. Mọi yêu cầu HTTP đều bị chặn trước khi rời khỏi máy của bạn.
Lỗi này xuất hiện trong hai trường hợp:
- Bạn là developer đã bật HSTS, sau đó HTTPS bị hỏng — cert hết hạn, redirect cấu hình sai, hoặc môi trường dev local chạy không có TLS.
- Bạn đang truy cập một domain đã gửi header HSTS hợp lệ trong phiên trước đó, hoặc domain đó nằm trong danh sách preload được tích hợp cứng trong trình duyệt.
Nguyên Nhân Gốc Rễ
Việc thực thi HSTS đến từ hai nguồn hoàn toàn khác nhau:
- Cache HSTS của trình duyệt: Khi trình duyệt truy cập một trang gửi header
Strict-Transport-Security, nó lưu chính sách đó cục bộ. Mọi lần truy cập tiếp theo sẽ tự động nâng cấp HTTP lên HTTPS. Nếu HTTPS thất bại, trình duyệt hiển thị lỗi này — nó sẽ không fallback về HTTP thông thường. - Danh sách preload: Chrome, Firefox, Edge và Safari đều được tích hợp sẵn một danh sách cứng các domain bị khóa với HTTPS. Nếu domain của bạn nằm trong đó, ngay cả khi cài trình duyệt mới hoàn toàn cũng sẽ bị chặn HTTP. Danh sách này được biên dịch vào nhị phân của trình duyệt. Xóa cache không có tác dụng gì.
Chẩn Đoán Bạn Đang Gặp Trường Hợp Nào
Kiểm tra cache HSTS của Chrome
Mở Chrome và truy cập:
chrome://net-internals/#hsts
Trong phần Query HSTS/PKP domain, nhập domain của bạn (ví dụ: example.com) và nhấn Query. Có kết quả nghĩa là Chrome đã cache HSTS cho domain đó.
Xem trường static_sts_domain trong kết quả. Nếu là true, domain đó nằm trong danh sách preload. Xóa cache sẽ không giúp được gì — bạn đang thuộc trường hợp Cách Sửa 3.
Kiểm tra trạng thái HSTS của Firefox
Firefox không có trang nội bộ tương đương Chrome. Cách nhanh nhất là dùng hstspreload.org — dán domain vào và nó sẽ cho biết ngay domain có được preload không và trên trình duyệt nào.
Với HSTS được cache cục bộ (không phải preload), xóa site preferences của Firefox sẽ gỡ bỏ nó. Xem Cách Sửa 1 bên dưới.
Cách Sửa 1: Xóa Cache HSTS Của Trình Duyệt (Dành Cho Người Dùng)
Cách này chỉ hiệu quả nếu domain không nằm trong danh sách preload. Nếu có, hãy chuyển thẳng đến Cách Sửa 3.
Chrome
- Truy cập
chrome://net-internals/#hsts - Cuộn xuống phần Delete domain security policies
- Nhập domain (ví dụ:
example.com) — không cóhttp://hayhttps:// - Nhấn Delete
- Chạy Query lại để xác nhận — không có kết quả trả về là thành công
Firefox
- Đóng tất cả tab của trang bị ảnh hưởng
- Mở menu History → Clear Recent History
- Đặt khoảng thời gian là Everything
- Tích vào Active Logins và Site Preferences
- Nhấn Clear Now
Site Preferences là nơi lưu dữ liệu HSTS. Chỉ xóa "Cache" sẽ không đụng đến bản ghi HSTS — đây là lỗi thường gặp.
Edge
edge://net-internals/#hsts
Thao tác giống Chrome. Tìm Delete domain security policies, nhập domain, xóa.
Safari (macOS)
Safari không có giao diện người dùng cho việc này. Bạn phải xóa trực tiếp file:
- Thoát hoàn toàn Safari
- Xóa database HSTS:
rm ~/Library/Cookies/HSTS.plist
- Mở lại Safari
Cách Sửa 2: Sửa Cấu Hình HSTS Phía Server (Dành Cho Developer)
Nếu bạn đã bật HSTS và giờ cần truy cập HTTP — dev local, chuyển domain, cert hết hạn — đây là cách gỡ bỏ mà không khóa người dùng của chính bạn.
Giảm max-age trước khi xóa HSTS
Đừng chỉ xóa header HSTS đột ngột. Trình duyệt cache chính sách cũ cho đến khi max-age hết hạn, nên những người dùng hiện tại vẫn bị chặn dù sao. Đặt max-age=0 trước để người dùng mới ngừng thực thi HSTS trong khi các cache cũ dần hết hạn:
# Nginx
add_header Strict-Transport-Security "max-age=0" always;
# Apache
Header always set Strict-Transport-Security "max-age=0"
Chờ hết thời gian max-age ban đầu — có thể lên đến 365 ngày nếu bạn đặt max-age=31536000. Sau đó mới xóa hoàn toàn header.
Nếu SSL cert hết hạn hoặc HTTPS bị hỏng
Sửa HTTPS trước. Không gì khác quan trọng cho đến khi điều đó hoạt động. Gia hạn cert:
# Let's Encrypt / Certbot
sudo certbot renew
sudo systemctl reload nginx
# Xác minh cert còn hiệu lực
curl -I https://yourdomain.com
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -dates
Phát triển local không có HTTPS
Dùng hostname khác cho dev local — đừng chạy domain production trên máy local. Dùng cái gì đó như myapp.local để tránh hoàn toàn HSTS. Nếu bạn thực sự cần HTTPS ở local, mkcert tạo cert local được trình duyệt tin tưởng trong chưa đầy một phút:
mkcert -install
mkcert localhost 127.0.0.1 myapp.local
Cách Sửa 3: Xóa Khỏi Danh Sách HSTS Preload (Quá Trình Lâu Dài)
Đã xóa cache trình duyệt mà vẫn bị chặn? Domain nằm trong danh sách preload. Xóa cache không liên quan ở đây. Chỉ có một cách thoát:
- Giữ HTTPS hoạt động. Những người duy trì danh sách preload sẽ không xử lý yêu cầu gỡ bỏ nếu HTTPS của bạn bị hỏng.
- Xóa chỉ thị
preloadkhỏi header HSTS của bạn:
# Trước (có preload)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# Sau (xóa chỉ thị preload)
Strict-Transport-Security: max-age=31536000; includeSubDomains
- Gửi yêu cầu gỡ bỏ tại hstspreload.org/removal
- Chờ đợi — việc gỡ bỏ mất nhiều tháng. Cần có bản cập nhật Chrome mới thực sự đến tay người dùng.
Người dùng trên phiên bản trình duyệt cũ hơn vẫn bị chặn trong suốt thời gian đó. Đây là cam kết cấp độ vĩnh viễn. Đừng bao giờ thêm preload vào domain mà bạn có thể cần quay lại dùng HTTP.
Xác Minh
Sau khi áp dụng cách sửa, chạy các kiểm tra sau:
# Kiểm tra header HSTS hiện tại từ server của bạn
curl -sI https://yourdomain.com | grep -i strict
# Xác nhận HTTP redirect đúng cách
curl -sI http://yourdomain.com | grep -i location
# Kiểm tra toàn bộ chuỗi TLS
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
Quay lại Chrome, truy cập chrome://net-internals/#hsts và query domain của bạn. Xóa cache thành công sẽ không trả về kết quả gì. Nếu static_sts_domain: true vẫn xuất hiện, domain đó đã được preload — cache trình duyệt không bao giờ là vấn đề.
Phòng Ngừa
HSTS là cánh cửa một chiều. Hãy đối xử với nó như vậy trước khi bật — đặc biệt với preload.
- Thiết lập tự động gia hạn SSL cert trước khi bật HSTS. Systemd timer của Certbot xử lý Let's Encrypt tự động; AWS ACM tự gia hạn. Cert hết hạn cộng với HSTS sẽ khóa người dùng mà không có cách thoát nhanh.
- Kiểm tra với
max-agengắn trước —max-age=300cho bạn cửa sổ 5 phút để phát hiện vấn đề trước khi cam kết cả năm. - Đừng bao giờ thêm
preloadvào domain mà bạn có thể cần quay lại HTTP. Quá trình thoát ra một mình đã mất nhiều tháng. - Theo dõi chủ động thời hạn cert. Khi người dùng báo cáo lỗi HSTS, cert đã hết hạn đủ lâu để thiệt hại lan rộng rồi.
Khi xử lý các vấn đề SSL hoặc HTTPS liên quan đến quy tắc firewall và routing, dải CIDR thường xuất hiện. Subnet Calculator của ToolCraft xử lý điều đó nhanh chóng — chạy hoàn toàn trên trình duyệt, không gửi dữ liệu đi đâu cả.
Bài Học Rút Ra
- HSTS được thiết kế cố tình để khó hoàn tác. Trình duyệt tin vào chính sách được cache hơn bất kỳ điều gì server nói lúc này — đó chính là toàn bộ ý nghĩa của mô hình bảo mật này.
- Danh sách preload không phải là cache trình duyệt. Đây là hai cơ chế khác nhau với cách sửa khác nhau. Xóa cache không gỡ bỏ các entry trong preload.
- Bắt đầu với
max-age=300khi kiểm tra HSTS. Chỉ tăng lên 1 năm — và thêmpreload— khi bạn đã hoàn toàn cam kết và HTTPS đã vững chắc. - Kế thừa domain có vấn đề HSTS? Kiểm tra hstspreload.org ngay lập tức. Nó cho bạn biết ngay liệu cách sửa mất vài giờ hay vài tháng.

