【问题标题】:pip always fails ssl verificationpip 总是无法通过 ssl 验证
【发布时间】: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 需要引用它?

【问题讨论】:

标签: ssl pip


【解决方案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}

    【讨论】:

    • 谢谢,它工作得非常好。为此浪费了一个小时。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 2014-07-14
    相关资源
    最近更新 更多