Sửa lỗi NET::ERR_CERT_COMMON_NAME_INVALID — Chứng chỉ SSL Không Khớp Tên Miền

intermediate🔒 SSL/TLS2026-03-21| Chrome, Firefox, Edge, Safari — mọi trình duyệt; ảnh hưởng tất cả hệ điều hành (Windows, macOS, Linux); web server: Nginx, Apache, Caddy; mọi tên miền có cấu hình TLS/SSL

Error Message

NET::ERR_CERT_COMMON_NAME_INVALID — The server's security certificate does not match the website's URL.
#ssl#chứng-chỉ#common-name#san#tên-miền

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.com nhưng bạn đang truy cập www.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ồm example.com gố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.timer xử 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.pem hoặ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.

Related Error Notes