2016-04-23 30 views
0

mitmproxyとPython 3を使用してHTTPS接続をデバッグしようとしています。プロキシがローカルで実行されていて、PythonにHTTPS接続用に使用するよう伝えます。 Pythonはmitmproxyによって作成された自己署名証明書を受け入れなければなりません。すべてがうまくいけば、mitmproxyのコンソールはデコードされた要求/応答のペアを表示します。HTTPS通信をmitmproxyに渡すときに問題が発生しました

私はPython 3とrequestsで欲しいことをすることができますが、標準urllibを使ってやる必要があります。私は失敗しています。ここでは、コードは:

#!/usr/bin/env python3 

import urllib.request 
import ssl 

proxy = urllib.request.ProxyHandler({'https': 'localhost:8080'}) 
opener = urllib.request.build_opener(proxy) 
urllib.request.install_opener(opener) 

ssl_ctx = ssl.create_default_context() 
ssl_ctx.check_hostname = False 
ssl_ctx.verify_mode = ssl.CERT_NONE 
#ssl_ctx = ssl._create_unverified_context() 

req = urllib.request.Request('https://github.com') 

with urllib.request.urlopen(req) as res: 
#with urllib.request.urlopen(req, context=ssl_ctx) as res: 
    print(res.read().decode('utf8')) 

上記のコードが実行されると、私は ssl.SSLErrorを得る:[SSL:CERTIFICATE_VERIFY_FAILED]:プロキシがあることを意味する(645 _ssl.c) エラー、認証が失敗したことを確認しますその証明書は検証されません。これはまさに私がこの時点で起こりそうなことです。

ssl_context(いずれかの方法で作成)を使用するためにコメントアウトされた行を使用すると、要求したページの内容が表示されますが、プロキシコンソールにはデコードされた要求情報は表示されません。これは、ssl_contextを使用してプロキシを完全に迂回しているかのようです。

誰かが私を助けて、私が間違っていることを教えてもらえますか?

EDIT:念のため、私は8081にプロキシポートを変更し、そして今ssl_ctx変数を使用してコードないは(予想通り)「接続が拒否」、およびssl_ctx作品を使用してコードで失敗これはプロキシがまったく使われていないという私の前提を主張しています。

+0

私は、デフォルトでは不可能だと思います。「現在、urllib.requestは、プロキシを介したhttpsの場所の取得をサポートしていません。しかし、これはレシピ[6]に示されているようにurllib.requestを拡張することで有効にできます。 https://docs.python.org/3/howto/urllib2.html#id13にそうです。それがもたらすレシピは、Python 3のPython 3バージョンへのコメントリンクの1つです。これは 'TypeError:do_open()が失敗し、urllibコードのどこかに予期しないキーワード引数' context 'があります。私はもうそれを働かせようとはしません。 – wujek

答えて

1

お問い合わせいただきありがとうございました。ありがとうございました。私は、ドキュメンテーションが、プロキシを介してHTTPSを取得することがサポートされていないと主張する理由がわかりません。

明示的にSSLコンテキストを渡す代わりに、ProxyHandlerに加えてHTTPSHandlerを作成してインストールしました。 - 私は必要なものである。このオープナーがインストールされている

import urllib.request 
import ssl 

ssl_ctx = ssl.create_default_context() 
ssl_ctx.check_hostname = False 
ssl_ctx.verify_mode = ssl.CERT_NONE 

ssl_handler = urllib.request.HTTPSHandler(context=ssl_ctx) 
proxy_handler = urllib.request.ProxyHandler({'https': 'localhost:8080'}) 

opener = urllib.request.build_opener(ssl_handler, proxy_handler) 
urllib.request.install_opener(opener) 


if __name__ == '__main__': 
    req = urllib.request.Request('https://...') 

    with urllib.request.urlopen(req) as res: 
     print(res.read().decode('utf8')) 

たら、それはでも、サードパーティ製のライブラリで、urllibはを使用して、すべての要求のデフォルトとして使われています:これは(Pythonの3.5 + mitmproxy)私のために働きました。

コメントアウトされた行がうまくいかなかった理由はわかりません。おそらくurlopenにコンテキストを渡すと、カスタムオープナーをオーバーライドする新しいオープナーがインストールされます。

関連する問題