【发布时间】:2020-11-02 09:25:35
【问题描述】:
我正在使用上游到远程代理运行 mitmproxy。
mitmweb --set mode=upstream:http://proxyIp:proxyPort --set ssl_insecure=true
申请流程为:
- 在 Python 中发出 HTTP 请求并使用 mitmproxy 服务器作为
proxies参数 - 拦截 mitmproxy 中的调用,并上游到另一个代理。
- 返回结果。
HTTP 请求是向受 CloudFlare 保护的外部 API(我无权访问它)发出的。
headers = {
'User-Agent': 'PostmanRuntime/7.26.7',
'Accept': 'application/json'
}
r = requests.get("https://api.website.com/",
headers=headers,
verify=False,
proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})
运行此请求将导致来自https://api.website.com/ 的 403 响应。如果我跳过 mitmproxy 部分并直接从 Python 连接到最终代理,结果是一样的。然而,我尝试使用Fiddler 作为网关并且效果很好(它肯定会在后台修改请求)。
<span>Error</span><span>1020</span>
如果我使用curl 运行相同的请求,结果会很好(200 OK)
curl -x 127.0.0.1:8080 -k 'https://api.website.com/' -H 'user-agent: PostmanRuntime/7.26.7' -H 'accept: application/json'
这两个请求看起来相同,但 Python 请求返回 403。
我在 Python 配置中遗漏了什么吗?设置一些协议或标头?
注意:
我尝试通过直接连接到终端代理(跳过 mitmproxy)来运行 curl,但请求也失败并返回 403 响应。
curl -x proxyIp:proxyPort -k 'https://api.website.com/' -H 'user-agent: PostmanRuntime/7.26.7'
然后我尝试使用curl-openssl/bin/curl,它成功了,但我不得不添加--tlsv1.3。
/usr/local/opt/curl-openssl/bin/curl --tlsv1.3 -x proxyIp:proxyPort -k 'https://api.website.com/' -H 'user-agent: PostmanRuntime/7.26.7'
【问题讨论】:
-
如果相同的请求在 Fiddler 中有效,但在 Python 中无效,这表明 CloudFlare 执行客户端指纹(例如基于 TLS 握手和更多数据),因此拒绝某些请求。我建议查看 Wireshark 中的请求以了解 TLS 握手的差异。
标签: python python-3.x curl openssl mitmproxy