mitmproxy 应用(二)可编程代理

系列文章

mitmproxy 是可编程的,而且非常容易使用。先来看一个简单的例子:

替换内容

 1import re
 2from mitmproxy import ctx
 3
 4def request(flow):
 5    remote_host = flow.request.pretty_host
 6    method = flow.request.method
 7
 8    ctx.log.info('remote_host %s'%remote_host)
 9    ctx.log.info('request.host %s' % flow.request.host)
10    ctx.log.info('request.path %s' % flow.request.path)
11    ctx.log.info('request.pretty_url %s' % flow.request.pretty_url)
12    ctx.log.info('request.query %s' % flow.request.query)
13    ctx.log.info('request.method %s' % flow.request.method)
14    ctx.log.info('client host %s' % flow.client_conn.address.host)
15
16    flow.request.replace('Mozilla', 'Google', re.M)

这个例子打印出了客户端发来的请求中的一些有用的属性,其中:

  • flow.request.pretty_host 请求的域名。如果希望对不同的网站采取不同的策略,可使用该值。
  • flow.request.host 请求的 IP 地址。
  • flow.request.path 请求的路径。如果希望对不同的请求路径采用不同的策略,可使用该值。
  • flow.client_conn.address.host 客户端 IP。如果希望对不同的客户端采取不同的策略,可使用该值。

ctx.log.info 可以将内容打印在 mitmproxy 的 Event log 窗口中(采用快捷键 e 打开) ,下面是访问网站 https://zengrong.net 的 log 内容:

1remote_host zengrong.net
2request.host 121.40.23.108
3request.path /
4request.pretty_url https://zengrong.net/
5request.query MultiDictView[]
6request.method GET
7client host 192.168.43.196

上面代码中最后还有一句 replace ,是将请求中的所有 Mozilla 字符串替换成 Google 。这里的“所有”包含下面的内容:

  • header
  • path
  • body

在我的这个请求中,仅有一个 Header User-Agent 包含 Mozilla 字符串:

replace

动态修改代理

有 5 个客户端,我希望这 5 个客户端在访问同一个网站的时候,使用不同的代理服务器。该如何处理?

传统的方法是在这 5 个客户端上设置不同的代理服务器。这样存在两个问题:

  1. 有的应用程序可能不走系统代理。
  2. 如果有 100 个客户端呢?

用 mitmproxy 可以解决这些问题。

对于不走系统代理的应用程序,我们可以采用 mitmproxy 应用(一)基础代理 中提到的透明代理的方法来解决。

我们可以将多个客户端的代理服务器全部指向 mitmproxy ,然后在 mitmproxy 中通过编程的方法,为不同的客户端指定不同的代理服务器。

下面是(伪)代码:

1def request(flow):
2    client_ip = flow.client_conn.address.host
3    if client_ip == '192.168.0.10':
4        proxy = ('1.2.3.4', 8080)
5    else:
6        proxy = ('3.4.5.6', 8080)
7    if flow.live:
8        flow.live.change_upstream_proxy_server(proxy)

需要注意的是,request 在每次请求的时候都会被调用。你可能并不希望每次请求都切换代理服务器,这种情况下,可以通过判断 flow.request.path 或者相关属性来实现条件切换。

全文完