mitmproxy:交互式 TLS 拦截代理三件套(mitmproxy / mitmdump / mitmweb)详解
mitmproxy 是一款面向渗透测试者与软件开发者的交互式、支持 SSL/TLS 的拦截代理(intercepting proxy),可捕获 HTTP/1、HTTP/2 与 WebSocket 流量。它通过 mitmproxy(交互式控制台界面)、mitmdump(命令行非交互版本,常被形容为“HTTP 界的 tcpdump”)、mitmweb(浏览器 Web 界面)三个工具入口交付同一套核心能力。本文以仓库根目录 README.md 为主线,结合 pyproject.toml、入口源码 mitmproxy/tools/main.py 与 CONTRIBUTING.md,讲解这套工具的定位、安装运行方式、核心能力以及从源码出发的开发工作流。
项目定位:一个核心,三种形态
README 对项目的一句话定义是:
mitmproxyis an interactive, SSL/TLS-capable intercepting proxy with a console interface for HTTP/1, HTTP/2, and WebSockets.
其下的三个可执行程序各有分工:
mitmproxy:交互式命令行界面(TUI),适合逐条查看、编辑、重放流量;mitmdump:命令行版本,“Think tcpdump for HTTP”,适合脚本化抓取、日志输出与自动化;mitmweb:基于 Web 的图形界面,适合在浏览器中检视与修改请求/响应。
三者并非独立实现,而是共享同一个核心库 mitmproxy,区别仅在于前端 Master 类型。从入口文件 mitmproxy/tools/main.py 可以看到,三个函数分别装配不同的 Master 并复用同一个 run() 启动流程:
def mitmproxy(args=None):
from mitmproxy.tools import console
run(console.master.ConsoleMaster, cmdline.mitmproxy, args)
def mitmdump(args=None):
from mitmproxy.tools import dump
run(dump.DumpMaster, cmdline.mitmdump, args, extra)
def mitmweb(args=None):
from mitmproxy.tools import web
run(web.master.WebMaster, cmdline.mitmweb, args)
这三个入口的命令行声明位于 pyproject.toml 的 [project.scripts] 段:
[project.scripts]
mitmproxy = "mitmproxy.tools.main:mitmproxy"
mitmdump = "mitmproxy.tools.main:mitmdump"
mitmweb = "mitmproxy.tools.main:mitmweb"
也就是说,安装 mitmproxy 包后,这三个命令即可在终端直接使用。
安装与运行环境
README 将安装细节指向官方文档站点,在本仓库中对应的在线文档源文件位于 docs/src/content/overview/installation.md。就当前仓库源码而言,运行环境的硬约束记录在 pyproject.toml 中:
- Python 版本:
requires-python = ">=3.12",classifiers 进一步声明支持 3.12 / 3.13 / 3.14(仅 CPython); - 操作系统:macOS、POSIX(Linux)、Windows 均在声明范围内,对应 mitmproxy/platform/ 下
linux.py、osx.py、windows.py、openbsd.py等平台适配模块; - 核心依赖(节选自
[project] dependencies,均带上下界约束):- TLS/网络栈:
pyOpenSSL、cryptography、aioquic(QUIC/HTTP3)、h11+h2(HTTP/1 与 HTTP/2 解析)、wsproto(WebSocket); - 界面:
urwid(console TUI)、flask(mitmweb 后端); - 压缩与内容处理:
Brotli、zstandard、kaitaistruct(二进制格式解析)、pyparsing; - 其他:
certifi(CA 证书包)、ldap3(上游代理认证)、tornado等。
- TLS/网络栈:
当前仓库的版本信息定义在 mitmproxy/version.py:
VERSION = "13.0.0.dev"
MITMPROXY = "mitmproxy " + VERSION
# Serialization format version. ...
FLOW_FORMAT_VERSION = 21
其中 FLOW_FORMAT_VERSION 是 .mitm 流量序列化文件格式的版本号——每次文件格式变更时递增,这解释了仓库测试数据目录 test/mitmproxy/data/flows/ 中大量 .mitm 存档文件的来历。版本字符串还支持通过 git describe 动态附加提交距离与哈希(见 get_dev_version()),并识别 PyInstaller 打包的二进制版本。
适用前提:从源码直接运行 mitmproxy 需要 Python 3.12 及以上;依赖
pydivert的透明模式(transparent mode)仅支持 Windows(见依赖声明中的sys_platform == 'win32'标记)。
启动流程剖析:一个 run() 如何拉起三种工具
理解三个工具的共同启动链路,有助于快速定位参数与配置问题。mitmproxy/tools/main.py 中的 run() 是整个入口的核心:
- 日志降噪:将
tornado、asyncio、hpack、quic等第三方日志级别压到 WARNING,只保留自身调试信息; - 构造 Options 与 Master:
opts = options.Options(),再master_cls(opts)——console/dump/web 的差异从这里分叉; - 命令行解析:
make_parser(opts)生成 argparse 解析器,命令行参数与选项系统(options模块)一一对应; - 配置文件加载:依次尝试
<confdir>/config.yaml与<confdir>/config.yml(optmanager.load_paths),允许以 YAML 文件固化选项; - 参数覆盖:
process_options()把命令行中非 None 的解析结果覆盖进 Options;--verbose会同时把日志级别调到 debug、flow_detail调到 2,而--quiet则压到 error 级别; - 特殊子命令:
--options打印全部选项及默认值(会先加载脚本以注册脚本注册的自定义选项),--commands打印全部可用控制台命令;-v打印系统诊断信息后退出; - 信号处理:注册 SIGINT/SIGTERM 优雅关闭(在支持
loop.add_signal_handler的平台使用事件循环处理器,Windows Proactor 环境回退到signal.signal); - 进入事件循环:
await master.run()开始代理工作。
一个实用技巧:mitmdump 支持在末尾追加过滤表达式(如 mitmdump "q: example.com")。从 mitmproxy/tools/main.py 的 extra 回调可以看到,该过滤器会被同时写入 save_stream_filter、readfile_filter、dumper_filter 三个内部选项,从而只对匹配的流量做保存、读取与终端打印——这与 docs/src/content/concepts/filters.md 描述的过滤表达式语法相呼应。
核心能力:流量拦截之外的“内置武器库”
README 将详细特性指向官方文档,这些特性在仓库中对应 docs/src/content/overview/features.md 与 mitmproxy/addons/ 目录下一系列内置插件。以下按文档脉络梳理,并标注对应源码,便于深入阅读。
Anticache(反缓存)
设置 anticache 选项后,mitmproxy 会移除请求头中的 if-none-match 与 if-modified-since,防止服务器返回 304 Not Modified,确保捕获到完整的 HTTP 交互。常用于客户端重放(client-side replay)场景。实现见 mitmproxy/addons/anticache.py。
Blocklist(黑名单拦截)
block_list 选项的条目格式为:
/flow-filter/status-code
- flow-filter:可选的 mitmproxy 过滤表达式,描述要拦截的请求;
- status-code:拦截时返回的 HTTP 状态码;特殊值
444表示直接“挂断”、不发送任何响应。
文档给出的示例:
| 模式 | 说明 |
|---|---|
:~d google-analytics.com:404 |
拦截所有到 google-analytics.com 的请求,返回 404 |
:~d example.com$:444 |
拦截所有到 example.com 的请求,不发送任何 HTTP 响应 |
:!~d ^example\.com$:403 |
仅放行 example.com 的 HTTP 请求(文档提示:这不构成对主动攻击者的安全防护) |
Map Local(本地资源映射)
map_local 将请求 URL 重定向到本地文件或目录,条目格式:
|url-regex|local-path
|flow-filter|url-regex|local-path
- 若 local-path 是文件,则始终直接提供该文件,无缓存;
- 若是目录,用 url-regex 把请求 URL 切成两段,右段(去除 query string)拼接到目录后;若正则含捕获组,则改用第一个捕获组拼接且不去除 query;
- 找不到文件时尝试追加
/index.html,仍失败则返回 404;目录遍历被限制在指定目录内。
文档中的典型示例(分隔符可任意,取首个字符):
| 模式 | 说明 |
|---|---|
|example.com/main.js|~/main-local.js |
用本地 ~/main-local.js 替换 example.com/main.js |
|example.com/static|~/static |
example.com/static/foo/bar.css → ~/static/foo/bar.css |
|~m GET|example.com/static|~/static |
同上,但仅对 GET 请求生效 |
对应实现为 mitmproxy/addons/maplocal.py。仓库示例 examples/addons/internet-in-mirror.py 展示了用脚本方式做更灵活的资源替换。
Map Remote(远端 URL 替换)
map_remote 在请求发往服务器前替换 URL 中的片段,条目格式:
|url-regex|replacement
|flow-filter|url-regex|replacement
例如把所有 .jpg 请求映射到一张固定图片,或把 example.org 的 GET 请求改写到另一个域名。实现见 mitmproxy/addons/mapremote.py。
Modify Body / Modify Headers(内容修改)
两个选项都以“过滤表达式 + 正则 + 替换串”为核心,替换串以 @ 开头时视为从文件读取内容。
modify_body 条目格式:
/flow-filter/body-regex/replacement
/body-regex/@file-path
示例:
/~q/foo/bar # 将所有请求体中的 foo 替换为 bar
:~q:foo:@~/xss-exploit # 替换内容为文件 ~/xss-exploit 的数据(示例中经 mitmdump --modify-body 传入)
modify_headers 条目格式:
/flow-filter/name/value
/name/@file-path
示例:
/~q/Host/example.org # 所有请求的 Host 头改为 example.org(覆盖已有值)
/~q & !~h Host:/Host/example.org # 仅当请求原本没有 Host 头时设置
/~q/User-Agent/@~/useragent.txt # User-Agent 取自文件内容
/~q/Host/ # 空 value 表示删除现有 Host 头
关键语义:modify 钩子在客户端请求与服务器响应到达时都会触发,但只作用于匹配的那一侧(响应钩子不会改动请求对象);对流式(streamed)body 不生效。实现见 mitmproxy/addons/modifybody.py 与 mitmproxy/addons/modifyheaders.py,相关测试在 test/mitmproxy/addons/test_modifybody.py、test/mitmproxy/addons/test_modifyheaders.py。
重放(Replay)、Sticky 会话与流式传输
- Client-side replay:提供一份已保存的 HTTP 会话,mitmproxy 逐条重放客户端请求;注意请求是串行发送的(等上一个响应再发下一个),与录制时的并发行为可能不同。建议配合
anticache使用。 - Server-side replay:把保存的服务器响应重放给新请求,按 URL + 方法等启发式匹配(默认忽略请求头,因此换 User-Agent 也能匹配上);
server_replay_refresh选项(默认开启)会按录制时的相对时间偏移刷新date、expires、last-modified头与 Cookie 过期时间,避免过期 Cookie 导致异常行为。 - Sticky auth / Sticky cookies:
stickyauth会把已见过的Authorization头自动重放到后续请求(当前支持 Basic 认证,不支持 Digest 重放);stickycookie把服务器最近设置的 Cookie 自动附加到无 Cookie 的请求上,典型用法是先正常登录一次,之后用 curl/wget 等工具直接访问受保护资源。 - Streaming:默认情况下 mitmproxy 会完整缓冲请求/响应后再转发与修改;开启流式后(
stream_large_bodies指定大小阈值,或用脚本把消息的.stream属性设为True)body 直通转发、不再可被代理访问,body 修改类选项随之失效,但 HTTP 头仍完整缓冲。
这些插件的实现集中在 mitmproxy/addons/ 目录:clientplayback.py、serverplayback.py、stickyauth.py、stickycookie.py 等,可对照 examples/addons/duplicate-modify-replay.py 等示例脚本理解“拦截—修改—重放”的组合拳。
从零开发:源码工作流
README 的 “Contributing” 一节指向 CONTRIBUTING.md,其中给出了完整的开发环境与测试流程。
从源码启动(uv 工作流)
git clone https://github.com/mitmproxy/mitmproxy.git
cd mitmproxy
uv run mitmproxy --version
uv run 会在 mitmproxy/.venv 中透明地创建虚拟环境并安装全部依赖。之后可以两种方式执行命令:
- Linux / macOS:
source .venv/bin/activate后直接mitmdump --version; - Windows:
.venv\Scripts\activate后直接执行。
测试与代码风格
- 完整测试套件:
uv run tox; - 针对单个模块快速回归(示例直接来自 CONTRIBUTING.md):
cd test/mitmproxy/addons
uv run pytest --cov mitmproxy.addons.anticache --cov-report term-missing --looponfail test_anticache.py
项目追求 100% 测试覆盖率并对部分代码严格强制,CI 的额外 tox 环境定义在 pyproject.toml 中(pytest 配置采用 asyncio_mode = "auto",测试根目录为 test,其中 test/mitmproxy/ 按源码模块一一对应组织测试文件)。
- Lint 检查(PR 强制,失败会阻塞合并):
uv run tox -e lint。
仓库内其他值得关注的配套目录:release/(PyInstaller 打包 spec、Docker 构建、Windows 安装包)、test/bench/(基准测试)、docs/(Hugo 站点源码,含教程与截图录制脚本 docs/scripts/clirecording/)。
文档与社区资源
README 指引使用者到官方站点查阅教程与预编译二进制,而文档源文件就在仓库内,可作为“一手资料”直接阅读:
- docs/src/content/overview/:安装(installation.md)、快速上手(getting-started.md)、特性总览(features.md);
- docs/src/content/concepts/:核心概念——how-mitmproxy-works.md(工作原理)、modes.md(代理模式)、certificates.md(CA 证书与 TLS)、filters.md(过滤表达式)、options.md(选项参考)、protocols.md(协议支持);
- docs/src/content/tutorials/ 与 docs/src/content/cli-tutorials/:面向 mitmproxy/mitmdump 的操作教程;
- docs/src/content/addons-api.md 与 docs/src/content/api/:插件(addon)API 参考,配合 docs/src/examples/addons/ 中 30 个示例脚本阅读;
- examples/addons/ 与 examples/contrib/:仓库内置的完整可运行示例与社区贡献脚本(DNS 欺骗、SSL pinning 检查、上游代理切换、HTTP/2 透传等)。
仓库结构速览
从源码组织可以快速建立全局认知(均以仓库根目录为起点):
- mitmproxy/coretypes/:基础类型(
Serializable、multidict等,是流量对象序列化的基础); - mitmproxy/net/:协议栈——
http/(HTTP 模型、Cookie、Headers)、dns/、tls.py、server_spec.py(如tcp:127.0.0.1:8080、reverse:等模式规范解析); - mitmproxy/proxy/:代理核心——
server.py、layer.py(分层协议处理)、layers/http/(客户端/服务器侧 HTTP 层)、layers/quic/(QUIC/HTTP3); - mitmproxy/addons/:上文所列全部内置功能插件;
- mitmproxy/tools/:三个前端——
console/(urwid TUI)、web/(Flask + 前端资源)、dump.py; - mitmproxy/contentviews/:JSON、CSS、JavaScript、Multipart、GraphQL、MQTT、WBXML 等内容的可读化视图(TUI 与 Web 界面共用);
- mitmproxy/io/:
.mitm存档与 HAR 的读写; - web/:mitmweb 前端源码(TypeScript/React,独立构建)。
小结
- mitmproxy 以“一个核心库 + 三个入口(mitmproxy/mitmdump/mitmweb)”交付交互式 TLS 拦截代理,入口装配逻辑集中在 mitmproxy/tools/main.py;
- 当前仓库要求 Python ≥ 3.12,版本为 13.0.0.dev,流量存档格式版本 21(见 mitmproxy/version.py);
- 核心功能(anticache、block_list、map_local/map_remote、modify_body/modify_headers、replay、sticky 会话、streaming)以 addon 插件形式实现,文档与 docs/src/content/overview/features.md、mitmproxy/addons/ 源码一一对应;
- 开发工作流以
uv+tox为核心(CONTRIBUTING.md),测试与源码目录同构,覆盖率与 lint 均有 CI 强制约束。
按上述路径,你可以从 uv run mitmdump --version 验证安装,用 mitmdump --options 查看全部选项,再顺着 addons 源码与 examples 脚本把“拦截—查看—修改—重放”的完整链路跑通。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00