ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Go-mitmproxy:5分钟搭建HTTPS中间人代理,实现API调试与安全测试

Go-mitmproxy:5分钟搭建HTTPS中间人代理,实现API调试与安全测试 1. 项目概述为什么你需要一个自己的中间人代理如果你是一名开发者、测试工程师或者对网络协议和安全感兴趣的技术爱好者最近可能经常被一些网络错误困扰。比如你在调试一个调用外部API的应用时突然遇到unexpected status 404 not found: unknown error, url: https://api.deepseek.com/responses或者在使用某些工具时看到curl -fssl https://ollama.com/install.sh | sh这样的命令却对背后的HTTPS流量一无所知。又或者你只是想搞清楚手机App和服务器之间到底传输了什么数据但所有内容都被HTTPS加密得严严实实。这时一个能“窥探”HTTPS流量的工具就显得至关重要。Go-mitmproxy 正是为解决这个问题而生。它是一个用Go语言编写的高性能中间人Man-in-the-Middle MITM代理服务器。简单来说它就像一个“透明的中介”你的设备比如电脑或手机将所有网络请求都先发给它它再转发给真正的目标服务器。在这个过程中它有能力对经过的HTTPS流量进行解密、查看、甚至修改然后再重新加密转发。这听起来有点“黑客”味道但其核心价值在于调试、分析和安全测试。你可以用它来调试API清晰看到你的应用发出的每一个请求和收到的每一个响应包括Header和Body快速定位是请求参数不对还是服务器返回了意想不到的数据。分析网络行为了解一个App或网站具体加载了哪些资源调用了哪些接口对于逆向工程或竞品分析非常有帮助。安全测试作为Web漏洞扫描器或渗透测试工具链的一环拦截和修改请求以测试服务器的安全性。模拟网络环境通过修改响应模拟服务器返回错误如500、404或特定数据用于客户端健壮性测试。与经典的 mitmproxyPython版或 Charles 等图形化工具相比go-mitmproxy 的优势在于其轻量、高性能和易于集成。它本身是一个命令行工具非常适合自动化测试、CI/CD流水线或者嵌入到其他Go应用中。接下来我会带你从零开始在5分钟内搭建起属于你自己的HTTPS中间人代理并深入讲解每一步背后的原理和避坑指南。2. 核心原理与前置知识HTTPS是如何被“中间人”的在动手之前我们必须搞清楚一个核心问题HTTPS设计来就是防止中间人攻击的那 go-mitmproxy 是如何合法地成为这个“中间人”的呢理解这一点是安全、正确使用该工具的关键。2.1 HTTPS 与 TLS/SSL 握手简析HTTPS HTTP TLS/SSL。安全的核心在于TLS握手。简单流程如下客户端向服务器发起连接说“你好我支持这些加密套件。”服务器返回它的数字证书证书里包含了服务器的公钥并由受信任的证书颁发机构CA签名。客户端检查证书是否过期域名是否匹配最重要的是它的签名是否来自我信任的CA列表如操作系统或浏览器内置的根证书如果验证通过客户端就用证书里的公钥加密一个“预主密钥”发给服务器。服务器用自己的私钥解密双方由此生成相同的会话密钥后续通信就用这个对称密钥加密速度快且安全。这个机制确保了即使流量被截获攻击者没有服务器的私钥也无法解密。那么mitmproxy 要解密就必须让客户端信任它自己。2.2 Go-mitmproxy 的中间人机制Go-mitmproxy 实现中间人的核心步骤其实是在模拟一个“受信任的CA”生成根证书首次运行时go-mitmproxy 会在本地生成一个自签名的根证书CA证书和对应的私钥。这个证书不被任何公共CA信任但我们可以手动将其安装到操作系统或浏览器的受信任根证书存储区。动态签发证书当客户端如浏览器请求https://example.com时go-mitmproxy 会拦截这个请求。它并不会直接转发而是以自己的名义动态地创建一个针对example.com的“假”证书。用第一步生成的根证书私钥对这个“假”证书进行签名。建立两个独立的TLS连接连接A客户端 - mitmproxymitmproxy 将刚刚签发的、针对example.com的“假”证书返回给客户端。因为我们已经把 mitmproxy 的根证书安装为受信任的CA所以客户端会愉快地接受这个证书并基于它建立安全的TLS连接。这样mitmproxy 就拥有了解密客户端流量的能力。连接Bmitmproxy - 真实服务器mitmproxy 再以普通客户端的身份与真实的example.com服务器建立标准的HTTPS连接。服务器返回真实的证书mitmproxy 像普通浏览器一样验证它通常忽略证书错误或使用自定义CA池。解密、中转、再加密至此mitmproxy 坐在了两段独立的、安全的TLS连接中间。它可以从连接A解密出客户端的明文请求然后将其通过连接B转发给服务器同样它可以从连接B解密出服务器的明文响应再通过连接A加密后返回给客户端。在整个过程中它可以查看、记录甚至修改这些明文数据。重要提示正因为 mitmproxy 需要解密你的HTTPS流量所以你必须信任它生成的根证书。这意味着在你的测试环境中这个证书是安全的。但绝对不要将 mitmproxy 的根证书安装在你处理敏感信息如网银、主邮箱的日常设备上也切勿将根证书私钥分享给他人。3. 5分钟快速上手搭建你的第一个代理理论说完了我们开始实战。目标是快速运行起一个能拦截HTTPS流量的代理。3.1 环境准备与安装Go-mitmproxy 是Go语言编写的因此你需要先安装Go环境。如果你没有Go可以去官网下载安装。这里假设你已具备基本的命令行操作能力。安装 go-mitmproxy打开终端Linux/macOS或 PowerShell/CMDWindows执行以下命令go install github.com/lqqyt2423/go-mitmproxylatest这条命令会从GitHub下载最新的 go-mitmproxy 源码并编译将可执行文件安装到你的$GOPATH/bin目录下通常位于~/go/bin或C:\Users\YourName\go\bin。请确保该目录已添加到系统的PATH环境变量中这样你才能在任意位置直接运行go-mitmproxy。安装完成后可以通过go-mitmproxy --version检查是否安装成功。3.2 首次运行与根证书生成这是最关键的一步。在终端中直接运行go-mitmproxy默认情况下它会监听本机的8080端口。首次运行时你会发现在用户目录下通常是~/.mitmproxy/在Linux/macOS或C:\Users\YourName\.mitmproxy\在Windows自动生成了几个文件mitmproxy-ca-cert.pem根证书PEM格式mitmproxy-ca-cert.cer根证书DER格式常用于Windows安装mitmproxy-ca-key.pem根证书的私钥务必保密安装根证书到系统macOS双击mitmproxy-ca-cert.pem文件会打开钥匙串访问。找到该证书双击打开在“信任”设置中将“使用此证书时”设置为“始终信任”。Windows双击mitmproxy-ca-cert.cer文件点击“安装证书”选择“本地计算机”下一步选择“将所有的证书都放入下列存储”点击“浏览”选择“受信任的根证书颁发机构”然后完成。Linux (Ubuntu/Debian)sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt sudo update-ca-certificates浏览器你也可以直接将证书文件导入到浏览器如Chrome的 设置 - 隐私和安全 - 安全 - 管理设备证书。但安装到系统是更彻底的方法。安装成功后最好重启一下浏览器让新的根证书生效。3.3 配置客户端使用代理现在代理服务器已经在127.0.0.1:8080运行了我们需要让客户端的流量经过它。方法一系统全局代理最简单macOS/Windows在系统设置 - 网络 - 代理中手动设置HTTP和HTTPS代理为127.0.0.1端口8080。注意这会使你所有的系统网络流量都走代理可能会影响一些不兼容代理的应用。测试完毕后记得关闭。方法二浏览器代理推荐使用浏览器插件如 SwitchyOmegaChrome/Firefox来管理代理。新建一个情景模式配置代理服务器为127.0.0.1:8080协议为HTTP注意go-mitmproxy 接收的是HTTP代理协议但它能处理HTTPS流量。然后通过插件按钮快速切换。方法三命令行工具代理对于curl,wget等可以通过环境变量设置export http_proxyhttp://127.0.0.1:8080 export https_proxyhttp://127.0.0.1:8080 # 然后运行你的curl命令 curl -v https://httpbin.org/get或者在curl命令中直接指定curl -x http://127.0.0.1:8080 -v https://httpbin.org/get3.4 验证拦截是否成功确保go-mitmproxy仍在终端运行。配置好浏览器代理并访问任何一个HTTPS网站例如https://httpbin.org/headers。观察运行go-mitmproxy的终端窗口。你应该能看到滚动的日志显示了拦截到的请求和响应信息包括URL、方法、状态码等。访问一个不存在的HTTPS地址比如https://api.deepseek.com/nonexist。在终端日志里你不仅能看到404 Not Found的状态码还能清晰地看到服务器返回的错误信息体这比浏览器里一个简单的错误页面信息量大多了。至此一个基本的HTTPS拦截代理就已经搭建并运行成功了。你可以在终端里看到所有经过的流量概览。但这只是开始go-mitmproxy 的强大之处在于其可编程性和丰富的功能。4. 核心功能详解与实战配置默认的终端输出信息比较基础。Go-mitmproxy 提供了多种运行模式和配置选项来满足不同场景。4.1 运行模式Web UI 与 命令行1. 命令行模式默认就是我们刚才用的模式所有日志输出到终端。适合快速查看、脚本集成。2. Web UI 模式强烈推荐这是 mitmproxy 传统的优势所在。运行以下命令go-mitmproxy web然后打开浏览器访问http://127.0.0.1:8081注意端口是8081不是代理端口8080。你会看到一个功能强大的Web界面。流量列表清晰展示所有捕获的请求可以按域名、状态码过滤。详情查看点击任何一个请求可以以原始、格式化JSON、HTML等、Hex等多种形式查看请求和响应的每一个字节包括Headers、Cookies、Query参数、表单数据、响应体。拦截与修改你可以手动暂停流量修改请求或响应后再放行。这对于调试和测试极其有用。重放Replay右键点击任何一个历史请求选择“Replay”可以重新发送该请求用于复现问题或性能测试。4.2 关键命令行参数通过参数可以定制代理行为-addr :8080指定监听地址和端口。:前是IP默认0.0.0.0监听所有网络接口:后是端口。-web_addr :8081指定Web UI的监听地址和端口。-ssl_insecure忽略上游服务器证书的错误例如自签名证书。在测试内部服务时常用。-cert_path ~/.my-mitmproxy/指定自定义的CA证书和私钥存储路径。如果你有多个测试环境可以用这个来隔离。-dump_dir ./dumps将所有拦截到的流量以原始格式.har或.mitm转储到指定目录便于后续分析。一个更复杂的启动示例同时开启Web UI并忽略证书错误go-mitmproxy -addr :9090 -web_addr :9091 -ssl_insecure4.3 实战使用Addon进行自动化处理Go-mitmproxy 真正的威力在于其插件Addon系统。你可以用Go编写Addon在流量经过的各个生命周期如请求头已接收、请求体已接收、响应头已接收、响应体已接收等注入自定义逻辑。下面是一个简单的Addon示例它会将所有请求的User-Agent修改为自定义值并记录所有访问的URL到文件创建一个名为my_addon.go的文件。写入以下代码package main import ( fmt io os github.com/lqqyt2423/go-mitmproxy/proxy log github.com/sirupsen/logrus ) // MyAddon 实现了 proxy.Addon 接口 type MyAddon struct { logFile *os.File } func (a *MyAddon) Requestheaders(f *proxy.Flow) error { // 在请求头阶段修改User-Agent f.Request.Header.Set(User-Agent, My-Custom-MitmProxy-Agent/1.0) log.Infof(Modified UA for: %v, f.Request.URL.String()) return nil } func (a *MyAddon) Response(f *proxy.Flow) error { // 在响应完整接收后记录URL到文件 url : f.Request.URL.String() if _, err : a.logFile.WriteString(url \n); err ! nil { log.Errorf(Failed to write log: %v, err) } log.Infof(Logged URL: %v, url) return nil } func main() { // 打开日志文件 file, err : os.OpenFile(visited_urls.log, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err ! nil { log.Fatal(err) } defer file.Close() myAddon : MyAddon{logFile: file} // 创建代理选项并添加我们的Addon opts : proxy.Options{ Addr: :8080, StreamLargeBodies: 1024 * 1024 * 5, // 处理大文件 } p, err : proxy.NewProxy(opts) if err ! nil { log.Fatal(err) } p.AddAddon(myAddon) // 注册Addon log.Println(代理服务器启动在 :8080 自定义Addon已加载...) log.Fatal(p.Start()) }运行这个Addon程序go run my_addon.go现在所有经过代理的流量都会应用你定义的规则User-Agent被修改并且所有访问过的URL都会被记录到visited_urls.log文件中。你可以基于这个模式开发出非常强大的插件例如自动修改响应将特定API的返回JSON中的某个字段替换为测试值。流量镜像将线上流量复制一份发送到测试环境用于压测或问题复现。性能统计统计每个请求的耗时绘制性能图表。敏感信息过滤自动脱敏日志中出现的密码、Token等信息。5. 高级应用场景与避坑指南掌握了基本用法后我们来看看如何将 go-mitmproxy 应用到更复杂的场景中以及如何避开那些常见的“坑”。5.1 场景一移动端App抓包这是最常见的需求之一。步骤比桌面浏览器稍复杂确保电脑和手机在同一局域网连接同一个Wi-Fi。查找电脑的局域网IP。在macOS/Linux上运行ifconfig在Windows上运行ipconfig找到类似192.168.1.100的地址。启动 go-mitmproxy并绑定到局域网IPgo-mitmproxy -addr 192.168.1.100:8080 -web_addr :8081将192.168.1.100替换为你的电脑IP在手机上配置代理iOS 设置 - 无线局域网 - 点击当前Wi-Fi旁的 (i) - 配置代理 - 手动服务器填电脑IP端口填8080。Android 设置 - WLAN - 长按当前网络 - 修改网络 - 高级选项 - 代理 - 手动同上。在手机浏览器中安装CA证书用手机浏览器访问http://mitm.it。这是一个由 mitmproxy 家族工具提供的特殊页面能自动检测设备并给出证书安装指引。根据页面提示如“iPhone/Android”下载并安装证书。对于Android 7 和 iOS安装后还需额外步骤Android 进入 设置 - 安全 - 加密与凭据 - 安装的证书找到 mitmproxy 证书点击进入并启用。iOS 进入 设置 - 通用 - 关于本机 - 证书信任设置找到 mitmproxy 的根证书并开启完全信任。现在手机上的App流量除了那些硬编码忽略系统代理或使用证书绑定的App就能被成功拦截了。避坑点很多现代App尤其是金融、社交类使用了SSL Pinning证书绑定技术。这意味着App在代码里写死了只信任特定的服务器证书或CA而拒绝我们安装的 mitmproxy CA证书。对付这种情况通常需要反编译App并修改代码或者使用Frida等动态插桩工具来绕过这超出了基础抓包的范围属于移动安全测试的领域。5.2 场景二集成到自动化测试如Python pytest你可以将 go-mitmproxy 作为子进程启动并在测试用例中直接通过其API或访问Web UI来断言流量。import subprocess import time import requests import pytest PROXY_HOST 127.0.0.1 PROXY_PORT 8080 PROXY_URL fhttp://{PROXY_HOST}:{PROXY_PORT} pytest.fixture(scopesession) def mitmproxy_server(): # 启动 go-mitmproxy 进程 proc subprocess.Popen([go-mitmproxy, -addr, f:{PROXY_PORT}], stdoutsubprocess.PIPE, stderrsubprocess.PIPE) time.sleep(2) # 等待服务器启动 yield # 测试结束后终止进程 proc.terminate() proc.wait() def test_api_call_with_proxy(mitmproxy_server): # 配置 requests 使用我们的代理 proxies { http: PROXY_URL, https: PROXY_URL, } # 发起一个测试请求 response requests.get(https://httpbin.org/json, proxiesproxies, verifyFalse) # verifyFalse 仅用于测试忽略证书警告 assert response.status_code 200 # 在这里你可以通过 go-mitmproxy 的 API如果开启或解析其输出来进行更复杂的断言 # 例如检查是否发出了特定请求或者响应中包含了特定字段。 # 一个简单的方法是启动时添加 -dump_dir 参数然后测试结束后去读取转储的文件进行分析。5.3 常见问题与排查技巧实录即使按照步骤操作你也可能会遇到一些问题。下面是我在实践中总结的常见问题及解决方法问题1浏览器访问HTTPS网站提示“您的连接不是私密连接”或“NET::ERR_CERT_AUTHORITY_INVALID”原因浏览器不信任 mitmproxy 的CA证书。解决确认证书已正确安装到系统的“受信任的根证书颁发机构”。重启浏览器。检查证书是否过期自签名证书通常有效期很长但也可检查。尝试在浏览器中直接访问http://mitm.it如果页面能打开并提示安装证书说明代理连通性没问题问题出在证书安装上。问题2手机App无法抓包没有流量显示原因A手机代理设置错误或电脑防火墙阻止了连接。排查在手机浏览器访问http://mitm.it如果打不开检查IP和端口并暂时关闭电脑防火墙测试。原因BApp使用了SSL Pinning。排查尝试抓包一个普通的网站如httpbin.org如果正常但目标App无流量则很可能是SSL Pinning。可以尝试用系统浏览器访问该App的域名如果能抓到则基本确认。问题3拦截到的响应体是乱码或显示binary data原因响应可能是gzip、br等压缩格式或者是图片、视频等二进制文件。解决在Web UI中查看响应头中的Content-Encoding。如果是gzipmitmproxy 通常会自动解压并显示明文。如果没有你可以尝试手动解码。对于二进制文件Web UI通常会提供十六进制Hex视图供查看。问题4go-mitmproxy 进程占用内存或CPU过高原因拦截了流量非常大的场景如视频流或者某个Addon处理逻辑效率低下。解决使用-stream_large_bodies参数设置一个阈值如5M超过此大小的文件将不会被载入内存而是流式传输显著降低内存消耗。检查自定义Addon的逻辑避免在流量处理函数中进行复杂的同步阻塞操作。使用过滤表达式只拦截你关心的特定域名或URL模式的流量。问题5某些网站或API请求失败返回奇怪的错误原因这些网站可能使用了高级的TLS特性或检测代理机制。解决尝试在启动命令中添加-ssl_insecure参数。检查 mitmproxy 的CA证书是否被某些安全软件如某些国产杀毒软件、电脑管家误删或拦截。这是一个已知限制mitmproxy 无法完美处理所有网站特别是那些使用非标准TLS栈或强化了反代理措施的网站。对于这类站点可能需要更专业的工具或方法。最后记住 mitmproxy 是一个强大的调试和测试工具但务必在合法和授权的范围内使用。不要用它来拦截你不拥有或未获得明确授权测试的网络流量。在你的开发、测试和安全评估环境中它绝对是一个能极大提升效率的利器。
返回列表