V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
smilebaby
V2EX  ›  Python

mitmproxy 太慢了,有没有性能更好的替代品?

  •  
  •   smilebaby · Feb 19, 2022 · 8714 views
    This topic created in 1528 days ago, the information mentioned may be changed or developed.

    最近在使用 mitmproxy 作为中间人代理服务器做一些对 https 请求和响应的中间修改。现在的问题是 mitmproxy 非常慢 , 在请求到达和响应完成都会增加几百毫秒的延迟,问问大家有没有这样一款代理服务器:

    1.像 mitmproxy 也可以有插件机制的 https 代理服务器。 2.性能快一点,真正的请求以外的浪费尽量少;能支持 https 长链接,不要每次请求好像都要重新握手。

    Supplement 1  ·  Feb 19, 2022
    正常的一个请求

    02-19 18:19:12-1000197041366 0.01 [testproxy-35224 MainThread-5464] before no proxy call.
    02-19 18:19:12-1000197309182 26.78 [testproxy-35224 MainThread-5464] after no proxy call.len=2443 c=


    经过 mproxy 后

    02-19 18:19:13-1000204438122 46.85 [mproxy] into request... url:https://www.baidu.com/
    02-19 18:19:13-1000204442339 0.42 [mproxy] exit request... url:https://www.baidu.com/
    02-19 18:19:13-1000205221067 77.87 [mproxy] into response... url:https://www.baidu.com/
    02-19 18:19:13-1000205221281 0.02 [mproxy] exit response... url:https://www.baidu.com/
    02-19 18:19:13-1000205389596 16.83 [testproxy] after proxy call.len=2443 c=

    可用看到 进入 request 前 经历了 46ms ,请求完成后又消耗了 16ms 才到了调用结果。从离开 request 到 进入 response 也把 原来的 26ms 拉倒了 77ms 。
    Supplement 2  ·  Feb 20, 2022
    问题开始没有说清楚。补充如下:问题的实质是目前看浏览器和代理之间没有维持一个长链接,导致每次请求浪费在浏览器和代理之间的时间太多,特别是 https 的访问每次都要初始化。忽略如下情况:

    1.第一次请求慢可以接受;只要后续的访问有效率即可。
    2.对真正目标的访问性能不重要,因为数据是自己组织的,或者可以在插件中自己编程获取,有很大的灵活性。

    所以现在的问题变成了:

    1.能否优化 mitmproxy 去提高 浏览器和代理 间的性能,甚至达到维持长链接的效果(同在一台机器上时来回消耗低于 10 ms )
    2.如果 mitmproxy 不行,有其他 可以做到的替代品吗? 要有中间修改数据的插件能力,最好是支持 python (因为大量中间数据的产生依赖现有的 python 实现)

    感谢:
    @also24 @jerryjhou 对 mitmproxy 优化的建议。
    @wuruxu C 实现的建议 https://github.com/droe/sslsplit
    @ly841000 c# Titanium.Web.Proxy 库
    @monkeyWie java 的 https://github.com/monkeyWie/proxyee
    @0o0O0o0O0o go 的 建议

    其实我还实验了 python 的两个库,性能上没有达到期望。

    https://github.com/abhinavsingh/proxy.py
    https://github.com/inaz2/proxy2
    37 replies    2022-02-21 13:00:26 +08:00
    jerryjhou
        1
    jerryjhou  
       Feb 19, 2022 via iPad
    把证书验证取消能降低延迟,你敢吗
    smilebaby
        2
    smilebaby  
    OP
       Feb 19, 2022
    @jerryjhou 必须要走 https ,因为浏览器要跑 https 的网页。这种情况能 把证书验证取取消 ? 能否详细说说 已经信任了 mitmproxy 的证书了,我感觉没啥不敢的。
    dcty
        3
    dcty  
       Feb 19, 2022 via iPhone
    Mac 的话试试看 surge
    smilebaby
        4
    smilebaby  
    OP
       Feb 19, 2022
    @dcty 谢谢,由于 IE 等问题,希望 是 能有个 windows 上可用的。
    jerryjhou
        5
    jerryjhou  
       Feb 19, 2022 via iPad
    @smilebaby 取消验证不是指浏览器不验证证书,是让 Mitmproxy 不再验证远程服务器的证书
    中间人的工作原理肯定会有额外延迟
    haoliang
        6
    haoliang  
       Feb 19, 2022
    openresty?
    smilebaby
        7
    smilebaby  
    OP
       Feb 19, 2022
    @jerryjhou 非常有用!具体是怎么操作?
    ch2
        8
    ch2  
       Feb 19, 2022
    Fiddler 自带的 Jscript
    smilebaby
        9
    smilebaby  
    OP
       Feb 19, 2022
    @ch2 感觉 fiddler 界面很重,也不快, 插件还不支持 python 。
    also24
        10
    also24  
       Feb 19, 2022   ❤️ 1
    @jerryjhou #5
    看了你这条,去翻了下文档,发现 mitmproxy 有个 "Upstream Certificate Sniffing" 的功能,感觉这个功能会大大的增加延迟。
    https://docs.mitmproxy.org/stable/concepts-certificates/#upstream-certificate-sniffing


    这个功能可以通过选项 upstream_cert 来关闭。


    @smilebaby #7
    可以通过 ssl_insecure 选项关闭对上游证书的验证,不过我觉得可以先试一下我前面提到的 upstream_cert 选项

    https://docs.mitmproxy.org/stable/concepts-options/
    smilebaby
        11
    smilebaby  
    OP
       Feb 19, 2022
    @also24 @jerryjhou 多谢两位。我还不太熟悉这个 mitmproxy ,upstream_cert ssl_insecure 这两项 具体怎么设置 ? 我现在的程序是这样启动的 mitmproxy.main.mitmdump( ['-q','-s',__file__,'-p','9999','--insecure'] )
    also24
        12
    also24  
       Feb 19, 2022   ❤️ 1
    @smilebaby #11
    你的 mintmproxy 版本是? --insecure 应该是旧版本的选项,对应新版本的 --ssl-insecure

    至于 upstream_cert ,应该使用 --set upstream_cert=false
    smilebaby
        13
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @also24 谢谢!因为要在 py2 上跑,用了个低版本。我刚想起来,题目里没说清楚,其实我大部分情况是自己造一个响应,所以不请求真正的服务器。现在要解决的是浏览器和代理间的性能问题,哪怕同一台机器上,也像附言里看到的浪费太多时间。浏览器和代理间能保持长链接吗?
    wuruxu
        14
    wuruxu  
       Feb 19, 2022
    看看这个用 C 实现的
    https://github.com/droe/sslsplit
    zer
        15
    zer  
       Feb 19, 2022
    试过 charles 吗?
    ly841000
        16
    ly841000  
       Feb 19, 2022
    也用过 mitmproxy ,不仅慢,还有内存泄漏,时间长了连不上等问题,体验很差,
    后来用 c# Titanium.Web.Proxy 库,只对需要修改的 Host 代理,其它的直连,好用太多了
    ETiV
        17
    ETiV  
       Feb 19, 2022
    你得说说你本质的需求

    至少这些年我用它下来没觉得它慢过,因为我根本不会在意响应到达客户端的延迟 🤣

    mitmproxy 在设计上是为了能够劫持并修改内容的,修改内容这一部分就需要等待内容全部下载回来后再触发的钩子。。然后它再将这些内容吐回给请求端。

    这中间必然有延迟,或者说增加了请求端的「首字节响应时间」
    smilebaby
        18
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @ETiV 对,我的问题开始没有说清楚。我的问题实际是目前看浏览器和代理之间没有维持一个长链接,导致每次请求浪费在浏览器和代理之间的时间太多。第一次请求慢可以接受,对真正目标的访问更不重要,因为数据是自己组织的,或者可以不用 mitmproxy 获取。
    smilebaby
        19
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @ly841000 谢谢推荐。
    smilebaby
        20
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @wuruxu 需要 Windows 下插件支持,谢谢推荐。
    smilebaby
        21
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @zer 这个知道,感觉和 fiddler 一类,有界面的东西,感觉不会快。
    monkeyWie
        22
    monkeyWie  
       Feb 19, 2022
    java 的可以吗,试试我这个: https://github.com/monkeyWie/proxyee
    smilebaby
        23
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @monkeyWie 谢谢推荐。
    smilebaby
        24
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @monkeyWie 才发现您是作者,厉害!我需要找朋友随后实验一下。我现在的问题主要集中在浏览器和代理间这个交互需要保持长链接,使用场景是同一台机器上,希望通讯时间能降到 10ms 一下。https 通讯同一台机器上保持长链接并降到 10ms 以下,您觉得可能吗?
    smilebaby
        25
    smilebaby  
    OP
       Feb 19, 2022 via Android
    先忽略代理服务器和真实网址之间交互的性能问题。( 1.大部分情况是自己组织伪数据,2.有真实的请求也可以自己实现不用代理程序自己的。)
    llbbzh
        26
    llbbzh  
       Feb 19, 2022
    Fiddler 性能不错的呀,感觉比 Mitmproxy 好不少
    0o0O0o0O0o
        27
    0o0O0o0O0o  
       Feb 19, 2022 via iPhone
    我用过很多 mitm 工具和库,对于你描述的场景,我还是建议你自己实现。go 有不少 mitm 实现,找个用用,十行不到就能实现一个简单的 mitm ,语言跨平台,而且也不用找什么插件系统了,自己写代码实现想要的功能。
    0o0O0o0O0o
        28
    0o0O0o0O0o  
       Feb 19, 2022
    import "github.com/elazarl/goproxy"

    proxy := goproxy.NewProxyHttpServer()
    proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile(pattern))).
    HandleConnect(goproxy.AlwaysMitm)
    // proxy.OnRequest ...
    // proxy.OnResponse ...
    smilebaby
        29
    smilebaby  
    OP
       Feb 19, 2022 via Android
    @0o0O0o0O0o 是个新思路,多谢!
    neohob
        30
    neohob  
       Feb 19, 2022 via iPhone
    socat gost realm
    mrchi
        31
    mrchi  
       Feb 20, 2022
    这是用到生产环境上了?这玩意难道不是调试用的吗?调试时候多了几百豪秒延迟你能感觉出来?
    monkeyWie
        32
    monkeyWie  
       Feb 20, 2022
    @smilebaby #24 我这边的实现会保持和复用浏览器和代理服务器的连接的
    smilebaby
        33
    smilebaby  
    OP
       Feb 20, 2022
    @monkeyWie #32 那太好了!我想办法试用一下。
    SergeGao
        34
    SergeGao  
       Feb 20, 2022
    可以试试 whistle ,https://github.com/avwo/whistle
    smilebaby
        35
    smilebaby  
    OP
       Feb 21, 2022
    @SergeGao 好的。还是非常希望能有个 支持 python 的。 这一块是 python 的强项啊。
    daiqiangbudainiu
        36
    daiqiangbudainiu  
       Feb 21, 2022
    奇怪,如果你的所有返回都是自己构造的,那么你应该做一个 mock server ,这样也不会存在性能问题
    smilebaby
        37
    smilebaby  
    OP
       Feb 21, 2022
    @warcraft1236 你是说不过代理,直接做个假的 web 服务吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3738 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 92ms · UTC 05:02 · PVG 13:02 · LAX 22:02 · JFK 01:02
    ♥ Do have faith in what you're doing.