本文转载自微信公众号《测试开发刚哥》,作者dongfanger。转载本文请联系测试开发帮公众号。ManInTheMiddlemitm是ManInTheMiddle的首字母缩写,意思是中间人,说明mitmproxy是一个代理,可以拦截请求,实现网络抓包。比较知名的网络抓包工具有Fiddler、Charles、HttpWatch、WireShark、BurpSuite、Postman等,mitmproxy相对没那么出名。与上述工具相比,它的独特优势在于提供了PythonAPI,可以编写Python代码对网络请求进行流量记录,收集接口信息,转化为接口自动化用例等。mitmproxy的官方文档不仅介绍了mitmproxy工具的使用,还介绍了代理实现的原理,对我们学习和掌握网络知识很有帮助。安装和pip安装pipinstallmitmproxymitmproxy是Python开发的,用pip可以安装成功。官方给出了二进制安装包等方法。我觉得作为一个用Python开发的工具,直接用pip安装比较Pythonic。命令启动可以通过三种命令启动mitmproxy:mitmproxyconsolemitmwebwebpagemitmdumpcommandline它们的内容是一样的,只是UI不同。手动设置代理后,mitmproxy默认会监听http://localhost:8080。您需要设置代理并将代理服务器设置为该地址。Windows可以这样设置:设置后一定要记得点击保存按钮,否则代理不会生效。实际上,Charles等网络抓包工具会自动配置代理,而mitmproxy则需要手动设置代理。开发组解释说,由于浏览器版本和配置经常变化,建议按照网上环境搜索方式手动设置。要下载证书,请访问http://mitm.it/。如果代理配置没有生效,打开后会出现这个界面:如果正常,会出现证书下载页面:根据平台选择对应的证书安装就OK了。mitmproxy的使用与其他抓包工具类似。官方视频演示了如何使用mitmproxy:https://docs.mitmproxy.org/stable/mitmproxytutorial-userinterface/并介绍了5种运行模式:https://docs.mitmproxy.org/stable/concepts-modes/读者可以阅读它自己。mitmproxy工作原理客户端(本机)连接代理服务器(http://127.0.0.1:8080),代理服务器连接服务器。客户端向代理服务器发送请求,代理服务器向服务器发送请求。所有请求都可以通过mitmproxy拦截。对于HTTP,可以直接通过mitmproxy传递请求。对于HTTPS,有SSL/TLS安全认证,必须安装证书,服务器会认为mitmproxy的请求是可信的,请求就会被成功转发。HTTPS代理过程要复杂得多。客户端首先与mitmproxy建立连接(第12步),然后进行安全认证(第36步),最后发送请求(第7~8步)。反向代理假设本机使用FastAPI启动了一个Mock服务,地址为http://127.0.0.1:5000,如何使用mitmproxy拦截通过Postman调用接口的请求?这需要使用反向代理。首先以反向代理模式运行mitmproxy,服务器端口为5000,监听端口为8000:mitmproxy--modereverse:http://127.0.0.1:5000--listen-host127.0.0.1--listen-port8000和然后把请求中的5000端口http://127.0.0.1:5000/login改成8000,访问:http://127.0.0.1:8000/login就可以在mitmproxy中看到请求了:这样就可以使用Mock了本地服务来调试拦截请求的Python代码。反向代理,无需在本地手动设置代理。PythonAPIPythonAPI是mitmproxy的一个特色功能:可以在Python代码中处理拦截的请求。Addons提供了很多hook函数,比如request:"""Basicskeletonofamitmproxyaddon。运行如下:mitmproxy-sanatomy.py"""frommitmproxyimportctxclassCounter:def__init__(self):self.num=0defrequest(self,flow):self.num=self.num+1ctx.log.info("We'veseen%dflows"%self.num)addons=[Counter()]response:"""添加每个响应的HTTP标头。"""classAddHeader:def__init__(self):self.num=0defresponse(self,flow):self.num=self.num+1flow.response.headers["count"]=str(self.num)addons=[AddHeader()]启动时添加-s参数指定脚本:mitmdump-s./anatomy.py代码会在请求被拦截时生效。更多的hook函数可以参考官方说明:https://docs.mitmproxy.org/stable/api/events.html这里不再赘述。至于如何使用mitmproxy记录流量并自动生成自动化用例,我会在开发完成后集成到新版tep中,届时会介绍,敬请期待。参考:mitmproxy官方文档https://docs.mitmproxy.org/stable/
