ホームページ  >  記事  >  バックエンド開発  >  PythonのHTTPプロキシについて詳しく解説

PythonのHTTPプロキシについて詳しく解説

高洛峰
高洛峰オリジナル
2017-03-21 10:04:452087ブラウズ

0x00 はじめに

多くの面で非常に幅広い用途を持つ HTTP プロキシについては、誰もがよく知っているはずです。 HTTP プロキシは、フォワード プロキシとリバース プロキシに分けられ、後者は通常、ユーザーにファイアウォールの背後にあるサービスへのアクセスを提供するため、または Nginx や HAProxy などの目的で使用されます。この記事では、フォワード プロキシについて説明します。

HTTP プロキシの最も一般的な用途は、ネットワーク共有、ネットワークの高速化、ネットワーク制限の突破などです。さらに、HTTP プロキシは、Web アプリケーションのデバッグ や、Android/IOS APP で呼び出される Web API の監視と分析にも一般的に使用されており、現在、よく知られているソフトウェアには、Fiddler、Charles、Burp Suite、mitmproxy などがあります。 HTTP プロキシを使用すると、サーバーを変更せずにリクエスト/レスポンスのコンテンツを変更したり、Web アプリケーションに機能を追加したり、アプリケーションの動作を変更したりすることもできます。

0x01 HTTP プロキシとは

HTTP プロキシは本質的に Web アプリケーションであり、他の通常の Web アプリケーションと基本的に変わりません。 HTTP プロキシはリクエストを受信すると、Header の Host フィールドのホスト名と Get/POST リクエスト アドレスに基づいてターゲット ホストを総合的に判断し、新しい HTTP リクエストを確立してリクエスト データを転送します。受信した応答データをクライアント側に転送します。

リクエスト アドレスが絶対アドレスの場合、HTTP プロキシはアドレスのホストを使用します。それ以外の場合は、ヘッダーの HOST フィールドが使用されます。ネットワーク環境が次のとおりであると仮定して、簡単なテストを実行します。

  • 192.168.1.2 Web サーバー

  • 192.168.1.3 HTTP プロキシ サーバー

Telnet を使用してテストします

$ telnet 192.168.1.3
GET / HTTP/1.0
HOST: 192.168.1.2

2 つの連続したキャリッジリターンがあることに注意してください最後に必須です。これは HTTP プロトコルの要件です。完了すると、http://192.168.1.2/ のページコンテンツを受信できるようになります。 GET リクエストに絶対アドレスを含めてみましょう

$ telnet 192.168.1.3
GET http://httpbin.org/ip HTTP/1.0
HOST: 192.168.1.2

HOST も 192.168.1.2 に設定されていますが、実行結果は http://httpbin.org/ip ページのコンテンツを返すことに注意してください。パブリックIPアドレス情報。

上記のテストプロセスからわかるように、元のリクエストがプロキシサーバーに送信される限り、HTTP プロキシはそれほど複雑なものではありません。少数のホストが HTTP プロキシを必要とするシナリオで HTTP プロキシを設定できない場合、最も簡単な方法は、ターゲット ホスト ドメイン名の IP をプロキシ サーバーにポイントすることです。これは、hosts ファイルを変更することで実現できます。 。

0x02 Pythonプログラム内でHTTPプロキシを設定する

urllib2/urllib プロキシ設定

urllib2は非常に強力な機能を備えたPythonの標準ライブラリですが、使い方が少し面倒です。 Python 3 では、urllib2 は保持されなくなり、urllib モジュールに移動されました。 urllib2 では、ProxyHandler を使用してプロキシ サーバーを設定します。

proxy_handler = urllib2.ProxyHandler({'http': '121.193.143.249:80'})
opener = urllib2.build_opener(proxy_handler)
r = opener.open('http://httpbin.org/ip')
print(r.read())

install_opener を使用して、構成済みのオープナーをグローバル環境にインストールすることもできます。これにより、すべての urllib2.urlopen が自動的にプロキシを使用するようになります。

urllib2.install_opener(opener)
r = urllib2.urlopen('http://httpbin.org/ip')
print(r.read())
Python 3 では、urllib を使用します。

proxy_handler = urllib.request.ProxyHandler({'http': 'http://121.193.143.249:80/'})
opener = urllib.request.build_opener(proxy_handler)
r = opener.open('http://httpbin.org/ip')
print(r.read())
requests proxy settings

requests は、現在最高の HTTP ライブラリの 1 つであり、http リクエストを構築するときに私が最もよく使用するライブラリでもあります。その API 設計は非常にユーザーフレンドリーで使いやすいです。リクエスト用のプロキシの設定は非常に簡単です。{'http': 'x.x.x.x:8080', 'https': 'x.x.x.x:8080'} の形式でパラメータを設定するだけです。プロキシ。このうち http と https は互いに独立しています。

In [5]: requests.get('http://httpbin.org/ip', proxies={'http': '121.193.143.249:80'}).json()
Out[5]: {'origin': '121.193.143.249'}
{'http': 'x.x.x.x:8080', 'https': 'x.x.x.x:8080'} 的参数即可。其中http和https相互独立。
s = requests.session()
s.proxies = {'http': '121.193.143.249:80'}
print(s.get('http://httpbin.org/ip').json())

可以直接设置session的proxies属性,省去每次请求都要带上proxies参数的麻烦。

$ http_proxy=121.193.143.249:80 python -c 'import requests; print(requests.get("http://httpbin.org/ip").json())'
{u'origin': u'121.193.143.249'}

$ http_proxy=121.193.143.249:80 curl httpbin.org/ip
{
  "origin": "121.193.143.249"
}

0x03 HTTP_PROXY / HTTPS_PROXY 环境变量

urllib2 和 Requests 库都能识别 HTTP_PROXY 和 HTTPS_PROXY 环境变量,一旦检测到这些环境变量就会自动设置使用代理。这在用HTTP代理进行调试的时候非常有用,因为不用修改代码,可以随意根据环境变量来调整代理服务器的ip地址和端口。*nix中的大部分软件也都支持HTTP_PROXY环境变量识别,比如curl、wget、axel、aria2c等。

In [245]: os.environ['http_proxy'] = '121.193.143.249:80'
In [246]: requests.get("http://httpbin.org/ip").json()
Out[246]: {u'origin': u'121.193.143.249'}
In [249]: os.environ['http_proxy'] = ''
In [250]: requests.get("http://httpbin.org/ip").json()
Out[250]: {u'origin': u'x.x.x.x'}

在IPython交互环境中,可能经常需要临时性地调试HTTP请求,可以简单通过设置 os.environ['http_proxy']セッション

attribute

。これにより、リクエストごとにプロキシ パラメータを持ち込む手間が省けます。

# test.py
def response(flow):
    flow.response.headers["BOOM"] = "boom!boom!boom!"

0x03 HTTP_PROXY / HTTPS_PROXY 環境変数

🎜🎜urllib2 および Requests ライブラリは両方とも HTTP_PROXY および HTTPS_PROXY 環境変数を認識します、これらの環境変数が検出されると、プロキシを使用して自動的に設定されます。これは、コードを変更せずに環境変数に従ってプロキシ サーバーの IP アドレスとポートを調整できるため、HTTP プロキシを使用してデバッグする場合に非常に便利です。 *nix のほとんどのソフトウェアは、curl、wget、axel、aria2c などの HTTP_PROXY 環境変数認識もサポートしています。 🎜
$ http_proxy=localhost:8080 curl -I 'httpbin.org/get'
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 03 Nov 2016 09:02:04 GMT
Content-Type: application/json
Content-Length: 186
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
BOOM: boom!boom!boom!
...
🎜 IPython インタラクティブ環境では、HTTP リクエストを一時的にデバッグする必要がある場合があります。これは、os.environ['http_proxy'] を設定して HTTP プロキシを追加/キャンセルするだけで実現できます。 🎜rrreee🎜0x04 MITM-Proxy🎜🎜MITM は中間者攻撃に由来しており、一般的にクライアントとクライアントの間のネットワーク内のデータを傍受、監視、改ざんする中間者攻撃を指します。サーバ。 🎜

mitmproxy是一款Python语言开发的开源中间人代理神器,支持SSL,支持透明代理、反向代理,支持流量录制回放,支持自定义脚本等。功能上同Windows中的Fiddler有些类似,但mitmproxy是一款console程序,没有GUI界面,不过用起来还算方便。使用mitmproxy可以很方便的过滤、拦截、修改任意经过代理的HTTP请求/响应数据包,甚至可以利用它的scripting API,编写脚本达到自动拦截修改HTTP数据的目的。

# test.py
def response(flow):
    flow.response.headers["BOOM"] = "boom!boom!boom!"

上面的脚本会在所有经过代理的Http响应包头里面加上一个名为BOOM的header。用mitmproxy -s 'test.py'命令启动mitmproxy,curl验证结果发现的确多了一个BOOM头。

$ http_proxy=localhost:8080 curl -I 'httpbin.org/get'
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 03 Nov 2016 09:02:04 GMT
Content-Type: application/json
Content-Length: 186
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
BOOM: boom!boom!boom!
...

显然mitmproxy脚本能做的事情远不止这些,结合Python强大的功能,可以衍生出很多应用途径。除此之外,mitmproxy还提供了强大的API,在这些API的基础上,完全可以自己定制一个实现了特殊功能的专属代理服务器。

经过性能测试,发现mitmproxy的效率并不是特别高。如果只是用于调试目的那还好,但如果要用到生产环境,有大量并发请求通过代理的时候,性能还是稍微差点。我用twisted实现了一个简单的proxy,用于给公司内部网站增加功能、改善用户体验,以后有机会再和大家分享。

以上がPythonのHTTPプロキシについて詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。