事情本身不复杂,线索都在日志里。站点启用了中文域名,证书按中文形式申请,浏览器访问正常,蜘蛛抓取时一直报证书域名不匹配,日志里出现的是 xn-- 开头的 punycode 形式。

第一反应是「部分 CA 不签发 IDN 的通用名,只写进 SAN 且格式不同」,验证下来不成立。

真正麻烦的地方在于,几个原因的现象几乎一样。证书 SAN 里只有中文形式,punycode 形式没有覆盖。还有一种是服务器 SNI 按 punycode 匹配,找不到对应证书。

少数情况下是站点同时绑定了中文域和英文域,证书只覆盖了一个。

第一件事是查证书 SAN 里到底写了哪些名字

echo | openssl s_client -connect www.example.com:443 -servername xn--fiqs8s.example 2>/dev/null | openssl x509 -noout -text | grep -A1 'Subject Alternative Name'

接着用 punycode 形式重新申请并加入 SAN

acme.sh --issue -d xn--fiqs8s.example -d www.xn--fiqs8s.example --webroot /var/www/html

然后确认 Nginx 的 server_name 同时包含两种形式

nginx -T | grep -n 'server_name'

剩下的就是用 punycode 直接请求验证握手

curl -sI --resolve xn--fiqs8s.example:443:1.2.3.4 https://xn--fiqs8s.example/ | head -1

怎么算真的好了,看的是同一批现象。punycode 形式的请求握手成功且证书链完整,蜘蛛抓取错误里不再出现域名不匹配。

IDN 域名在 DNS 和 TLS 里都以 punycode 存在,证书申请时按这个形式提交,别只写中文。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189