0x00 Vorwort
Jeder sollte mit dem HTTP-Proxy bestens vertraut sein, der in vielerlei Hinsicht weit verbreitet ist. HTTP-Proxys werden in Forward-Proxys und Reverse-Proxys unterteilt. Letztere werden im Allgemeinen verwendet, um Benutzern Zugriff auf Dienste hinter der Firewall zu ermöglichen oder für den Lastausgleich. In diesem Artikel werden Forward-Proxys behandelt.
Die häufigsten Verwendungszwecke von HTTP-Proxys sind die gemeinsame Nutzung von Netzwerken, die Netzwerkbeschleunigung und das Durchbrechen von Netzwerkgrenzen usw. Darüber hinaus werden HTTP-Proxys auch häufig zum Debuggen von Webanwendungen, zur Überwachung und Analyse von Web-APIs verwendet, die in Android/IOS-APPs aufgerufen werden. Zu den bekannten Softwareprogrammen gehören derzeit Fiddler, Charles, Burp Suite und Mitmproxy. HTTP-Proxy kann auch verwendet werden, um Anforderungs-/Antwortinhalte zu ändern, zusätzliche Funktionen zu Webanwendungen hinzuzufügen oder das Anwendungsverhalten zu ändern, ohne den Server zu ändern.
0x01 Was ist HTTP-Proxy?
HTTP-Proxy ist im Wesentlichen eine Webanwendung und unterscheidet sich nicht grundlegend von anderen gewöhnlichen Webanwendungen. Nach Erhalt der Anfrage ermittelt der HTTP-Proxy umfassend den Zielhost anhand des Hostnamens im Host-Feld im Header und der Get/POST-Anfrageadresse, erstellt eine neue HTTP-Anfrage, leitet die Anfragedaten weiter und leitet die empfangenen Antwortdaten weiter an den Kunden.
Wenn die Anfrageadresse eine absolute Adresse ist, verwendet der HTTP-Proxy den Host in der Adresse, andernfalls wird das HOST-Feld im Header verwendet. Führen Sie einen einfachen Test durch, vorausgesetzt, die Netzwerkumgebung ist wie folgt:
192.168.1.2 Web服务器 192.168.1.3 HTTP代理服务器
Verwenden Sie Telnet zum Testen
$ telnet 192.168.1.3 GET / HTTP/1.0 HOST: 192.168.1.2
Beachten Sie, dass am Ende zwei aufeinanderfolgende Wagenrückläufe erforderlich sind, was eine Anforderung des HTTP-Protokolls ist. Nach Abschluss können Sie den Seiteninhalt von http://www.php.cn/ erhalten. Nehmen wir einige Anpassungen vor. Beachten Sie, dass der HOST ebenfalls auf 192.168.1.2 eingestellt ist Das laufende Ergebnis wird zurückgegeben. Der Inhalt der Seite http://www.php.cn/ ist die öffentliche IP-Adressinformation.
Wie aus dem obigen Testprozess ersichtlich ist, ist der HTTP-Proxy keine sehr komplizierte Sache, solange die ursprüngliche Anfrage an den Proxyserver gesendet wird. Wenn für eine kleine Anzahl von Hosts, die einen HTTP-Proxy benötigen, kein HTTP-Proxy festgelegt werden kann, besteht die einfachste Möglichkeit darin, die IP des Zielhostdomänennamens auf den Proxyserver zu verweisen. Dies kann durch Ändern der Hosts-Datei erreicht werden.
$ telnet 192.168.1.3 GET http://www.php.cn/ HTTP/1.0 HOST: 192.168.1.2
0x02 HTTP-Proxy im Python-Programm festlegen
urllib2/urllib-Proxy-Einstellung
ist die Python-Standardbibliothek . Es ist sehr leistungsstark, aber etwas umständlich zu bedienen. In Python 3 wird urllib2 nicht mehr beibehalten und in das Modul urllib verschoben. In urllib2 wird ProxyHandler zum Einrichten des Proxyservers verwendet.
urllib2
Sie können install_opener auch verwenden, um den konfigurierten Opener in der globalen Umgebung zu installieren, sodass alle urllib2.urlopen automatisch den Proxy verwenden.
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())
Verwenden Sie in Python 3 urllib.
urllib2.install_opener(opener) r = urllib2.urlopen('http://httpbin.org/ip') print(r.read())
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())
Sie können das Proxy-Attribut der Sitzung direkt festlegen, wodurch die Mühe entfällt, bei jeder Anfrage Proxy-Parameter mitzubringen.
In [5]: requests.get('http://httpbin.org/ip', proxies={'http': '121.193.143.249:80'}).json() Out[5]: {'origin': '121.193.143.249'}
s = requests.session() s.proxies = {'http': '121.193.143.249:80'} print(s.get('http://httpbin.org/ip').json())
In der interaktiven IPython-Umgebung müssen Sie möglicherweise häufig vorübergehend HTTP-Anfragen debuggen. Sie können dies einfach erhöhen, indem Sie os.environ['http_proxy festlegen '] / HTTP-Proxy abbrechen, um zu erreichen.
$ 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" }
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'}
上面的脚本会在所有经过代理的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中文网!