证书不包含这个域名:ERR_CERT_COMMON_NAME_INVALID 的几种成因
浏览器提示证书不适用于该网站,或者拿到了另一个站点的证书。
这个错误的含义很窄:服务器发来的证书是有效的,只是上面没有你正在访问的这个域名。链是好的、没过期、CA 也受信任 —— 唯独名字不对。
同一个报错有好几种完全不同的成因,其中一种(拿到了同一台服务器上另一个站点的证书)光看错误信息看不出来。下面按从最常见到最少见的顺序排。
先看清服务器到底发了哪张证书
这一步能直接分出「证书签少了」和「拿错了证书」两大类:
# 带 SNI(正常访问的样子)
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName
# 不带 SNI(看这台机器的默认站点是谁)
openssl s_client -connect example.com:443 -noservername </dev/null 2>/dev/null \
| openssl x509 -noout -subject-noservername 不能省。OpenSSL 1.1.1 及以上会自动按 -connect 的主机名填 SNI,所以不显式关掉的话,两条命令测的是同一件事。
对照结果:
| 两条命令的结果 | 指向的成因 |
|---|---|
| 一样,而且证书上没有你的域名 | 证书签少了名字 → 看下面第 1、2 节 |
| 不一样 | SNI 路由没配对,你的请求落到了默认站点 → 第 3 节 |
| 证书上有你的域名,但仍然报错 | 拿到的证书不是你以为的那张 → 第 4 节(CDN / 负载均衡) |
1. 泛域名不覆盖主域名
证书里只有 *.example.com,而访客访问的是 example.com。这是最常见的一种,因为它看起来完全不像证书问题 —— 所有子域名都正常,只有主域名坏。
详细解释和修法见泛域名为什么不覆盖主域名。
2. 少签了 www,或者少签了新加的域名
证书是 SAN 证书,能签多少个名字取决于签发时写了多少个。常见的漏签:
- 只签了
example.com,没签www.example.com(或者反过来)。 - 后来上线了新域名 / 换了品牌域名,DNS 指过来了,证书没重签。
- 多个域名指向同一个站点(主域名、短域名、旧域名),证书只签了其中一个。
修法是重新签一张包含全部域名的证书。一张证书装得下多个名字,不需要一个域名一张。
别指望用 301 跳转绕过去:TLS 握手在 HTTP 之前完成,握手时证书就已经被拒绝了,跳转规则根本执行不到。
3. SNI 没配对,你拿到了别人的证书
一台服务器上跑多个 HTTPS 站点时,服务器靠握手里的 SNI 字段决定发哪张证书。如果没有任何一个站点的域名配置与请求的域名匹配,服务器不会报错 —— 它会发出默认站点的证书。于是访客看到的是一个完全无关的域名。
上面第二条命令返回的主题,就是这台机器的默认站点。如果那是另一个项目的域名,问题就在这里。逐项检查:
server_name写全了吗。 nginx 里请求域名必须命中某个server块的server_name;命不中就落到default_server。- 新站点的配置真的被加载了吗。
nginx -T打印出的是实际生效的完整配置,比ls sites-enabled/可靠 —— 忘了做软链、或者软链断了,都会让配置看起来存在而实际没加载。 - 监听的地址对不对。
listen 443 ssl写在了另一个 IP 上、或者 IPv6 只配了一半(访客走 AAAA 记录进来,落到没配的那条监听上),都会绕开你以为会命中的那个块。 - 客户端是不是不发 SNI。 极老的客户端(Windows XP 上的 IE、Java 6)不发 SNI,一定会拿到默认站点的证书。这种情况没法在服务器端修,只能给那个站点单独一个 IP。
4. CDN、负载均衡、云上的证书绑定
接了 CDN 或负载均衡之后,访客握手的对象是边缘节点,不是你的源站。这时候有两张独立的证书,两处都可能出问题:
- 边缘证书没绑,或者绑错了域名。 加了新域名却只在 DNS 上指了过去,忘了在 CDN 控制台给这个域名绑证书 —— 边缘会拿默认证书应付,症状和上面的 SNI 问题一样。
- 源站证书的域名和回源 Host 不一致。 回源时如果开了「校验源站证书」,源站证书里必须有回源使用的那个 Host 名字,而不是访客看到的域名。这两个经常不是同一个。
5. 用 IP 或内网名访问
直接访问 https://1.2.3.4 或者 https://内网机器名 时报这个错,是正常的 —— 公开 CA 不给 IP 和内网名签发证书,证书里当然不会有它们。这不是故障,是用错了地址:用域名访问就好。
确实需要用 IP 校验源站时,用 --resolve 指定 IP 但仍以域名握手:
curl -v --resolve example.com:443:1.2.3.4 https://example.com/6. 只有 CN,没有 SAN
很老的证书、或者自己用 openssl req 手工签的证书,可能只在 CN 字段里写了域名而没有 SAN 扩展。现在的浏览器完全忽略 CN(Chrome 自 58 版起),所以这种证书对所有域名都报不匹配。
重新签发时必须带上 SAN 扩展。任何公开 CA 现在签出来的证书都一定有 SAN,这种情况基本只出现在自签证书上。
常见问题
检测一下你自己的域名
免登录,一次真实的 TLS 握手,直接给出结论:还有多少天到期、证书链是否完整、是否包含这个域名。
需要一张新证书?本站提供基于 Let's Encrypt 的免费签发,支持泛域名。
了解免费证书其他排错指南
- 证书过期了怎么办浏览器拦下访问,提示证书已过期或连接不是私密连接。
- 证书快到期了:先分清是没续期,还是续了没部署证书还没过期,但剩余天数已经不多了。
- 证书还没到生效时间:多半是时钟不对证书的生效时间还没到,被判定为无效。
- 证书透明度日志里出现了没见过的证书监控期间,域名下出现了不是本站签发的新证书。
- 无法连接:证书检测连不上服务器时的排查顺序检测连不上服务器,没能拿到证书。
- 「您的连接不是私密连接」:先找错误代码,再决定修哪里浏览器弹出红色警告拦下访问,但不知道属于哪一种证书问题。
- 关闭 TLS 1.0 / 1.1,只留 1.2 和 1.3服务器还在使用 TLS 1.0 或 1.1 协商连接。
- 电脑打得开、手机 App 报证书错误:证书链缺少中间证书电脑浏览器打得开,手机 App、curl 或 Java 客户端却报证书错误。
- OCSP stapling:开了能快一点,不开也不算故障没有启用 OCSP stapling,首次握手会稍慢一些。
- 证书被吊销,或者链验证没通过证书被吊销,或者链验证没有通过。
- 自签名证书:什么时候没问题,什么时候必须换证书是自己签给自己的,浏览器不信任。
- 证书链追溯不到受信任的根:新根交叉签名与私有 CA浏览器打得开,curl、旧安卓或 Java 客户端却说找不到颁发者证书。
- RSA 密钥长度不足:为什么现在才被提醒证书的 RSA 密钥长度低于 2048 位。
- 泛域名证书为什么不覆盖主域名子域名都正常,直接访问主域名却报证书错误。
Last updated on