HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 代理技术全栈手册

    • 代理技术全栈手册 - HiHuo
    • 原理篇

      • 第01章 代理是什么:正向 / 反向 / 透明 / 隧道的统一模型
      • 第02章 代理与网络层级:L3 / L4 / L5 / L7 在哪里截断流量
      • 第03章 一个请求穿过代理的一生:连接生命周期全景
    • 协议篇

      • 第04章 HTTP 代理协议:绝对 URI、CONNECT 隧道、转发头与连接池
      • 第05章 HTTPS 与 TLS 代理:终止 / 透传 / MITM / SNI / mTLS
      • 第06章 SOCKS 协议:SOCKS4/4a/5 与 UDP ASSOCIATE 报文级解析
      • 第07章 HTTP/2、gRPC 与 HTTP/3(QUIC) 代理的挑战
      • 第08章 代理自动配置:PAC / WPAD / 系统代理 / NO_PROXY
    • 层级与转发篇

      • 第09章 L4 代理:TCP/UDP 转发与连接级负载均衡
      • 第10章 L7 代理:协议感知与基于内容的路由
      • 第11章 透明代理:iptables REDIRECT/DNAT、TPROXY 与 eBPF 劫持
      • 第12章 数据搬运的艺术:splice / sendfile / 零拷贝 / io_uring
    • 组件横评篇

      • 第13章 Nginx / OpenResty:反向代理、upstream 与 Lua 可编程
      • 第14章 HAProxy:L4/L7、ACL、健康检查与 stick table
      • 第15章 Envoy:xDS 动态配置与 filter chain,为何是云原生数据面
      • 第16章 Traefik / Caddy:自动服务发现与自动 HTTPS
      • 第17章 Squid 与正向/缓存代理:企业出网、缓存与审计
      • 第18章 mitmproxy:抓包、改包、脚本化调试
      • 第19章 内网穿透与隧道:frp / gost / SSH 隧道 / ngrok
      • 第20章 科学上网生态的技术原理(技术中立)
    • 多语言手写篇

      • 第21章 Go:100 行手写 HTTP/CONNECT + SOCKS5 代理
      • 第22章 Rust:基于 tokio 的高性能 TCP 代理
      • 第23章 Python:asyncio 实现,适合调试与脚本
      • 第24章 C:epoll 裸写与零拷贝,及语言选型对比
    • 容器与K8s篇

      • 第25章 Docker 里的代理:HTTP_PROXY、build/pull 与 daemon 配置
      • 第26章 Sidecar 与流量劫持:Istio init-container 的 iptables 原理
      • 第27章 Ingress 与南北流量:Ingress-nginx 与 Gateway API
      • 第28章 Egress 与出网治理:出口网关、registry mirror、审计
      • 第29章 Service Mesh 数据面:Envoy Sidecar 全链路
    • 进阶篇

      • 第30章 可编程代理:Lua / Wasm / eBPF / xDS,代理的"软件定义"
      • 第31章 性能调优:并发模型、连接池、超时与重试、压测
      • 第32章 排错决策树:502 / 504 / 握手失败 / 环路 / 泄漏
      • 第33章 代理安全:开放代理、SSRF、凭证泄漏与攻击面
    • 底层机制篇

      • 第34章 代理的背压与流控:一个代理最难的部分
      • 第35章 socket 与 TCP 状态机:半关闭、超时、连接生命周期
      • 第36章 HTTP/2 帧、流控与 HPACK:h2 代理的内部机制
      • 第37章 负载均衡算法推导与韧性状态机
      • 第38章 Capstone:把玩具代理改造成生产级骨架
    • 综合实战篇

      • 第39章 企业多跳转发链:拓扑、协议矩阵与贯穿性难题
      • 第40章 端到端实战:把 6 类流量全代理通
      • 第41章 更刁钻的流量:gRPC、长轮询、WebRTC、大文件、双向流
      • 第42章 可落地完整参考实现:一套能跑的多协议转发栈
    • 附录

      • 附录 A:代理协议报文速查(HTTP / SOCKS / PAC / PROXY protocol)
      • 附录 B:组件选型决策树
      • 附录 C:抓包与命令速查

第18章 mitmproxy:抓包、改包、脚本化调试

学习目标

  • 掌握 mitmproxy 三件套(mitmproxy/mitmweb/mitmdump)与五种工作模式
  • 用它拦截、查看、修改 HTTPS 明文流量,做 API 调试与移动端抓包
  • 用 Python addon 脚本化改包:自动改请求头、篡改响应、Mock
  • 理解它与 tcpdump 的分工:一个看应用层明文,一个看字节

前置知识

  • 第05章 HTTPS 与 TLS 代理(MITM 原理、CA 信任、HSTS/锁定)
  • 第04章 CONNECT、第17章 Squid SSL Bump(同为 MITM)

原理

定位:开发者的 HTTPS 调试神器

第17章 的 SSL Bump 是"企业审计"视角的 MITM;mitmproxy 是**"开发调试"视角的同一技术。它是一个交互式的中间人代理,让你能实时看到、修改、重放** HTTPS 流量——调 API、抓移动端、做安全测试的利器。

三件套

工具形态用途
mitmproxy终端 TUI交互式查看/拦截,键盘操作
mitmweb浏览器 Web UI可视化,适合不熟终端的人
mitmdump命令行(类 tcpdump)脚本化、自动化、CI

五种工作模式

regular(默认)  :标准正向代理,客户端配 proxy(第01章)
transparent     :透明代理,配 iptables 劫持(第11章)
reverse         :反向代理,固定转发到某后端(调试线上服务)
upstream        :串联到上游代理(代理链)
socks5          :作为 SOCKS5 代理(第06章)

MITM 原理回顾(来自第05章)

mitmproxy 能看 HTTPS 明文,靠的是 第05章 的 MITM:

客户端 ──CONNECT example.com:443──▶ mitmproxy
        ◀── mitmproxy 用自己的 CA 现签一张 example.com 证书 ──
客户端 ══TLS(信任了 mitm CA)══▶ mitmproxy(解密看明文)══真TLS══▶ example.com

铁律:客户端必须信任 mitmproxy 的 CA(首次运行生成在 ~/.mitmproxy/)。不装 CA 就会证书报错——这正是 第05章 强调的 MITM 安全边界。HSTS 和证书锁定的 App 抓不到,是正常的安全机制。

脚本化:addon 的请求/响应钩子

mitmproxy 用 Python addon 在流量经过时插入逻辑——本质是给代理装"可编程 filter"(呼应 第30章):

# 几个核心钩子,按流量阶段触发
def request(flow):   # 请求即将发往服务器前
    ...
def response(flow):  # 响应从服务器返回后
    ...

flow.request / flow.response 可读可改——改头、改体、改状态码、Mock 整个响应,全在几行 Python 里。


️ 实现 / 命令

实验一:起 mitmproxy 看 HTTPS 明文

mitmproxy --listen-port 8080            # 启动 TUI

# 另一终端:装 CA 后走它(演示用)
curl -x http://127.0.0.1:8080 \
     --cacert ~/.mitmproxy/mitmproxy-ca-cert.pem \
     https://httpbin.org/get
# mitmproxy 界面里实时出现这条请求,按回车可看完整明文请求/响应

实验二:mitmdump 脚本自动改包

# addon.py —— 给所有请求加一个头,把响应里的 foo 替换成 bar
def request(flow):
    flow.request.headers["X-Debug"] = "mitm"          # 注入请求头

def response(flow):
    if flow.response.text:
        flow.response.text = flow.response.text.replace("foo", "bar")  # 篡改响应体
mitmdump -s addon.py --listen-port 8080
# 此后所有经过的请求被加头、响应被替换——可用于调试、Mock、注入测试

实验三:Mock 一个接口(不碰真后端)

# 拦截特定路径,直接返回伪造响应,根本不发往后端
from mitmproxy import http

def request(flow):
    if flow.request.path == "/api/user":
        flow.response = http.Response.make(
            200,
            b'{"id": 1, "name": "mock-user"}',
            {"Content-Type": "application/json"},
        )

前端联调时,后端还没好?用这招直接 Mock。

实验四:移动端抓包

# 1. 手机和电脑同一 WiFi;手机 WiFi 代理设为 电脑IP:8080
# 2. 手机浏览器访问 http://mit.it 下载并信任 mitmproxy CA
# 3. mitmweb 在电脑上可视化手机流量
mitmweb --listen-port 8080
# 注意:做了证书锁定的 App(银行/大厂)抓不到——锁定就是为防这个(第05章)

实验五:与 tcpdump 的分工

# tcpdump:看字节流(TLS 是密文,看不懂应用层)
sudo tcpdump -i any -n 'tcp port 443'        # 只能看到加密字节

# mitmproxy:看应用层明文(解密后的 HTTP)
mitmproxy --listen-port 8080                 # 看到完整 URL/头/体

分工:排查"连不连得通、握手对不对" → tcpdump(第01章 起就在用);排查"请求内容对不对" → mitmproxy。 两者互补。


排错

现象根因解决
certificate problem客户端没信任 mitm CA装 ~/.mitmproxy/mitmproxy-ca-cert.pem
App 流量抓不到证书锁定(第05章)锁定无法绕过;用 debug 构建/越狱环境
HSTS 站点失败浏览器对 HSTS 拒绝异常证书设计如此
HTTP/2 流量异常个别老配置 h2 支持问题升级 mitmproxy,或强制 h1
透明模式不拦截没配 iptables/--mode transparent参考 第11章
改了响应体长度对不上没更新 Content-Length改 flow.response.text 时框架会自动算长度,改 raw 要手动

本章小结

  • mitmproxy 三件套:mitmproxy(TUI) / mitmweb(Web) / mitmdump(脚本),五模式(regular/transparent/reverse/upstream/socks5)。
  • 它是"开发调试视角"的 MITM,原理同 第05章:动态签证书 + 客户端信任 CA;HSTS/锁定可反制。
  • Python addon 用 request/response 钩子脚本化改包、Mock,是可编程代理的轻量形态。
  • 与 tcpdump 分工:tcpdump 看字节/握手,mitmproxy 看应用层明文/内容。

下一章 第19章 内网穿透与隧道,换个问题:内网服务没有公网 IP,如何让外部访问?frp、gost、SSH 反向隧道、ngrok 各显神通。

Prev
第17章 Squid 与正向/缓存代理:企业出网、缓存与审计
Next
第19章 内网穿透与隧道:frp / gost / SSH 隧道 / ngrok