调用第三方接口时抛出 SSLCertVerificationError,信息是 certificate verify failed: unable to get local issuer certificate。第一反应往往是在请求里加 verify=False,代码确实跑通了,但线上这么做等于关掉了整条链路的安全校验。

先看证书链是否完整

openssl s_client -connect 目标域名:443 \
  -servername 目标域名 

正常应该看到服务器证书和至少一级中间证书。只出现一行 s: 说明中间证书没有下发,浏览器有时会靠缓存补上,Python 的校验链却会直接失败。

不要用关闭校验来解决问题

临时排查可以用 verify=False 确认是不是证书导致,但请求库会持续告警,生产环境应该指定可信 CA:

import certifi, requests
resp = requests.get(url, timeout=10,
    verify=certifi.where())

公司内网的自签证书,把自己的 CA 文件路径传给 verify,而不是关闭验证。

Windows 和容器里最常见的坑

  • certifi 版本过旧:python -m pip install -U certifi
  • 公司代理替换了证书:需要导入代理的根证书
  • Docker 镜像缺少 CA:apt-get install -y ca-certificates

还有一种情况是证书本身没问题,而是系统时间偏差过大,导致校验时提示证书尚未生效或已经过期。容器里没有同步时间源时会遇到,装个 ntp 对齐时间即可。

证书链修好后,同样的请求不加任何 verify 参数就能通过,才算真正修复。排查过程中记住一点:报错发生在哪一步,就查哪一步的证书,不要因为某一次请求失败就全站关掉校验。

作者 9823189

发表回复