私は、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
あなたが抱えている問題は信頼できない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
:証明書の検証完全にをバイパスします。ソース: リクエスト - SSL証明書検証
同じリンクのcert
パラメータも見てください。
リクエストから - SSL検証に関するドキュメント :
Webブラウザのように、リクエストはHTTPSリクエストのSSL証明書を検証できます。ホストのSSL証明書を確認するには、verify引数を使います。
>>> requests.get('https://kennethreitz.com', verify=True)
SSL証明書を確認したくない場合は、verify=False
を作成してください。
使用するCAファイルの名前はverify
で渡すことができます。
cafile = 'cacert.pem' # http://curl.haxx.se/ca/cacert.pem
r = requests.get(url, verify=cafile)
verify=True
を使用する場合、requests
は、サーバー証明書に署名したCAを持たない可能性がある独自のCAセットを使用します。
$ pip install -U requests[security]
この質問が開かれたとき(2012-05)、Requestsのバージョンは0.13.1でした。バージョン 2.4.1(2014-09) 利用可能な場合はcertifi
パッケージを使用して、 "セキュリティ"追加機能が導入されました。
現在(2016-09)のメインバージョンは2.11.1で、これはうまく動作しますwithoutverify=False
。 requests[security]
エクストラとともにインストールされている場合は、requests.get(url, verify=False)
を使用する必要はありません。
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
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';)"
私はgspreadを使用して同じ問題に直面します、そして、これらのコマンドは私のために働きます:
Sudo pip uninstall -y certifi
Sudo pip install certifi==2015.04.28
警告を削除したい場合は、以下のコードを使用してください。
import urllib3
urllib3.disable_warnings()
verify=False
またはpost
メソッドを使用したrequest.get
私は同様の問題を解決するための具体的なアプローチを見つけました。この考えは、 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
に加えることを試みることができます(例えばそれをファイルの終わりまでコピーする)。
証明書を気にしないのであればverify=False
を使うだけです。
import requests
url = "Write your url here"
returnResponse = requests.get(url, verify=False)
何時間ものデバッグの後、私はこれをうまく動かすことができるのは次のパッケージを使うことだけでした。
requests[security]==2.7.0 # not 2.18.1
cryptography==1.9 # not 2.0
OpenSSL 1.0.2g 1 Mar 2016
を使う
これらのパッケージがなければverify=False
は動作しませんでした。
これが誰かに役立つことを願っています。
私は同じ問題に遭遇しました。中間証明書が私のサーバーにインストールされていないことがわかりました(以下のように証明書の末尾に追加してください)。
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
自己署名証明書を使用している場合は、おそらくそれを手動でシステムに追加する必要があります。
私はこの問題をHOURSのために戦った。
リクエストを更新しようとしました。それから私はcertifiを更新しました。私はcertifi.where()に確認を向けました(コードはとにかくデフォルトでこれをします)。何もうまくいきませんでした。
最後に私は自分のバージョンのpythonをpython 2.7.11に更新しました。私は証明書が検証されるという点でいくつかの非互換性を持っていたPython 2.7.5にいました。 Pythonを(そして他のいくつかの依存関係も)アップデートしたら、それは動き始めました。
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'
リクエストの呼び出しがコードのどこかに埋め込まれていて、サーバー証明書をインストールしたくない場合は、 デバッグ目的のみ の場合は、リクエストを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!')
本番では絶対に使用しないでください。
パーティーに遅すぎると思いますが、私のような仲間の放浪者のための修正を貼り付けたいと思いました。そのため、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
@ Rafael Almeidaが述べたように、あなたが抱えている問題は信頼できないSSL証明書が原因です。私の場合、SSL証明書は私のサーバーによって信頼されていませんでした。セキュリティを犠牲にすることなくこれを回避するために、I 証明書をダウンロードして 、そして単に.crtファイルをダブルクリックしてからInstall Certificate ...をクリックすることによってサーバーにインストールしました。
私の場合、その理由はかなり簡単でした。
私は、SSL検証が数日前まではうまくいっていたことを知っていましたが、実際には別のマシンで作業していました。
私の次のステップは、検証が機能していたマシンとそうでないマシンの間で証明書の内容とサイズを比較することでした。
これはすぐに「間違って」動作しているマシンの証明書が良くないと判断するようになりました、そして一度「良い」証明書に置き換えれば、すべてが大丈夫でした。
要求が別のパッケージから呼び出されている場合は、オプションを追加することは現実的ではありません。その場合、証明書を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つで十分かもしれません、私はチェックしませんでした
私は似たような、あるいは同じ認証確認問題を抱えていました。私は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())
私はPython 3.4.0から3.4.6にアップグレードしなければなりませんでした
pyenv virtualenv 3.4.6 myvenv
pyenv activate myvenv
pip install -r requirements.txt