Loading

mitmweb在linux上进行反向代理及浏览器中实时查看请求响应

背景

大家好,我是逐日。最近我们做软件测试的同事遇到一些问题,测试app时,网络链路是这样的:app--》后端nginx的ip+端口--》后端服务。一般为了便于定位是前端app还是后端的问题,会使用fiddler、charles等进行网络抓包。常见的方法是这样的:手机和电脑连同一个wifi,保证手机可以访问电脑上的服务(telnet要通)。比如电脑ip:192.168.1.1,fiddler/charles监听8080端口,手机设置wifi的代理为192.168.1.1:8080,这种情况下,fiddler、charles就承担了代理服务器的工作。

问题在于,fiddler、charles基本只能代理http、https类型的流量,对于纯粹的tcp私有协议,那自然是没有办法。

最近,我们这边有两款app,都因为不同原因,不能抓了。

一个app是因为,app发出去的http流量,为了安全,会转换为tcp流量,在服务端的tcp网关,再还原为http流量,然后再传输给后端nginx。链路为:

app发出http--》app转换为tcp--》tcp网关(转换tcp为http)--》后端nginx(接收http流量)。

另一个app呢,也是因为安全问题,会将https报文中的body进行加密;服务端呢,是一个openresty(加强版nginx),lua脚本对流量进行解密,然后再发到后端java服务。

这两个的共同问题是,在后端没解密之前,抓到的报文都没法看,对测试同事是很不友好的。我们想要的,就是一个能在图形界面上实时看流量的软件,但明文部分的流量都在linux服务器上。

基于这个原因,最终找到了mitmweb这个linux上的代理软件。

解决方案--mitmweb

mitmweb官网:https://www.mitmproxy.org/

mitmweb简单理解,还是和fiddler等一样,就是个代理软件。

一张图解释下我怎么用的,老的链路如下:

image-20260905195447475

新的链路如下,将mitmweb接到了nginx的后面:

image-20260905200155211

从上图可以看出,nginx拿到的流量,被转发给了mitmweb,然后再由mitmweb转给了java。既然流量都从mitmweb过了,那就相当于一个中间人,那就什么事都能干了,比如像fiddler、charles那样去改请求、改响应等等,都可以。

其实linux上的各种代理软件挺多的,难的是有图形界面可以实时查看经过的流量,而mitmweb就暴露了一个端口出来,可以通过浏览器来查看,大概长下面这样:

image-20260905200634091

mitmweb介绍

linux服务器上,能把网络流量进行图形界面展示的,确实是少数,更多的是命令行方式展示的,就像tcpdump那样。

而mitmweb其实也不例外,它还有两个兄弟命令:

  • mitmproxy,命令行方式展示:

    image-20260905200953212

  • mitmdump,可以抓包到文件里。

这几个命令的差异,可以看下这个官网文章:

https://docs.mitmproxy.org/stable/

  • mitmproxy,数据都保存在内存里,所以使用它时,流量不要太大。支持和人交互,实时检查和修改流量。我没用过,可自行探索

  • mitmweb,数据都保存在内存里,同样,流量不要太大。支持和人交互,实时检查和修改流量。

  • mitmdump,不支持和人交互,数据应该是流式的,不会一直存在内存里,支持把流量存到文件里。另外,支持指定自定义的python脚本(类似于hook),对流量进行各种操作。我感觉这个模式比较像xml解析的流式模式。

    mitmdump -w outfile
    保存流量到文件outfile中。
    
    指定一个脚本,如下脚本会给响应都加上一个header:
    mitmdump -s examples/simple/add_header.py
    

另外,这几个命令,支持的平台包括:windows、mac、linux,当然,像在linux上,部分功能对内核会有些要求,具体看官网。

支持的协议

https://docs.mitmproxy.org/stable/concepts/protocols/

http1.0(含https)

http1.1(含https)

http2(含https)

http3(含https)

websocket

dns

tcp、udp四层代理

支持的代理方式

参考:https://docs.mitmproxy.org/stable/concepts/modes/

常规的正向代理

用于代理客户端。

看官网这个图,正向代理就是说,下图的客户端自始自终,都知道自己要访问的是 http://example.com ,由于一些网络限制或者什么原因,决定通过mitmproxy来进行中转。

image-20260905203636376

代理某个软件、某个进程

https://docs.mitmproxy.org/stable/concepts/modes/#local-capture

mitmproxy --mode local       # Intercept everything on this machine. 本机全部流量
mitmproxy --mode local:curl  # Intercept cURL only. 指定进程名
mitmproxy --mode local:42    # Intercept PID 42 only.  指定pid

这个着实有点惊艳,好像是这几年才出的功能,有点类似于proxifier那个付费软件。准备重点试试在windows上的这个功能。

在linux上呢,发现对内核要求有点高,说要Linux 6.8以上,我还以为我们的centos 7也能用上了呢,想多了。

WireGuard

这个模式好像是,mitmproxy 启动后,相当于一个WireGuard VPN server,然后WireGuard client都可以来连了。

这有篇文章:https://www.mitmproxy.org/posts/wireguard-mode/

好像是安卓手机直接扫码,就能连上了:

image-20260905205145952

简单查了下,后续试试:

image-20260905205750965

反向代理

类似于nginx了,这就是我这个场景下准备用的。

image-20260905200155211

透明代理

比较复杂,后面研究,反正就是改路由表。

https://docs.mitmproxy.org/stable/concepts/modes/#transparent-proxy

tun interface

仅linux可用。

https://docs.mitmproxy.org/stable/concepts/modes/#tun-interface

Upstream Proxy

https://docs.mitmproxy.org/stable/concepts/modes/#upstream-proxy

image-20260905210751178

SOCKS Proxy

正向代理,不过不是http那些协议,而是代理SOCKS5协议。

dns server

作为一个dns服务器,支持dns客户端查询。

linux上安装mitmweb

https://docs.mitmproxy.org/stable/overview/installation/

按官网意思,下载二进制是最推荐的。

https://www.mitmproxy.org/downloads/

我先选了个最新的版本:https://www.mitmproxy.org/downloads/#12.2.3/

我看下图也说支持docker等方式:

image-20260905211527053

centos 7.9无法运行

[root@year-account-nginx2 mitmproxy-12.2.3]# tar -zxvf mitmproxy-12.2.3-linux-x86_64.tar.gz 
mitmproxy
mitmdump
mitmweb

由于缺少glibc_2.18版本,运行失败:

image-20260905212736882

由于我的CentOS 7.9 的 glibc 是 2.17,所以二进制是跑不起来的。要跑只能docker跑。

但我决定换一台机器。

open-euler

换了一台open-euler的机器,这个glibc是没问题的。

[root@xxx-openrestry ~]# cat /etc/os-release 
NAME="openEuler"
VERSION="22.03 (LTS-SP4)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP4)"
ANSI_COLOR="0;31"

[root@xxx-openrestry ~]# ldd --version
ldd (GNU libc) 2.34

这个直接可以启动:

[root@111-openrestry test]# ./mitmweb 
[21:33:11.813] Using a plaintext password to protect the mitmweb user interface. Consider using an argon2 hash for `web_password`  instead.
[21:33:11.818] HTTP(S) proxy listening at *:8080.
[21:33:11.820] Web server listening at http://127.0.0.1:8081/
[21:33:11.870] No web browser found. Please open a browser and point it to http://127.0.0.1:8081/

可以通过指定--web-host 0.0.0.0来允许ip访问:

[root@VM-0-6-rockylinux mitmproxy-12.2.3]# ./mitmweb --web-host 0.0.0.0
[21:49:56.844] HTTP(S) proxy listening at *:8080.
[21:49:56.845] Web server listening at http://0.0.0.0:8081/?token=70854dcc18c57019425f836187e88e53
[21:49:56.978] No web browser found. Please open a browser and point it to http://0.0.0.0:8081/?token=70854dcc18c57019425f836187e88e53
[21:49:56.978] You can configure a fixed authentication token by setting the `web_password` option (https://docs.mitmproxy.org/stable/concepts-options/#web_password).

然后访问,需要输入显示的token:

image-20260905215408142

image-20260905220214358

上述默认是在正向代理模式下运行的:

image-20260905220251001

正向代理

我是在公网云服务器测试,因为就这一台服务器,所以我先弄了个目标服务:

[root@VM-0-6-rockylinux ~]# python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

假设http://1.1.1.1:8000就是最终要访问的后台服务。

image-20260905221847568

mitmweb启动命令如下:

./mitmweb --web-host 0.0.0.0 --set block_global=false

假设我们要通过正向代理htp://1.1.1.1:8080来访问http://1.1.1.1:8000

可以这么写:
curl -x http://1.1.1.1:8080 http://127.0.0.1:8000

image-20260905222046008

反向代理

不停服务,直接可以改:

image-20260905222559618

测试:这次没指定代理了:

image-20260905222617222

配置保存

但我发现个问题,上述已经改成反向代理了,但是程序关了一重启,又恢复原样,变成正向代理了。

可以这样,先:

 ./mitmweb --options > /root/.mitmproxy/config.yaml

然后自己再去config.yaml里慢慢改,我主要也就改了下:

web_columns:
- tls
- icon
- path
- method
- status
- size
- time

改成了:
web_columns:
- tls
- icon
- path
- method
- status
- size
- time
- timestamp


web_host: 0.0.0.0

密码:
web_password: '11111111'

效果如下:

image-20260905223907579

linux上后台多实例运行

我实际是下面这样运行,而且机器上会启动多个实例,多个实例共享配置文件:/root/.mitmproxy/config.yaml

然后这里通过命令行参数指定,这个优先级更高:

 nohup /root/upload/mitmproxy-tool/mitmweb --mode reverse:http://1.1.1.1:9905 --web-host 0.0.0.0 --web-port 8168 --listen-port 8167   2>&1 &
 
  nohup /root/upload/mitmproxy-tool/mitmweb --mode reverse:http://1.1.1.1:9906 --web-host 0.0.0.0 --web-port 8268 --listen-port 8267   2>&1 &

总结

回头再试试其他的代理模式,及https代理之类的。好了,就这。

posted @ 2026-09-05 22:45  三国梦回  阅读(12)  评论(0)    收藏  举报