我試圖調試HTTPS連接使用mitmproxy
和Python 3.這個想法如下:代理運行本地,並告訴Python使用它的HTTPS連接; Python必須接受由mitmproxy
創建的自簽名證書才能正常工作,如果一切順利,mitmproxy
的控制檯會向我顯示已解碼的請求/響應對。麻煩通過mitmproxy HTTPS通信
我能夠用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]證書驗證失敗(_ssl.c:645) 錯誤,這意味着代理是使用,但其證書不驗證。這正是我期望在這一點上發生的事情。
當我使用註釋掉的行來使用ssl_context
(以任何方式創建)時,我得到我請求的頁面內容,但代理控制檯從不顯示解碼的請求信息,它保持空白。這就好像使用ssl_context
完全避開了代理。
難道有人請幫助我,告訴我我做錯了什麼?
編輯:只是爲了確保,我改變了代理端口8081,而現在使用ssl_ctx
變量的代碼不失敗,「拒絕連接」(如預期),並使用ssl_ctx
作品代碼好 - 這表明我假設代理根本沒有被使用。
所以我猜這是不可能的默認情況下,注意'目前urllib.request不支持通過代理獲取https位置。但是,這可以通過擴展urllib.request來啓用,如配方[6]所示。'在https://docs.python.org/3/howto/urllib2.html#id13中是這樣說的。它導致的配方是針對Python 2,其中一個註釋鏈接到Python 3版本,該版本與'TypeError:do_open()失敗,在urllib代碼深處有一個意外的關鍵字參數'context'。我不會試圖讓它繼續工作,沒有意義。 – wujek