Poetry 安装 SSL 验证失败问题探究

今天安装 python 的包管理工具 poetry 遇到了如下的 SSL 验证失败问题,研究了一下原因并解决了安装问题,记录并分享之。

# 安装 poetry
curl -sSL https://install.python-poetry.org | python3 -

# 遇到错误如下,这里省略绝大部分内容,突出错误
...
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)
...

解决 poetry 安装问题

之前在执行某些脚本时也遇到过这个原因,比较暴力的解决方式就是不验证,因为我此时的目标是安装 poetry,我简单看了下安装脚本内容,定位到是下载 https://pypi.org/pypi/poetry/json 这个 json 文件时使用了 urllib 库出现的 SSL 问题,比较暴力的方式就是将 ssl 全局关闭验证,改造命令如下:

# 1. 下载脚本
# 2. 脚本内容最前面加上设置验证的 python 代码
# 3. 执行脚本安装 poetry
curl -sSL https://install.python-poetry.org | sed '1s;^;import ssl\nssl._create_default_https_context = ssl._create_unverified_context\n;' | python3 -

🔖 思考

暴力的解决思路就是关闭验证,这里是 python,其它语言或者工具相应的思路关闭 SSL 验证即可!

分析原因

看脚本内容是试图创建一个安全的 HTTPS 连接,但在验证服务器 SSL 证书时失败了。这可能是由多种原因导致的,包括:

  1. 服务器的 SSL 证书过期:如果服务器的 SSL 证书已过期,就无法完成验证,会导致这个错误。
  2. 证书颁发机构不被信任:如果 SSL 证书是由一个不在你的操作系统信任的证书颁发机构发出的,那么在尝试创建安全连接时就会出现这个错误。
  3. 连接的服务器不是证书中列出的服务器:如果你试图连接到的服务器与 SSL 证书中列出的服务器不匹配(例如,证书是为 “www.example.com” 发出的,但你正在尝试连接到 “www.somethingelse.com”),那么就会出现这个错误。
  4. 系统时间或日期错误:如果你的系统日期或时间设置错误,可能会导致 SSL 证书验证失败。
  5. 中间人攻击:虽然不太可能,但理论上这个错误也可能由网络攻击或劫持引发(如中间人攻击)。

一项项分析。

证书过期

理论上讲,https://pypi.org的证书不太可能过期,但还是看一下吧,🤣

echo | openssl s_client -servername pypi.org -connect pypi.org:443 2>/dev/null | openssl x509 -noout -dates

结果是

notBefore=Apr 29 19:53:38 2023 GMT
notAfter=May 30 19:53:37 2024 GMT

看时间是今年 4 月~明年 5 月,所以不是这个原因。

证书机构不被信任

先查看证书机构:

echo | openssl s_client -servername pypi.org -connect pypi.org:443 2>/dev/null | openssl x509 -noout -issuer

得到结果是:

issuer=C = BE, O = GlobalSign nv-sa, CN = GlobalSign Atlas R3 DV TLS CA 2023 Q2

我使用的是 macOS,所以去钥匙串访问 app 中查找,发现找不到同名的证书:

服务器不一致

使用下面命令查看证书和服务器是否一致:

echo | openssl s_client -servername pypi.org -connect pypi.org:443 2>/dev/null | openssl x509 -noout -subject

得到结果:

subject=CN = pypi.org

这个也没问题。

🐛 补充

我一开始以为是代理的问题,但是开关代理结果都一样不是代理导致的 SSL 验证异常。

写在最后

SSL 验证失败,非必须验证的情况下,可以使用本文提到的关闭验证的方式(比如能保证链接是公开公正的官方网站),毕竟我们的目标是其它的而不是从根本上解决验证问题(目标感很重要),希望本文对您有所帮助!