web-dev-qa-db-ja.com

SSLErrorを投げるPython要求

私は、CAS、jspringセキュリティチェック、リダイレクトなどを含む簡単なスクリプトを作成しています。それはすばらしい作品なので、Kenneth Reitzのpythonリクエストを使用したいと思います。しかし、CASはSSLで検証される必要があるので、最初にそのステップを通過する必要があります。 Pythonの要求が何を望んでいるのかわかりませんか?このSSL証明書はどこにありますか。

Traceback (most recent call last):
  File "./test.py", line 24, in <module>
  response = requests.get(url1, headers=headers)
  File "build/bdist.linux-x86_64/Egg/requests/api.py", line 52, in get
  File "build/bdist.linux-x86_64/Egg/requests/api.py", line 40, in request
  File "build/bdist.linux-x86_64/Egg/requests/sessions.py", line 209, in request 
  File "build/bdist.linux-x86_64/Egg/requests/models.py", line 624, in send
  File "build/bdist.linux-x86_64/Egg/requests/models.py", line 300, in _build_response
  File "build/bdist.linux-x86_64/Egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
269
TedBurrows

あなたが抱えている問題は信頼できないSSL証明書が原因です。

前のコメントで述べた@dirkのように、最速修正はverify=Falseを設定することです:

requests.get('https://example.com', verify=False)

これにより証明書が検証されないことに注意してください。 これにより、アプリケーションが中間者攻撃などのセキュリティリスクにさらされます。

もちろん、判断を下してください。コメントで述べたように、このmayはクイック/使い捨てのアプリケーション/スクリプトには受け入れられます、しかし実際には本番用ソフトウェアに行ってはいけません

特定のコンテキストで証明書チェックをスキップすることが受け入れられない場合は、次のオプションを検討してください。verifyパラメータを証明書の.pemファイルのパスである文字列に設定することをお勧めします安全な手段の)。

そのため、バージョン2.0以降、verifyパラメータはそれぞれの意味を持つ次の値を受け入れます。

  • True:ライブラリ自身の信頼できる認証局に対して証明書を検証します(注:Requestから抽出されたRCの信頼データベースであるCertifiライブラリを介して、どのルート証明書要求が使用するかを確認できます: Certifi - Trust Database for Humans ) 。
  • False:証明書の検証完全にをバイパスします。
  • 証明書を検証するために使用するRequestのCA_BUNDLEファイルへのパス。

ソース: リクエスト - SSL証明書検証

同じリンクのcertパラメータも見てください。

352
Rafael Almeida

リクエストから - SSL検証に関するドキュメント

Webブラウザのように、リクエストはHTTPSリクエストのSSL証明書を検証できます。ホストのSSL証明書を確認するには、verify引数を使います。

>>> requests.get('https://kennethreitz.com', verify=True)

SSL証明書を確認したくない場合は、verify=Falseを作成してください。

101
Boud

使用するCAファイルの名前はverifyで渡すことができます。

cafile = 'cacert.pem' # http://curl.haxx.se/ca/cacert.pem
r = requests.get(url, verify=cafile)

verify=Trueを使用する場合、requestsは、サーバー証明書に署名したCAを持たない可能性がある独自のCAセットを使用します。

46
jfs

$ pip install -U requests[security]

  • Python 2.7.6 @ Ubuntu 14.04.4 LTSでテスト済み
  • Python 2.7.5 @ MacOSX 10.9.5(Mavericks)でテスト済み

この質問が開かれたとき(2012-05)、Requestsのバージョンは0.13.1でした。バージョン 2.4.1(2014-09) 利用可能な場合はcertifiパッケージを使用して、 "セキュリティ"追加機能が導入されました。

現在(2016-09)のメインバージョンは2.11.1で、これはうまく動作しますwithoutverify=Falserequests[security]エクストラとともにインストールされている場合は、requests.get(url, verify=False)を使用する必要はありません。

33
alanjds

Aws boto3を使用したときに同じ問題が発生し、SSL証明書の検証が失敗するという問題が発生しました。見直しboto3コードで、REQUESTS_CA_BUNDLEが設定されていないことがわかりました。

from boto3.session import Session
import os

# debian
os.environ['REQUESTS_CA_BUNDLE'] = os.path.join(
    '/etc/ssl/certs/',
    'ca-certificates.crt')
# centos
#   'ca-bundle.crt')

Aws-cliの場合、~/.bashrcにREQUESTS_CA_BUNDLEを設定することでこの問題は解決されるでしょう(私のaws-cliはそれなしでも動作するのでテストされていません)。

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt # ca-bundle.crt
export REQUESTS_CA_BUNDLE
25
Yong

requestsに依存していて検証パスを変更できないライブラリがある場合(pyvmomiの場合のように)、リクエストにバンドルされているcacert.pemを見つけてそこにCAを追加する必要があります。 cacert.pemの場所を見つける一般的な方法は次のとおりです。

C:\>python -c "import requests; print requests.certs.where()"
c:\Python27\lib\site-packages\requests-2.8.1-py2.7.Egg\requests\cacert.pem

Linux

#  (py2.7.5,requests 2.7.0, verify not enforced)
root@Host:~/# python -c "import requests; print requests.certs.where()"
/usr/lib/python2.7/dist-packages/certifi/cacert.pem

#  (py2.7.10, verify enforced)
root@Host:~/# python -c "import requests; print requests.certs.where()"
/usr/local/lib/python2.7/dist-packages/requests/cacert.pem

ところで。 @ requests-devs、自分のcacertをrequestにバンドルすることは、本当に厄介です...特に、システムcaストアを最初に使用していないようで、これがどこにも文書化されていないという事実。

更新

ライブラリを使用していてca-bundleの場所を制御できない状況では、ca-bundleの場所をホスト全体のca-bundleに明示的に設定することもできます。

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)"
15
tintin

私はgspreadを使用して同じ問題に直面します、そして、これらのコマンドは私のために働きます:

Sudo pip uninstall -y certifi
Sudo pip install certifi==2015.04.28
13
user941581

警告を削除したい場合は、以下のコードを使用してください。

import urllib3

urllib3.disable_warnings()

verify=Falseまたはpostメソッドを使用したrequest.get

11
AniketGole

私は同様の問題を解決するための具体的なアプローチを見つけました。この考えは、 system に格納され、他のSSLベースのアプリケーションで使用されるcacertファイルを指すことです。

Debian(他のディストリビューションでも同じかどうかわからない)では、証明書ファイル(.pem)は/etc/ssl/certs/に格納されています。だから、これは私のために働くコードです:

import requests
verify='/etc/ssl/certs/cacert.org.pem'
response = requests.get('https://lists.cacert.org', verify=verify)

どのpemファイルが選択したのかを推測するために、URLを参照して、どの認証局(CA)が証明書を生成したのかを確認します。

編集:あなたがコードを編集することができない場合(あなたが第三のアプリを実行しているので)あなたはpem証明書を直接/usr/local/lib/python2.7/dist-packages/requests/cacert.pemに加えることを試みることができます(例えばそれをファイルの終わりまでコピーする)。

10
chk

証明書を気にしないのであればverify=Falseを使うだけです。

import requests

url = "Write your url here"

returnResponse = requests.get(url, verify=False)
9
yogesh prasad

何時間ものデバッグの後、私はこれをうまく動かすことができるのは次のパッケージを使うことだけでした。

requests[security]==2.7.0  # not 2.18.1
cryptography==1.9  # not 2.0

OpenSSL 1.0.2g 1 Mar 2016を使う

これらのパッケージがなければverify=Falseは動作しませんでした。

これが誰かに役立つことを願っています。

7
michael

私は同じ問題に遭遇しました。中間証明書が私のサーバーにインストールされていないことがわかりました(以下のように証明書の末尾に追加してください)。

https://www.digicert.com/ssl-support/pem-ssl-creation.htm

Ca-certificatesパッケージがインストールされていることを確認してください。

Sudo apt-get install ca-certificates

時間を更新すると、これも解決する可能性があります。

Sudo apt-get install ntpdate
Sudo ntpdate -u ntp.ubuntu.com

自己署名証明書を使用している場合は、おそらくそれを手動でシステムに追加する必要があります。

5

私はこの問題をHOURSのために戦った。

リクエストを更新しようとしました。それから私はcertifiを更新しました。私はcertifi.where()に確認を向けました(コードはとにかくデフォルトでこれをします)。何もうまくいきませんでした。

最後に私は自分のバージョンのpythonをpython 2.7.11に更新しました。私は証明書が検証されるという点でいくつかの非互換性を持っていたPython 2.7.5にいました。 Pythonを(そして他のいくつかの依存関係も)アップデートしたら、それは動き始めました。

3
ajon

V2.6.2からv2.12.4(ATOW)に存在する、このエラーの原因となっている要求モジュールには現在問題があります: https://github.com/kennethreitz/requests/issues/2573

この問題を回避するには、次の行を追加します。requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

2
Peter

リクエストの呼び出しがコードのどこかに埋め込まれていて、サーバー証明書をインストールしたくない場合は、 デバッグ目的のみ の場合は、リクエストをmonkeypatchすることができます。

import requests.api
import warnings


def requestspatch(method, url, **kwargs):
    kwargs['verify'] = False
    return _origcall(method, url, **kwargs)

_origcall = requests.api.request
requests.api.request = requestspatch
warnings.warn('Patched requests: SSL verification disabled!')

本番では絶対に使用しないでください。

2
xmedeko

パーティーに遅すぎると思いますが、私のような仲間の放浪者のための修正を貼り付けたいと思いました。そのため、Python 3.7.xでは以下がうまくいきました。

端末に次のように入力してください。

pip install --upgrade certifi      # hold your breath..

あなたのスクリプト/リクエストをもう一度実行して、それが機能するかどうかを確かめてください(まだ修正されないと確信しています!)。うまくいかなかった場合は、ターミナルで直接以下のコマンドを実行してみてください。

open /Applications/Python\ 3.6/Install\ Certificates.command  # please replace 3.6 here with your suitable python version
1
d-coder

@ Rafael Almeidaが述べたように、あなたが抱えている問題は信頼できないSSL証明書が原因です。私の場合、SSL証明書は私のサーバーによって信頼されていませんでした。セキュリティを犠牲にすることなくこれを回避するために、I 証明書をダウンロードして 、そして単に.crtファイルをダブルクリックしてからInstall Certificate ...をクリックすることによってサーバーにインストールしました。

1
Michael

私の場合、その理由はかなり簡単でした。

私は、SSL検証が数日前まではうまくいっていたことを知っていましたが、実際には別のマシンで作業していました。

私の次のステップは、検証が機能していたマシンとそうでないマシンの間で証明書の内容とサイズを比較することでした。

これはすぐに「間違って」動作しているマシンの証明書が良くないと判断するようになりました、そして一度「良い」証明書に置き換えれば、すべてが大丈夫でした。

0

要求が別のパッケージから呼び出されている場合は、オプションを追加することは現実的ではありません。その場合、証明書をcacertバンドルに追加するのが簡単な方法です。ルート証明書をダウンロードした "StartCom Class 1プライマリ中間サーバCA"をStartComClass1.pemに追加する必要がありました。私のvirtualenvがcaldavと命名されているので、証明書を追加しました:

cat StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/pip/_vendor/requests/cacert.pem
cat temp/StartComClass1.pem >> .virtualenvs/caldav/lib/python2.7/site-packages/requests/cacert.pem

それらの1つで十分かもしれません、私はチェックしませんでした

0
rhoerbe

私は似たような、あるいは同じ認証確認問題を抱えていました。私はOpenSSLのバージョンが1.0.2未満であることを読みましたが、その要求は強力な証明書を検証するのに苦労することがあります( here を参照)。 CentOS 7は1.0.1eを使っているようですが、問題があるようです。

CentOSでこの問題を回避する方法がわからないので、もっと弱い1024bit CA証明書を許可することにしました。

import certifi # This should be already installed as a dependency of 'requests'
requests.get("https://example.com", verify=certifi.old_where())
0
Tim Ludwinski

私はPython 3.4.0から3.4.6にアップグレードしなければなりませんでした

pyenv virtualenv 3.4.6 myvenv
pyenv activate myvenv
pip install -r requirements.txt
0
Paul