部署证书后提示“证书名称与输入不匹配”:Safari 报错的三层排查
证书刚部署完,命令行里测着都正常,iPhone 上却打不开——Safari 弹「此连接非私人连接」,详情里写着:“api.example.com”证书名称与输入不匹配。先别删证书重装:它不是“证书坏了”,而是“证书上的名字和访问的地址对不上”。像快递面单写着 A 栋、你却在 B 栋等。按三层查:先对名字(证书名单),再看应答(实发哪张),最后看客户端(为什么有的报、有的不报)。

一、先看懂这句提示:它在说“两个名字对不上”
“证书名称与输入不匹配”是 Safari(macOS / iOS)中文界面的说法(英文:Certificate name does not match input);同类问题,Chrome 报 NET::ERR_CERT_COMMON_NAME_INVALID,Firefox 报 SSL_ERROR_BAD_CERT_DOMAIN。文案不同,指向同一件事——浏览器在 TLS 握手时做“身份校验”:把你请求的主机名,和证书里的名字列表对照,对不上就拦。另两类提示别混:不受信任查证书链/根、已过期查时间——名称不匹配,只查名字。
二、浏览器认的“名单”在哪:SAN,不是 CN
现代客户端只认证书里的 subjectAltName(SAN)扩展——CommonName(CN)已退役:Apple 对受信任证书的要求写明,服务器证书必须把域名写进 SAN,CN 不再被信任;RFC 9525 也明确服务身份不能用 Common Name 表达。记两个细节:SAN 可同时含 DNS: 与 IP: 条目,用 IP 访问要有对应 IP: 条目;通配符只能作最左侧标签、只匹配一层——*.example.com 不匹配 example.com,也不匹配 a.b.example.com。
三、第一层:对名字——读回证书名单
先别改配置,把证书文件里的名单读出来:
openssl x509 -noout -subject -ext subjectAltName -in fullchain.pem
输出里 subject 一行、SAN 一行,对着访问地址核对:访问名在不在名单?www 和裸域都在吗?用 IP 访问的有没有 IP: 条目?
四、第二层:看应答——服务器实际发的是哪张证书
名字改对了还报错?先确认“发出来的”是谁——用 -servername 模拟 SNI,读回实发证书:
echo | openssl s_client -connect 127.0.0.1:443 -servername api.example.com 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName
-servername 不能省:省略它,你问到的可能是默认站点证书——本机实测,用不存在的名字连本机 443,回来的 subject 是另一个域名。SNI 不命中的常见原因:server_name 写错或没写、证书绑到了别的 server 块。快速核对:
nginx -T 2>/dev/null | grep -nE 'server_name|ssl_certificate'
ss -ltnp | grep ':443'
五、第三层:看客户端——为什么“有的报、有的不报”
两个经典错觉。其一:s_client 默认不校验证书——不带 -verify_hostname 时“连接成功”不代表名字正确;本机实测,同一连接加上它立即返回 Verify return code: 62 (Hostname mismatch)。其二:curl -k 或关掉校验的客户端同样“看着正常”。想看真实报错:
curl -v https://api.example.com/
# 示例:访问 api.example.com,证书只覆盖 www.example.com
# * subject: CN = www.example.com
# * subjectAltName does not match api.example.com
# * SSL: no alternative certificate subject name matches target host name 'api.example.com'
同一根因、不同文案:Safari“证书名称与输入不匹配”、Chrome/Edge NET::ERR_CERT_COMMON_NAME_INVALID、Firefox SSL_ERROR_BAD_CERT_DOMAIN、curl 与 s_client 各有自己的说法——都指同一件事,修复在服务端或访问地址,不用挨个设备改。
六、四类典型场景对照表
| 现象 | 常见根因 | 一条命令验证 | 修复方向 |
|---|---|---|---|
| 浏览器直接报名称不匹配 | SAN 名单不含访问名(只签了主域/www) | x509 -ext subjectAltName 对照地址栏 | 重签补齐名字再部署 |
| 打开 A 站却提示 B 站的名字 | SNI 未命中,默认站点抢先应答 | s_client -servername 对比 subject | 核对 server_name 与证书绑定 |
| 命令行“正常”,浏览器和手机却报错 | 工具默认不校验(s_client、curl -k) | 加 -verify_hostname 复测 | 以带校验的客户端为准 |
| 用 IP 或内网名访问报错 | 名单没有 IP: 条目或那个内网名 | 看 SAN 是否含 IP: 与访问名 | 补条目重签,或改用覆盖的域名 |
七、修复:把缺的名字补进 SAN
情形 A——名单缺名字:重签时把会用来访问的名字全部列上(关键在 -addext 的 SAN 列表):
openssl req -new -newkey rsa:2048 -nodes \
-keyout api.example.com.key -out api.example.com.csr \
-subj "/CN=api.example.com" \
-addext "subjectAltName=DNS:api.example.com,DNS:*.api.example.com"
CSR 交给 CA(或自签)签发,部署后用第四节的命令读回验证。情形 B——名字没问题,是发错了:把 ssl_certificate / ssl_certificate_key 指到正确文件、写进正确 server 块;nginx -t 通过再 reload。顺序要记牢:先改对,再重载。自签证书还要单独处理“不受信任”,别混着改。
八、验收清单:跨端过一遍
- SAN 输出与全部访问名逐一对上;
- s_client -servername 逐个域名复核,subject 为同一张预期证书;
- curl -v 不再出现 does not match;
- s_client 加 -verify_hostname,返回 code 0;
- iPhone / Mac Safari 实机打开,不再出现该提示;
- 同机其它站点抽查,无互相“串名”。
九、参考:签发与管理方式
名字能否对上,从签发那一步就决定了。常见的签发与管理方式有三类:
- 官方路线:Let's Encrypt 官方文档(ACME 标准与策略说明);
- 开源客户端:acme.sh(纯 shell 实现的 ACME 客户端);
- 平台化方式:CertbotX(把证书签发、部署与监控集中管理的平台)。
三类侧重不同,排查链路是同一套:名字、应答、客户端。文中命令的官方资料:OpenSSL s_client 手册、Nginx server_names 文档、Apple 受信任证书要求。
名字对不上从来不是玄学,就是一次对账:证书的名单、服务器实际发的东西、客户端看到的东西,三样对上,浏览器自然放行。
更多推荐


所有评论(0)