pip 总是无法通过 ssl 验证

Posted

技术标签:

【中文标题】pip 总是无法通过 ssl 验证【英文标题】:pip always fails ssl verification 【发布时间】:2018-08-25 18:14:58 【问题描述】:

即使我使用pip install dedupepip install --trusted-host pypi.python.org dedupe,Pip 总是失败 ssl

无论如何输出总是一样的:

收集重复数据删除

重试(重试(总数=4,连接=无,读取=无, redirect=None, status=None)) 连接中断后 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书 验证失败 (_ssl.c:777)'),)': /simple/dedupe/ 正在重试...

跳过

找不到满足重复数据删除要求的版本(来自版本:)没有找到重复数据删除的匹配分布

所以我卸载了 anaconda 并重新安装了它。一样的。

您认为问题在于我的 _ssl.c 文件(我不知道它在哪里)一定是损坏的还是什么?如果我告诉它绕过 ssl 验证,为什么 pip 需要引用它?

【问题讨论】:

看起来类似于***.com/questions/41691327/…,但我在windows机器上 【参考方案1】:

可能与PyPI的2018 changedomains有关。 请确保您的防火墙/代理允许访问/来自:

pypi.org files.pythonhosted.org

所以你可以尝试一下:

$ python -m pip install --trusted-host files.pythonhosted.org --trusted-host pypi.org --trusted-host pypi.python.org [--proxy ...] [--用户]<packagename>

请参阅$ pip help install 了解--user 选项说明(如果在 virtualenv 中则省略)。--trusted-host 选项实际上并没有绕过 SSL/TLS,但允许在(且仅当)它没有有效(或任何)HTTPS 时将主机标记为受信任。与 PiPY 无关,因为 pypi.org(以前的 pypi.python.org)确实使用 HTTPS,并且前面有 CDN,无论连接如何,它始终强制执行 TLSv1.2 握手要求pip 客户端选项.. 但是,如果您有自己的 pypi.org 本地镜像,并且只能访问 HTTP,那么 --trusted-host 可能会很方便。哦,如果您使用代理,请务必同时指定:--proxy [user:passwd@]proxyserver:port 一些公司代理甚至可以在运行中使用 HTTPS 连接证书replace。如果您的系统时钟不同步,也可能会破坏 SSL 验证过程。

如果防火墙/代理/时钟没有问题,请检查 pip 的 SSL 握手中使用的 SSL 证书。事实上,你可以得到一个当前的cacert.pem(来自curl 的Mozilla 的CA 包)并使用pip 选项--cert 进行尝试:

$ pip --cert ~/cacert.pem install --user <packagename> 其中--cert 参数是PEM 格式的备用CA 包的系统路径。 (关于 --user 选项,请参见下文)。 或者,可以创建自定义配置 ~/.pip/pip.conf 并将选项指向有效的系统证书(或您的 cacert.pem)作为解决方法,例如:[global]证书 = /etc/pki/tls/external-roots/ca_bundle.pem (或其他 pem 文件)

甚至可以将 pip 中的原始 cacert.pem 手动替换为您可信赖的 CA 包(例如,如果您的 pip 非常旧)。如果出现证书问题,较旧的 pip 版本知道在 pip/_vendor/requests/cacert.pem 和 /etc/ssl/certs/ca-certificates.crt/etc/pki/tls/certs/ca-bundle.crt 等系统存储之间回退,但在最近的 pip 中不再是这种情况,因为它似乎完全依赖pip/_vendor/certifi/cacert.pem

基本上,pip 包使用requests,它使用urllib3,其中包括验证 SSL 证书;并且所有这些都在 pip 中发货(供应),以及提供 TLS 验证所需的当前 CA 包(cacert.pem 文件)的certifi 包(自 pip 9.0.2 起也包括在内)。 Requests 本身在内部使用 urllib3 和 certifi,而在 9.0.2 之前,pip 使用的是来自 requests 或系统的 cacert.pem。这意味着实际更新 pip 可能有助于修复 CERTIFICATE_VERIFY_FAILED 错误,尤其是在很久以前部署操作系统和 pip 的情况下:

OP 使用 anaconda,所以他们可以尝试:$ conda update pip - 因为如果 conda 和 pip 在同一环境中一起使用,issues can arise。如果没有可用的 pip 版本更新,他们可以尝试:$ conda config --add channels conda-forge; conda update pip 或者,可以单独使用conda 直接安装/管理python 包:它是一个完全独立于pip 的工具,但在包和venv 管理方面提供了类似的功能。它的包不是来自 PyPI,而是来自anaconda's own repositories。 问题是,如果您将两者混合并在pip 之后运行 conda,则前者可以覆盖和破坏通过 pip 安装的包(及其依赖项),并使其全部无法使用。因此,建议只使用一个或另一个,或者,如果必须,只在 conda 之后使用 pip(并且在 pip 之后不使用 conda),并且只能在孤立的 conda 中使用环境。

在没有 conda 的普通 Linux Python 安装上: 如果您使用操作系统发行版提供的 pip 版本,请使用供应商提供的升级来进行系统范围的 pip 更新:$ sudo apt-get install python-pip 或:$ sudo yum install python27-pip 某些更新可能不容易获得,因为发行版通常落后于 PyPI。在这种情况下,可以在您的用户级别(就在您的 $HOME 目录中)或在 virtualenv 中升级 pip,例如:$ python -m pip install --user --trusted-host files.pythonhosted.org --trusted-host pypi.org --trusted-host pypi.python.org --upgrade pip (如果在 virtualenv 中,则省略 --user--user 开关将只为当前用户(在你家 ~/.local/lib/ 中)而不是为整个操作系统升级 pip,这是避免干扰系统 python 包的好习惯。它在最近的 Ubuntu/Fedora 版本中分发的 pip 中默认启用。如果您不使用此选项并且碰巧覆盖了操作系统级别的系统 pip,请注意如何解决 ImportError。 或者(也在用户级别)您可以尝试:$ curl -LO https://bootstrap.pypa.io/get-pip.py && python get-pip.py --user PyPA script 包含一个从 pip._vendor.certifi 中提取 .pem SSL 包的包装器。

否则,如果仍然不行,请尝试使用 -vvv 选项运行 pip 以向输出添加详细信息,并检查现在是否存在由 tlsv1 alert protocol version 引起的另一个 SSLError

【讨论】:

我建议在您的 .bash_profile 或 .zshrc 中创建此别名以使其更容易:alias pp="python -m pip install --trusted-host files.pythonhosted.org --trusted-host pypi.org --trusted-host pypi.python.org " @henry 嘿,是的,确实如此,或者在 ~/.bashrc 然后source 它.. 虽然,尝试更新pip 看看它是否修复可能是个好主意证书问题的根本原因。或者,可以获取当前的 Mozilla CA bundle file 并将其与 pip 选项 --cert 一起使用(答案已更新)。 到目前为止,我在这篇文章中建议的任何方法都没有成功。即使我将 pypi.org、pypi.python.org 和 files.pythonhosted.org 指定为受信任的主机,我也会收到错误消息“无法获取 URL pypi.org/simple/pip:确认 ssl 证书时出现问题:HTTPSConnectionPool(host='pypi .org',端口 = 443)”。如果我已将这些主机指定为受信任,为什么它会尝试确认 ssl 证书?【参考方案2】:

上面的错误或者类似的错误是由于虚拟机(VM)没有时间同步引起的,我的guest Ubuntu VM是几天前的。

我运行这个命令是为了让 VM 获得正确的网络时间:

sudo timedatectl set-ntp on

这使得 Ubuntu 来宾操作系统获得网络时间。 (可能要提供网络时间源……我用了这篇文章:Digital Ocean - How to set time on Ubuntu)

检查时间是否正确:

timedatectl

重新运行失败的 pip 命令。

【讨论】:

【参考方案3】:

我的方式是简化@Alex C 的回答:

python -m pip install --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --trusted-host pypi.org --upgrade pip

【讨论】:

无论我指定这些受信任的主机,我的安装尝试总是导致“确认 ssl 证书时出现问题:HTTPSConnectionPool(host='pypi.org', port=443)”。因此,无论如何,似乎总是尝试 SSL 确认。【参考方案4】:

这对我有用,试试这个:

pip install --trusted-host=pypi.org --trusted-host=files.pythonhosted.org --user name of whatever I'm installing

【讨论】:

谢谢,它工作得非常好。为此浪费了一个小时。非常感谢。

以上是关于pip 总是无法通过 ssl 验证的主要内容,如果未能解决你的问题,请参考以下文章

django 无法在 docker-compose 中连接 mysql

Traefik:无法使用摘要身份验证登录服务

php:关于微信一直无法通过php token验证, ehcho echo $echoStr; 总是提示不对的问题.

使用Python进行验证码识别案例无法验证通过,SOS

用python安装pip总是报错

Traefik无法通过docker-compose连接到服务器。