Python pip:证书失败,但 curl 有效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19377045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
pip: cert failed, but curl works
提问by guettli
We installed the our root cert on the client, and the https connection works for curl
.
我们在客户端安装了我们的根证书,并且 https 连接适用于curl
.
But if we try to use pip
, it fails:
但是如果我们尝试使用pip
,它会失败:
Could not fetch URL https://installserver:40443/pypi/simple/pep8/:
There was a problem confirming the ssl certificate:
<urlopen error [Errno 1] _ssl.c:499: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed>
The cert is on the client. See:
证书在客户端。看:
(foo_fm_qti)foo_fm_qti@vis-work:~$ curl -v https://installserver:40443/pypi/simple/pep8/
* About to connect() to installserver port 40443 (#0)
* Trying 127.0.0.1... connected
* Connected to installserver (127.0.0.1) port 40443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs/
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS alert, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
* subject: C=DE; ST=Sachsen; L=Chemnitz; O=FOO-COM GmbH; OU=DV; CN=gray.foo-com.lan; [email protected]
* start date: 2013-09-09 10:47:50 GMT
* expire date: 2019-05-24 10:47:50 GMT
* subjectAltName: installserver matched
* issuer: C=DE; ST=Sachsen; L=Chemnitz; O=FOO-COM GmbH; CN=FOO-COM Root CA; [email protected]
* SSL certificate verify ok.
> GET /pypi/simple/pep8/ HTTP/1.1
Version: pip 1.4.1
版本:pip 1.4.1
采纳答案by guettli
Unfortunately pip does not use the system certs, but curl does.
不幸的是 pip 不使用系统证书,但 curl 使用。
I found a solution:
我找到了一个解决方案:
pip --cert /etc/ssl/certs/FOO_Root_CA.pem install pep8
This is not nice (curl and other libraries find the cert without adding a parameter) but works.
这不好(curl 和其他库在不添加参数的情况下找到证书)但有效。
If you don't want to use the command line argument, you can set the cert in ~/.pip/pip.conf:
如果不想使用命令行参数,可以在 ~/.pip/pip.conf 中设置证书:
[global]
cert = /etc/ssl/certs/Foo_Root_CA.pem
回答by user2200896
My solution is downloading cacert.pem
from http://curl.haxx.se/ca/cacert.pemand add the path for cacert.pem
to ~/.pip/pip.conf
as guettli suggested
我的解决办法是下载cacert.pem
从http://curl.haxx.se/ca/cacert.pem和路径添加cacert.pem
到~/.pip/pip.conf
为guettli建议
[global]
cert = /path/to/cacert.pem
回答by arjenve
I use:
我用:
export PIP_CERT=`python -m pip._vendor.requests.certs`
pip install pep8
PIP always validates the certificate of HTTPS connections (and all pypi packages redirect to HTTPS).
PIP 始终验证 HTTPS 连接的证书(并且所有 pypi 包都重定向到 HTTPS)。
The algorithm for determining the CA file is based on 3 steps:
确定 CA 文件的算法基于 3 个步骤:
- Look in a list of default locations for different linux distributions (in my case this file turned out to be out of date, as I am building on a very old linux distribution)
- If available, override the value found in (1) from a value in the pip.conf file, the environment or the command-line (in that order),
- If both (1) and (2) did not result in a value, use a bundled file
- 查看不同 linux 发行版的默认位置列表(在我的例子中,这个文件已经过时了,因为我是在一个非常旧的 linux 发行版上构建的)
- 如果可用,从 pip.conf 文件、环境或命令行(按该顺序)中的值覆盖在 (1) 中找到的值,
- 如果 (1) 和 (2) 都没有产生值,请使用捆绑文件
Note that pip does not use the default SSL directories and files (from ssl.get_default_verify_paths()). But only supports a bundled CA file.
请注意,pip 不使用默认的 SSL 目录和文件(来自 ssl.get_default_verify_paths())。但只支持捆绑的 CA 文件。
PIP does support a command-line action to list the bundled file from step 3 and that is what I use for this answer.
PIP 确实支持命令行操作来列出步骤 3 中的捆绑文件,这就是我用于此答案的内容。
回答by andzep
For me, none of the config-file workarounds worked. I'm using pip 1.5.4on Ubuntu 14.04
对我来说,没有一个配置文件解决方法有效。我在Ubuntu 14.04上使用pip 1.5.4
The command posted by @arjenve didn't work on my system either. I get: /usr/bin/python: No module named _vendor.requests
@arjenve 发布的命令也不适用于我的系统。我得到:/usr/bin/python: No module named _vendor.requests
UPDATE
更新
An even better solution than my first workaround is installing the certificate on the system first (for me on ubuntu this would be)
比我的第一个解决方法更好的解决方案是首先在系统上安装证书(对我来说在 ubuntu 上是这样)
sudo cp ~/my_cert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
The previous automatically updates the bundle file (checking at the bottom of /etc/ssl/certs/ca-certificates.crt
you should now see the same certificate as in my_cert.crt
)
以前的自动更新捆绑文件(检查底部/etc/ssl/certs/ca-certificates.crt
现在应该看到与 中相同的证书my_cert.crt
)
Now export that path into PIP_CERT
and add it to your .bashrc
:
现在将该路径导出PIP_CERT
并添加到您的.bashrc
:
echo export PIP_CERT=/etc/ssl/certs/ca-certificates.crt >> ~/.bashrc
OLDER WORKAROUND
较旧的解决方法
My workaround was to create a bundle file from /etc/ssl/certs/ca-certificates.crt
and my corporate's crt (just concatenated both files). And then export a variable (put that on my .bashrc
) like this:
我的解决方法是从/etc/ssl/certs/ca-certificates.crt
我公司的 crt创建一个包文件(只是连接两个文件)。然后.bashrc
像这样导出一个变量(把它放在 my 上):
export PIP_CERT=/my/path/to/the/bundle.crt