web-dev-qa-db-ja.com

pip:証明書は失敗しましたが、カールは機能します

クライアントにルート証明書をインストールしました。https接続はcurlで機能します。

ただし、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>

証明書はクライアント上にあります。見る:

(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

バージョン:pip 1.4.1

30
guettli

残念ながら、pipはシステム証明書を使用しませんが、curlは使用します。

私は解決策を見つけました:

pip --cert /etc/ssl/certs/FOO_Root_CA.pem install pep8

これはニースではありませんが(カールや他のライブラリはパラメータを追加せずに証明書を見つけます)、動作します。

コマンドライン引数を使用したくない場合は、〜/ .pip/pip.confで証明書を設定できます。

[global]
cert = /etc/ssl/certs/Foo_Root_CA.pem
36
guettli

私の解決策は、cacert.pemhttp://curl.haxx.se/ca/cacert.pem からダウンロードし、cacert.pemのパスをguettliとして~/.pip/pip.confに追加することです。提案された

[global]
cert = /path/to/cacert.pem
21
user2200896

私が使う:

export PIP_CERT=`python -m pip._vendor.requests.certs`

pip install pep8

PIPは常にHTTPS接続の証明書を検証します(すべてのpypiパッケージがHTTPSにリダイレクトします)。

CAファイルを決定するアルゴリズムは、3つのステップに基づいています。

  1. さまざまなLinuxディストリビューションのデフォルトの場所のリストを確認します(私の場合、このファイルは非常に古いLinuxディストリビューションでビルドしているため、古くなっています
  2. 可能な場合、(1)にある値をpip.confファイル、環境、またはコマンドラインの値から(この順序で)オーバーライドします。
  3. (1)と(2)の両方が値にならなかった場合、バンドルされたファイルを使用します

pipはデフォルトのSSLディレクトリとファイル(ssl.get_default_verify_paths()から)を使用しないことに注意してください。ただし、バンドルされたCAファイルのみをサポートします。

PIPは、ステップ3でバンドルされたファイルをリストするコマンドラインアクションをサポートしており、それがこの回答に使用するものです。

4
arjenve

私にとって、構成ファイルの回避策はどれも機能しませんでした。 pip 1.5.4 on buntu 14.04を使用しています

@arjenveによって投稿されたコマンドも、私のシステムでは機能しませんでした。取得:/usr/bin/python: No module named _vendor.requests

[〜#〜] update [〜#〜]

私の最初の回避策よりもさらに良い解決策は、最初にシステムに証明書をインストールすることです(ubuntuの私にとってはこれです)

Sudo cp ~/my_cert.crt /usr/local/share/ca-certificates/
Sudo update-ca-certificates

以前のバージョンでは、バンドルファイルが自動的に更新されます(/etc/ssl/certs/ca-certificates.crtの下部で確認すると、my_cert.crtと同じ証明書が表示されるはずです)

次に、そのパスをPIP_CERTにエクスポートし、.bashrcに追加します。

echo export PIP_CERT=/etc/ssl/certs/ca-certificates.crt >> ~/.bashrc

以前の回避策

私の回避策は、/etc/ssl/certs/ca-certificates.crtと私の会社のcrt(両方のファイルを連結しただけ)からバンドルファイルを作成することでした。そして、次のように変数をエクスポートします(私の.bashrcに置きます):

export PIP_CERT=/my/path/to/the/bundle.crt
3
andzep