Préface 0x00
Tout le monde devrait être très familier avec le proxy HTTP, qui est largement utilisé dans de nombreux aspects. Les proxys HTTP sont divisés en proxys directs et proxys inverses. Ces derniers sont généralement utilisés pour fournir aux utilisateurs un accès aux services derrière le pare-feu ou pour l'équilibrage de charge. Les proxys typiques sont Nginx, HAProxy, etc. Cet article traite des proxys directs.
Les utilisations les plus courantes du proxy HTTP concernent le partage réseau, l'accélération du réseau et la rupture des limites du réseau, etc. En outre, les proxys HTTP sont également couramment utilisés pour le débogage, la surveillance et l'analyse des API Web appelées dans les applications Android/IOS. Actuellement, les logiciels bien connus incluent Fiddler, Charles, Burp Suite et mitmproxy. Le proxy HTTP peut également être utilisé pour modifier le contenu des requêtes/réponses, ajouter des fonctions supplémentaires aux applications Web ou modifier le comportement des applications sans changer de serveur.
0x01 Qu'est-ce que le proxy HTTP
Le proxy HTTP est essentiellement une application Web, et il n'est pas fondamentalement différent des autres applications Web ordinaires. Après avoir reçu la requête, le proxy HTTP détermine de manière exhaustive l'hôte cible en fonction du nom d'hôte indiqué dans le champ Hôte de l'en-tête et de l'adresse de la requête Get/POST, établit une nouvelle requête HTTP, transmet les données de la requête et transmet les données de réponse reçues. au client.
Si l'adresse de la requête est une adresse absolue, le proxy HTTP utilise l'hôte dans l'adresse, sinon le champ HOST dans l'en-tête est utilisé. Effectuez un test simple, en supposant que l'environnement réseau est le suivant :
192.168.1.2 Web服务器 192.168.1.3 HTTP代理服务器
Utilisez telnet pour tester
$ telnet 192.168.1.3 GET / HTTP/1.0 HOST: 192.168.1.2
Notez que deux retours chariot consécutifs sont requis à la fin, ce qui est une exigence du protocole HTTP. Une fois terminé, vous pouvez recevoir le contenu de la page //m.sbmmt.com/. Faisons quelques ajustements. Apportez l'adresse absolue
$ telnet 192.168.1.3 GET //m.sbmmt.com/ HTTP/1.0 HOST: 192.168.1.2
lors d'une requête GET. Notez que l'HOST est également défini sur 192.168.1.2, mais le. le résultat de l'exécution est renvoyé Le contenu de la page //m.sbmmt.com/ est l'information d'adresse IP publique.
Comme le montre le processus de test ci-dessus, le proxy HTTP n'est pas une chose très compliquée, tant que la requête originale est envoyée au serveur proxy. Lorsqu'un proxy HTTP ne peut pas être défini, pour un scénario dans lequel un petit nombre d'hôtes nécessite un proxy HTTP, le moyen le plus simple consiste à faire pointer l'adresse IP du nom de domaine de l'hôte cible vers le serveur proxy, ce qui peut être réalisé en modifiant le fichier hosts. .
0x02 Définir le proxy HTTP dans le programme Python
paramètre de proxy urllib2/urllib
urllib2
est la bibliothèque standard Python . C'est très puissant, mais un peu lourd à utiliser. Dans Python 3, urllib2 n'est plus conservé et déplacé vers le module urllib. Dans urllib2, ProxyHandler est utilisé pour configurer le serveur proxy.
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())
Vous pouvez également utiliser install_opener pour installer l'ouvreur configuré dans l'environnement global, afin que tous les urllib2.urlopen utilisent automatiquement le proxy.
urllib2.install_opener(opener) r = urllib2.urlopen('http://httpbin.org/ip') print(r.read())
Dans Python 3, utilisez 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 paramètres de proxy
requests est actuellement l'une des meilleures bibliothèques HTTP et mon habitude Le plus bibliothèque couramment utilisée lors de la construction de requêtes http. Sa conception API est très conviviale et facile à utiliser. Définir un proxy pour les requêtes est très simple. Il vous suffit de définir un paramètre sous la forme {'http' : 'x.x.x.x:8080', 'https' : 'x.x.x.x:8080'} pour les proxys. Parmi eux, http et https sont indépendants l’un de l’autre.
In [5]: requests.get('http://httpbin.org/ip', proxies={'http': '121.193.143.249:80'}).json() Out[5]: {'origin': '121.193.143.249'}
Vous pouvez définir directement l'attribut proxy de la session, éliminant ainsi le problème d'apporter des paramètres proxy à chaque requête.
s = requests.session() s.proxies = {'http': '121.193.143.249:80'} print(s.get('http://httpbin.org/ip').json())
0x03 Variable d'environnement HTTP_PROXY / HTTPS_PROXY
Les bibliothèques urllib2 et Requests reconnaissent les variables d'environnement HTTP_PROXY et HTTPS_PROXY , une fois ces variables d'environnement détectées, elles sont automatiquement définies à l'aide du proxy. Ceci est très utile lors du débogage avec un proxy HTTP, car vous pouvez ajuster l'adresse IP et le port du serveur proxy en fonction des variables d'environnement sans modifier le code. La plupart des logiciels dans *nix prennent également en charge la reconnaissance des variables d'environnement HTTP_PROXY, telles que curl, wget, axel, aria2c, etc.
$ 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" }
Dans l'environnement interactif IPython, vous devrez peut-être souvent déboguer temporairement les requêtes HTTP. Vous pouvez simplement l'augmenter en définissant os.environ['http_proxy. '] / Annuler le proxy HTTP pour y parvenir.
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'}
0x04 MITM-Proxy
MITM provient de Man-in-the-Middle Attack, faisant référence Les attaques de type Man-in-the-middle interceptent, surveillent et falsifient généralement les données du réseau entre le client et le serveur.
mitmproxy est un artefact proxy open source man-in-the-middle développé en langage Python. Il prend en charge SSL, le proxy transparent, le proxy inverse, l'enregistrement et la lecture du trafic et les scripts personnalisés. La fonction est quelque peu similaire à Fiddler sous Windows, mais mitmproxy est un programme console sans interface graphique, mais il est assez pratique à utiliser. En utilisant mitmproxy, vous pouvez facilement filtrer, intercepter et modifier tous les paquets de requête/réponse HTTP du proxy. Vous pouvez même utiliser son API de script pour écrire des scripts afin d'intercepter et de modifier automatiquement les données 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中文网!