现场是这样的。阿里云 ALB 开启双向认证,浏览器能正常访问,可一部分通过 curl 和 SDK 调用的客户端一直收到 495 状态码,ALB 日志里写 client certificate verify failed。
中间走过弯路,把「curl 调用时没带 --cert 和 --key 参数」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。客户端用的是自签证书,ALB 里配置的 CA 证书没有包含它;客户端证书链里缺中间证书,服务端构建不出完整链;后端的 nginx 也开了客户端校验,两次校验用的 CA 不是同一套。
先用 curl 带证书复现一次
curl -v --cert client.crt --key client.key https://api.lu0.cn/health
再往下看 ALB 访问日志里的具体错误码
grep -i 'client certificate' /var/log/nginx/access.log | tail
接着确认客户端证书链是否完整
openssl verify -CAfile ca.pem client.crt
末了把 CA 链补进 ALB 的信任列表后重试
openssl s_client -connect api.lu0.cn:443 -cert client.crt -key client.key </dev/null
怎么算真的好了,看的是同一批现象。curl 带证书访问返回 200,ALB 日志里不再出现 495,SDK 调用恢复正常,未带证书的请求仍然被拒。
补一句。双向认证的 CA 列表要包含整条链,只放根证书时中途换发会导致不认;后端不要重复做一次校验,两层 CA 不一致时很难排查。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
