Lỗi Gặp Phải
Bạn thấy thông báo này trên trình duyệt:
NET::ERR_CERT_COMMON_NAME_INVALID
The server's security certificate does not match the website's URL.
Chứng chỉ trên máy chủ của bạn không bao gồm tên miền mà trình duyệt đang cố truy cập. Trình duyệt từ chối kết nối.
Nguyên Nhân Gốc Rễ
Chứng chỉ TLS khai báo các tên miền được bảo vệ trong hai trường: Common Name (CN) và phần mở rộng Subject Alternative Names (SAN). Các trình duyệt hiện đại chỉ kiểm tra SAN. Chrome đã bỏ kiểm tra CN từ phiên bản 58 (2017), và tất cả các trình duyệt lớn khác cũng làm theo.
Các nguyên nhân thường gặp:
- Chứng chỉ được cấp cho
example.comnhưng bạn đang truy cậpwww.example.com(hoặc ngược lại) - Chứng chỉ được cấp cho một tên miền nhưng lại triển khai trên máy chủ đang phục vụ tên miền khác
- Truy cập máy chủ qua địa chỉ IP trong khi chứng chỉ chỉ liệt kê tên hostname
- Wildcard cert
*.example.com— bao gồm các subdomain nhưng KHÔNG bao gồmexample.comgốc - Chứng chỉ tự ký được tạo mà không có phần mở rộng SAN
- File chứng chỉ cũ từ tên miền trước vẫn còn được cấu hình trên máy chủ
Bước 1: Chẩn Đoán Sự Không Khớp
Trước khi thay đổi bất cứ thứ gì, hãy tìm hiểu chính xác chứng chỉ đang triển khai thực sự bao gồm những tên miền nào:
# Kiểm tra các tên miền được liệt kê trong trường SAN của chứng chỉ
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
| openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
# Kiểm tra thêm CN
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
| openssl x509 -noout -subject
Một chứng chỉ không khớp trông như thế này:
Subject: CN = old-domain.com
X509v3 Subject Alternative Name:
DNS:old-domain.com, DNS:www.old-domain.com
Nếu tên miền của bạn không xuất hiện trong SAN, đó chính là vấn đề.
Cách Sửa 1: Cấp Lại Chứng Chỉ Với Tên Miền Đúng
Giải pháp lâu dài đúng đắn: lấy chứng chỉ mới thực sự bao gồm tên miền của bạn. Dùng Let's Encrypt với Certbot:
# Một tên miền + www
certbot --nginx -d example.com -d www.example.com
# Hoặc với Apache
certbot --apache -d example.com -d www.example.com
# Chế độ standalone (không tích hợp web server)
certbot certonly --standalone -d example.com -d www.example.com
Certbot tự động thêm cả hai tên miền vào trường SAN. Reload web server sau khi hoàn tất:
sudo systemctl reload nginx
# hoặc
sudo systemctl reload apache2
Cách Sửa 2: Chứng Chỉ Đúng Nhưng Sai Đường Dẫn — Trỏ Server Đến File Đúng
Đôi khi chứng chỉ đúng đã tồn tại trên máy chủ — chỉ là không phải file mà cấu hình đang tải. Kiểm tra và sửa lại đường dẫn.
Nginx:
server {
listen 443 ssl;
server_name example.com www.example.com;
# Đảm bảo các đường dẫn này trỏ đến chứng chỉ bao gồm example.com
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
}
Apache:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
Kiểm tra cấu hình trước khi reload — không bao giờ bỏ qua bước này:
sudo nginx -t && sudo systemctl reload nginx
# hoặc
sudo apachectl configtest && sudo systemctl reload apache2
Cách Sửa 3: Chứng Chỉ Tự Ký Thiếu SAN (Dev/Nội Bộ)
Lệnh openssl req thông thường tạo ra chứng chỉ chỉ có CN — không có phần mở rộng SAN. Chrome từ chối hoàn toàn những chứng chỉ như vậy. Bạn cần truyền vào file cấu hình có khai báo rõ ràng các mục SAN:
# Tạo file cấu hình OpenSSL có SAN
cat > cert.cnf <<EOF
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = myapp.local
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = myapp.local
DNS.2 = localhost
IP.1 = 127.0.0.1
EOF
# Tạo chứng chỉ có SAN
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout myapp.key -out myapp.crt -config cert.cnf
Sau đó tin tưởng chứng chỉ ở máy cục bộ. Trên macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain myapp.crt
Trên Ubuntu/Debian:
sudo cp myapp.crt /usr/local/share/ca-certificates/myapp.crt
sudo update-ca-certificates
Cách Sửa 4: Wildcard Cert Không Bao Gồm Tên Miền Gốc
*.example.com bao gồm www.example.com, api.example.com, và bất kỳ subdomain nào khác — nhưng example.com gốc không được bao gồm. Cấp lại chứng chỉ với cả hai được liệt kê rõ ràng:
certbot certonly --nginx -d example.com -d '*.example.com' \
--preferred-challenges dns-01
Wildcard cert yêu cầu dùng DNS-01 challenge thay vì HTTP-01. Trong quá trình cấp, Certbot sẽ yêu cầu bạn thêm một bản ghi TXT _acme-challenge vào DNS zone của mình. Thêm vào, chờ 30–60 giây để propagation, rồi tiếp tục.
Xác Minh Sau Khi Sửa
Sau bất kỳ thay đổi nào, hãy xác nhận chứng chỉ đã liệt kê đúng tên miền trước khi kết luận hoàn thành:
# Kiểm tra các mục SAN trên server thực tế
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text | grep -A5 "Subject Alternative Name"
# Kết quả mong đợi:
# X509v3 Subject Alternative Name:
# DNS:example.com, DNS:www.example.com
# Kiểm tra nhanh thời hạn hiệu lực
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
Kiểm tra chéo với curl — chứng chỉ hợp lệ trả về header phản hồi bình thường, không có cảnh báo SSL:
curl -vI https://example.com 2>&1 | grep -E "SSL|subject|issuer|expire"
Không có SSL certificate problem trong kết quả? Bạn đã hoàn thành.
Phòng Ngừa
- Luôn bao gồm cả tên miền gốc lẫn www trong mọi yêu cầu chứng chỉ, kể cả khi bạn redirect cái này sang cái kia. Chỉ mất vài giây để thêm
-d www.example.com; nhưng sẽ mất rất nhiều thời gian để debug sau này. - Thiết lập tự động gia hạn. Kiểm tra trước với
certbot renew --dry-run, sau đó để systemd timer mà Certbot cài tại/etc/systemd/system/snap.certbot.renew.timerxử lý (hoặc thêm cron của riêng bạn). Chứng chỉ Let's Encrypt hết hạn sau 90 ngày — đừng quản lý thủ công. - Kiểm tra chứng chỉ trước khi triển khai bằng
openssl verify -CAfile chain.pem cert.pemhoặc chạy tên miền qua SSL Labs (ssllabs.com/ssltest) để có báo cáo đầy đủ bao gồm cả phạm vi SAN. - Với các dịch vụ nội bộ, hãy dùng một CA nội bộ đúng nghĩa — các công cụ như step-ca hoặc cfssl giúp việc này trở nên đơn giản. Chứng chỉ tự ký ad-hoc ổn cho một máy; nhưng sẽ trở thành ác mộng bảo trì khi dùng chung trong cả nhóm.

