证书里的 CN 早就不够用了:SAN 到底在管什么

很多人排查 TLS 报错时还在看证书的 CN 字段,但现代浏览器早已只认 SAN。这篇解释两者的关系、为什么会踩坑,以及签发和配置证书时该注意什么。

本文目录
证书里的 CN 早就不够用了:SAN 到底在管什么

排查证书报错时,不少人习惯先看证书“颁发给谁”,也就是 Subject 里的 CN(Common Name)。看到 CN 写的是 example.com,就以为访问 api.example.com 报域名不匹配是别的原因。其实方向就错了:现代客户端验证域名时,基本不看 CN,只看 SAN。

CN 和 SAN 各是什么

CN 是证书 Subject 字段里的一个条目,历史上用来写证书绑定的域名。一个证书只有一个 CN,天然只能放一个名字。

SAN(Subject Alternative Name)是一个扩展字段,里面可以放一组名字:多个域名、通配符,甚至 IP 地址。浏览器和 TLS 库在校验“证书是否匹配当前域名”时,按现行规范只检查 SAN 列表;只有在 SAN 完全缺失时,一些老实现才会回退去看 CN。Chrome 多年前就强制要求 SAN,新证书没有 SAN 会直接报 ERR_CERT_COMMON_NAME_INVALID——这个报错名字本身就挺误导人,问题其实出在 SAN,不是 CN。

证书里的 CN 早就不够用了:SAN 到底在管什么 illustration 1
证书里的 CN 早就不够用了:SAN 到底在管什么 illustration 1查看原图

所以你可以把 CN 理解成证书上的“曾用名备注”,真正起决定作用的是 SAN 那份名单。

什么时候会撞上这个坑

  • 签发时漏域名。 证书只给 example.com 签,没带上 www.example.com。CN 看着没问题,SAN 里却少一个名字,访问 www 前缀的域名立刻报不匹配。这是最常见的情况,查证书时用 openssl x509 -in cert.pem -noout -ext subjectAltName 看一眼名单就清楚了。
  • 通配符的边界。 *.example.com 只匹配一层子域名,api.example.com 行,a.b.example.com 不行,裸的 example.com 也不行。如果 SAN 里只有通配符,裸域名的访问就会失败——这不是通配符坏了,是名单里少写了一个名字。
  • 内部系统用 IP 直连。 用 IP 访问 HTTPS 时,域名/IP 必须作为 IP 类型的 SAN 写进证书,写在 CN 里不算数。内网自签证书经常在这一点上翻车。

在 CertbotX 中实践

证书里的 CN 早就不够用了:SAN 到底在管什么 illustration 2
证书里的 CN 早就不够用了:SAN 到底在管什么 illustration 2查看原图

签发环节把域名名单列全,比事后排查省事得多。CertbotX 走 ACME 自动签发时,证书请求会按你配置的域名生成对应的 SAN 列表;如果 DNS 在其他服务商手里,可以用 DNS-01 CNAME 委托完成验证,不影响 SAN 里放哪些名字。签发后到期前会自动重新签发,证书内容保持一致;部署到 Agent、EdgeOne 或 CDN 的过程有记录可查,审计时能确认每个环境上跑的是哪张证书、覆盖哪些名字。

值得记住的一句话:看证书绑了哪些域名,别盯着 CN,直接读 SAN。名单之外的名字,客户端一个都不会放行。

---

← 返回资讯中心