这类问题我又碰上了一次。为提升握手速度把证书换成 ECDSA,Chrome 和手机都正常,日志里一部分蜘蛛的 TLS 握手直接失败,返回 handshake failure,抓取量掉了三成。
真正麻烦的地方在于,几个原因的现象几乎一样。旧爬虫的 TLS 栈只认 RSA 证书,ECDSA 直接协商不上;服务器只配了 EC 证书,没有回退的 RSA 证书;TLS 版本限制在 1.2 以上,旧客户端被一起拒掉。
动手时先分别用两种曲线测试握手
openssl s_client -connect www.example.com:443 -cipher 'ECDHE-RSA-AES128-GCM-SHA256' </dev/null 2>&1 | grep -i 'cipher is'
同时部署 RSA 与 EC 两张证书
ssl_certificate /etc/nginx/ssl/fullchain_rsa.pem; ssl_certificate /etc/nginx/ssl/fullchain_ec.pem;
保留 TLS 1.2 兼容旧客户端
ssl_protocols TLSv1.2 TLSv1.3;
同样的操作我在测试机上先走了一遍,线上只做验证过的部分。
这台环境是别人交接的,不少默认值被动过,只能一项项核。
恢复的判定其实很直接。双证书配置后握手失败率回到基线,抓取量在四天内恢复,首字节时间没有明显变差。
容易忽略的是,性能优化不要一刀切,证书算法这种底层项先看日志里的失败率再决定。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
