Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pip: cert failed, but curl works

Tags:

python

curl

pip

ssl

We installed the our root cert on the client, and the https connection works for curl.

But if we try to use pip, it fails:

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

like image 817
guettli Avatar asked Oct 15 '13 08:10

guettli


People also ask

Does Pip use curl?

Answer #1: Unfortunately pip does not use the system certs, but curl does.

Which certificate does curl use?

In this case, curl is making a GET request and returns the page source without any error because the server uses Trusted CA Signed SSL Certificates. This means that the server is using a certificate that was signed by a trusted authority.

How do I check my curl certificate?

You can check if the correct root certificate is installed by querying our platform using the following cURL command: curl --verbose https://live.cardeasexml.com/ultradns.php . If the connection is successful and verified by the root certificate, you will see the following entry below.


3 Answers

Unfortunately pip does not use the system certs, but curl does.

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.

If you don't want to use the command line argument, you can set the cert in ~/.pip/pip.conf:

[global] cert = /etc/ssl/certs/Foo_Root_CA.pem 
like image 166
guettli Avatar answered Oct 05 '22 22:10

guettli


My solution is downloading cacert.pem from http://curl.haxx.se/ca/cacert.pem and add the path for cacert.pem to ~/.pip/pip.conf as guettli suggested

[global]
cert = /path/to/cacert.pem
like image 38
user2200896 Avatar answered Oct 06 '22 00:10

user2200896


For me, none of the config-file workarounds worked. I'm using pip 1.5.4 on Ubuntu 14.04

The command posted by @arjenve didn't work on my system either. I get: /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)

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)

Now export that path into PIP_CERT and add it to your .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:

export PIP_CERT=/my/path/to/the/bundle.crt
like image 23
andzep Avatar answered Oct 05 '22 22:10

andzep