如何使用Go监听所有连接的GET与POST请求,实现类似mitmproxy的URL捕获功能
用Go实现类似mitmproxy的URL捕获功能指南
嘿,刚好我之前折腾过类似的需求,给你梳理下用Go实现这个功能的完整思路,绝对能帮你快速上手~
核心依赖包选择
首先,你不需要从零写底层代理逻辑,Go生态里有成熟的MITM代理库可以直接用:
github.com/elazarl/goproxy:这是最常用的HTTP/HTTPS代理库,完美支持中间人攻击(MITM),能自动解密HTTPS流量,和mitmproxy的核心逻辑一致,上手成本极低,完全匹配你的需求。- 如果后续需要处理非HTTP的底层TCP/UDP流量,可以试试
github.com/google/gopacket抓包,但你的目标是捕获URL,用goproxy就足够了。
实现步骤拆解
1. 生成MITM根证书
要解密HTTPS流量,必须让目标设备信任你的根证书,和mitmproxy的原理一模一样:
- 用goproxy自带的工具生成证书,执行以下命令:
执行后会在当前目录生成go run github.com/elazarl/goproxy/cmd/goproxy-cacert.pem(根证书)和key.pem(私钥)。 - 把
cert.pem安装到目标设备的信任证书列表里(不同设备操作不同:安卓要安装用户证书,iOS需要通过描述文件信任,电脑直接导入系统证书库)。
2. 编写代理核心代码
下面是一个最小可运行的示例,能捕获所有进出的HTTP/HTTPS请求URL:
package main import ( "log" "net/http" "github.com/elazarl/goproxy" ) func main() { // 初始化代理服务器实例 proxy := goproxy.NewProxyHttpServer() proxy.Verbose = true // 开启详细日志,方便调试过程排查问题 // 加载我们生成的MITM证书 caCert, caKey, err := goproxy.CertFromFile("cert.pem", "key.pem") if err != nil { log.Fatalf("加载证书失败: %v", err) } proxy.Ca = caCert proxy.Cert = caCert proxy.Key = caKey // 允许对所有HTTPS连接进行MITM解密 proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm) // 捕获所有请求的URL proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { // 打印请求方法和完整URL log.Printf("[请求] %s %s", req.Method, req.URL.String()) // 这里可以扩展:把URL写入文件、过滤特定域名、统计请求次数等 return req, nil // 放行请求,不影响原流量 }) // 可选:捕获响应中的重定向URL proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response { if resp.StatusCode >= 300 && resp.StatusCode < 400 { if location := resp.Header.Get("Location"); location != "" { log.Printf("[重定向] %s", location) } } return resp // 放行响应 }) // 启动代理服务,监听8080端口 log.Println("代理服务器已启动,监听地址: :8080") log.Fatal(http.ListenAndServe(":8080", proxy)) }
3. 配置目标设备代理
把目标设备的HTTP/HTTPS代理设置为你的Go程序运行机器的IP + 8080端口,比如你的电脑IP是192.168.1.100,就设置代理为192.168.1.100:8080。
扩展功能建议
- URL持久化:把捕获到的URL写入本地文件(用
os包)或者数据库(比如SQLite、MySQL),方便后续分析。 - 域名过滤:只捕获特定域名的URL,比如在
DoFunc里判断req.URL.Host是否包含目标关键词,过滤掉不需要的流量。 - 请求内容分析:除了URL,还可以获取请求头、请求体、响应内容等,做更深入的流量分析。
- 性能优化:如果要处理高并发请求,可以用goroutine异步处理URL存储逻辑,避免阻塞代理服务的正常运行。
注意事项
- 必须确保目标设备信任你的MITM根证书,否则HTTPS请求会被设备直接拒绝。
- 某些APP可能会使用证书钉扎(Certificate Pinning)技术,这种情况下无法解密其HTTPS流量,和mitmproxy遇到的限制一致。
- 如果需要监听本机的所有流量(而不是通过代理),可以用
gopacket抓包,但需要更高的权限(比如root),且处理逻辑会复杂很多。
内容的提问来源于stack exchange,提问作者Han Hanz




