先把当时的情况摆出来。换完证书浏览器能正常打开,可 openssl 握手一直报 unable to get local issuer certificate,必应那边的抓取成功率从九成八掉到四成,日志里全是 TLS 握手失败。

真正麻烦的地方在于,几个原因的现象几乎一样。Nginx 只部署了站点证书,中间证书没有拼进 fullchain.pem。少数情况下是证书商给的压缩包里带着中间证书,部署时只拷了域名 crt 那一个文件。

少数情况下是老证书还没到期,客户端走会话复用不报错,新连接的蜘蛛才会撞上。不容易想到的是,OCSP 装订地址还指向旧证书的 responder,握手时多了一次失败。

第一件事是看服务端实际下发的证书链

openssl s_client -connect www.lu0.cn:443 -servername www.lu0.cn -showcerts </dev/null

然后把中间证书拼到站点证书后面

cat domain.crt intermediate.crt > fullchain.pem

接着重载后复核链验证结果

openssl s_client -connect www.lu0.cn:443 2>/dev/null | grep 'Verify return code'

再跑一次抓取诊断确认握手正常

怎么算真的好了,看的是同一批现象。链校验返回码从 21 变成 0,三天内必应抓取成功率回到九成五以上,日志里的握手失败不再出现。

提醒一点。有些爬虫不支持 OCSP 装订,链完整比装订重要,先把根到站的路径走通再谈附加项。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189