Mitmproxy 11: 一款兼具性能与温度的代理软件,全面支持 HTTP/3

文摘   2024-10-05 16:31   江苏  

Mitmproxy 11: 一款兼具性能与温度的代理软件,全面支持 HTTP/3

引言

在技术迅猛发展的当下,网络工具的重要性日益凸显。Mitmproxy,作为一款能够拦截、检查、修改和重放广泛网络流量的工具,其开发和改进对于网络安全和数据隐私至关重要。

HTTP/3

现今,HTTP/3 在反向代理中实现了“即插即用”。您的 mitmproxy 实例将监听 TCP 和 UDP 数据包,并处理所有投向它的 HTTP 版本:

$ mitmproxy --mode reverse:https://http3.is

我们的透明代理模式现在也都支持 HTTP/3:

$ mitmproxy --mode wireguard
$ mitmproxy --mode local
$ mitmproxy --mode transparent

我们已经成功地与 Firefox、Chrome、各种 cURL 构建版本和其他客户端测试了 HTTP/3 支持,以解决兼容性问题。

目前我们所知的唯一主要限制是 Chrome 不信任用户添加的 QUIC 证书颁发机构。这意味着您需要提供公开信任的证书(例如 Let’s Encrypt 提供的),使用命令行开关启动 Chrome,或者接受它回落到 HTTP/2。Firefox 则没有这样的限制。有关更多 HTTP/3 故障排除提示,您可以查看 #7025。

将 HTTP/3 支持引入 mitmproxy 是一项从 2022 年开始的重大努力,由 Manuel Meitinger 和 Maximilian Hils 启动。随着 QUIC 和 HTTP/3 在野外的网络流量中占比越来越大,我们非常兴奋现在默认启用了这项功能!

改进的 DNS 支持

随着 DNS HTTPS 记录的出现和新的隐私增强功能,例如加密客户端 Hello(ECH),mitmproxy 的 DNS 功能变得越来越重要。我们很高兴在此分享多项进步:

支持 A/AAAA 之外的查询类型

mitmproxy 的旧 DNS 实现使用 getaddrinfo 解析查询。这很方便,因为 libc 会处理一切,但 getaddrinfo API 只支持 IPv4 和 IPv6 地址的 A/AAAA 查询。它不允许我们回答例如 HTTPS 记录的查询,这些记录用于表示 HTTP/3 支持。

为了克服这个限制,我们在 Hickory DNS 上重新实现了我们的 DNS 支持,这是一个基于 Rust 的 DNS 库。使用 Hickory,我们现在可以在 Windows、Linux 和 macOS 上获取操作系统的默认名称服务器,并将非 A/AAAA 查询转发到这些服务器。这种行为也可以通过新的 dns_name_servers 选项进行定制:

$ mitmdump --mode dns --set dns_name_servers=8.8.8.8

跳过 /etc/hosts

通过切换到 Hickory,我们现在还有选项忽略系统的 hosts 文件(Linux 上的 /etc/hosts),使用新的 dns_use_hosts_file 选项。我们计划也将 mitmproxy 的内部 DNS 解析迁移到 Hickory,届时此功能将非常有用,允许在同一台机器上对特定域名进行透明重定向。目前,这样的设置会导致 mitmproxy 递归地连接到自身,因为我们总是考虑 hosts 文件。

$ echo "192.0.2.1 mitmproxy.org" >> /etc/hosts

$
 mitmdump --mode dns
$ dig @127.0.0.1 +short mitmproxy.org
192.0.2.1

$
 mitmdump --mode dns --set dns_use_hosts_file=false
$ dig @127.0.0.1 +short mitmproxy.org
3.161.82.13

支持 DNS-over-TCP

DNS 默认使用 UDP,但也可能使用 TCP 来支持单个 UDP 数据包无法容纳的记录。mitmproxy 以前只支持 UDP,但现在我们支持任意查询类型,消息大小因此 TCP 支持变得更加重要。长话短说,DNS-over-TCP 现在可以在 mitmproxy 11 中使用!

剥离加密客户端 Hello (ECH) 密钥

除非配置了自定义证书,否则 mitmproxy 使用在 TLS 客户端 Hello 中传输的服务器名称指示(SNI)来构建有效证书。相反,如果没有 SNI,我们可能无法生成客户端信任的证书。

加密客户端 Hello(ECH)是一项提高 Web 隐私的激动人心的新技术。简而言之,客户端使用新的 DNS HTTPS 记录在建立连接之前获取 ECH 密钥,然后使用该密钥加密初始的客户端 Hello 握手消息。如果 DNS 查询和握手都被加密,被动中间人无法了解目标域名,只能了解目标 IP 地址(对于共享托管和内容分发网络来说,这并不具有决定性)。这对隐私来说是一个巨大的进步,但也破坏了 mitmproxy 生成证书的方式。

为了解决这个问题,mitmproxy 现在从 HTTPS 记录中剥离 ECH 密钥。这样客户端就没有密钥来加密初始的握手消息,mitmproxy 仍然可以了解目标域名并构建匹配的证书。

当然,ECH 为我们增加了复杂性,有时也会使 mitmproxy 更难使用。尽管如此,我们仍然对为 Web 的其余部分所做的这些隐私进步感到兴奋!

致谢

这项工作得到了 Google Summer of Code 的支持,属于 Honeynet 项目,并由 NLnet 建立的 NGI0 Entrust 基金资助。感谢我的导师 Maximilian Hils 提供的宝贵指导和支持。

下面是最终的报告部分

在这个充满挑战与机遇的时代,开源社区正成为技术创新和知识共享的温床。在这样的背景下,Google Summer of Code(GSoC)项目不仅为学生提供了一个展示才华的平台,更为他们打开了一扇通往广阔技术世界的大门。今天,我们有幸分享 Gaurav Jain 的故事,他作为 The Honeynet Project 的一员,在 mitmproxy 项目中留下了自己的足迹。

Gaurav 的旅程是一段关于成长、探索和坚持不懈的故事。在导师 Maximilian Hils 和 Emanuele Micheletti 的悉心指导下,他不仅在技术领域取得了显著的进步,更在解决问题的过程中学会了坚持和耐心。他所面临的挑战,从异步编程的复杂性到时间管理的考验,都是成长的催化剂,使他变得更加坚韧和自信。

在这篇最终报告中,我们将一起回顾 Gaurav 在改进 mitmproxy DNS 和 HTTP3 支持方面的努力和成就。这不仅是对他个人努力的肯定,也是对开源精神的一次赞颂。让我们一同走进 Gaurav 的世界,感受他在这个夏天所经历的风风雨雨,以及他为开源社区带来的温暖和光亮。

GSoC 最终报告


项目:改进 mitmproxy 中的 DNS 和 HTTP3 支持
贡献者:Gaurav Jain
组织:The Honeynet Project
导师:Maximilian Hils, Emanuele Micheletti

项目概述

mitmproxy 是一个出色的工具,可以拦截、检查、修改和重放包括 SSL/TLS 保护协议在内的广泛网络流量。它可以用于调试、测试、隐私测量和渗透测试。该工具主要基于 Python、Rust 和 TypeScript。本项目的目标是调试和修复 DNS 和 HTTP3 模式中的许多缺失/破损部分。

完成的任务

DNS

  • 剥离 DNS HTTPS 记录,以防止客户端发送加密的客户端 Hello (ECH) 消息

    • 第一步 - 完全阻止 HTTPS 记录:链接[1]
    • 解析 HTTPS 记录:链接[2]
    • 更新插件以解析 HTTPS 记录并单独剥离 ECH 值:链接[3]
    • 使用现有 API 解析 HTTPS 记录中的域名,以减少代码复用:链接[4]
  • 添加对 DNS 过 TCP 流的支持

    • 使 mitmproxy 在 DNS 模式下监听 TCP 端口:链接[5]
    • 解析 DNS 过 TCP 消息:链接[6]
  • 在 DNS 模式下支持代理所有查询类型

    • 使用 Rust 的 hickory_resolver 进行查找和提取系统名称服务器:链接[7], 链接[8]
    • 使用 Rust API 进行需要检查 hosts 文件的查找,将其他请求转发到选项中指定的服务器,从而支持所有 DNS 查询类型:链接[9]
    • 修复启动时如果 mitmproxy 无法确定操作系统的 DNS 服务器则会崩溃的错误:链接[10]
  • 修复 DNS 消息解析问题,其中压缩指针未正确处理

    • 问题:链接[11]

    • 修复:链接[12], 链接[13]

HTTP3

  • 调试和记录与 HTTP3 相关的现有问题:链接[14]
  • 处理分段的 QUIC 客户端 Hello:链接[15]
  • 添加插件以更新反向代理模式中 alt-svc HTTP 头部的目标主机:链接[16]
  • 在 HTTPS 反向代理模式中添加 HTTP3 支持:链接[17]

其他

  • 添加 HttpConnectedHookHttpConnectErrorHook链接[18]
  • 允许 typing.Sequence[str] 成为可编辑选项:链接[19]
  • 处理远程主机关闭 UDP 套接字时的错误:链接[20]
    • 结果发现是 Rust 的标准库问题:链接[21]
  • 为 UDP 套接字设置 IPV6_V6ONLY 标志:链接[22], 链接[23]

审查的 PR

  • 自动修正生成的 JS 文件,不要在测试中修补它们:链接[24]
  • 通过使用字节块列表优化 response/request_body_buf,避免连接开销:链接[25]
  • 防止 server_event 重入:链接[26]
  • 更新 next_layer 以检测 HTTP3 流:链接[27]
  • 更新 next_layer 以将 SSH 流检测为非 HTTP:链接[28]
  • 当用户指定无效证书时改善用户体验:链接[29]
  • QUIC:支持 STOP_SENDING 帧:链接[30]

未合并的工作

  • 加速 dns_resolver 的测试:链接[31]

当前状态

mitmproxy 现在支持

  • 在 DNS 流中代理所有查询类型
  • 代理 DNS 过 TCP 流
  • 从 HTTPS 类型 DNS 记录中剥离 ech
  • 代理压缩 DNS 记录
  • 基于 HTTP3 的反向代理和本地模式,尽管还有一些问题
  • 为基于 UDP 的服务器监听 IPv4 和 IPv6

下一步要解决的问题...

  • 服务器 QUIC 握手在 Windows 上的时间是 Linux 的 10 倍:链接[32]
  • 通过本地模式的 HTTP3 无法访问某些网站:链接[33]
  • 代理原始 QUIC 流:链接[34]
  • 处理暴露 HttpConnectErrorHook链接[35]

遇到的挑战

如果没有一路上遇到的所有令人沮丧的挑战,这段旅程就不会如此有回报。对我来说,项目中最困难和耗时的部分是调试问题。这通常涉及大量的无目的谷歌搜索和陷入无底洞。有时候即使花费了无数小时,也没有真正的进展。我要感谢我的导师在这里的耐心指导和引导我走向正确的方向。这个过程,我觉得极大地帮助我培养了“永不放弃”和“再努力一点”的态度来修复错误。

理解和编写带有 Python 绑定的异步 Rust 代码是我在项目中遇到的另一个困难。但从更积极的一面来看,我现在对 Rust 更有信心了,学到了很多新东西 - 从理解协议到编写异步代码。我在八月份开始上大学后也遇到了一些时间管理的困难。这些不同的事情真的开始影响我的睡眠时间表,但从另一方面来说,所有那些不眠之夜绝对是值得的。

结语

非常感谢 GSoC 和 The Honeynet Project 提供的这个绝佳机会,过去三个月将是我很长一段时间都会记得的事情。这次经历无疑极大地帮助我发展了我的技术和沟通技能,并让我更加热爱开源。我还要感谢我的导师 Maximilian Hils,他非常友好,并确保我在整个过程中有一个顺利愉快的体验。我希望将来也能继续活跃并为这个激动人心的开源世界做出贡献。


题外话

这个项目目前支持 CLI, WEB UI ,python API 三种方式调用,对于最新版本的 HTTPS 开发和测试代理需求来说,完全够用了,作者本身非常的谦逊,并且在解决问题的过程中,提高了掌控异步编程的实力,因此,做一件事的时候,可能当时没有回报,但是当你贡献出你的才能,你可能会在不久的将来收获更多。

参考资料
[1]

链接: https://github.com/mitmproxy/mitmproxy/pull/6876

[2]

链接: https://github.com/mitmproxy/mitmproxy/pull/6884

[3]

链接: https://github.com/mitmproxy/mitmproxy/pull/6905

[4]

链接: https://github.com/mitmproxy/mitmproxy/pull/6949/files

[5]

链接: https://github.com/mitmproxy/mitmproxy/pull/6912

[6]

链接: https://github.com/mitmproxy/mitmproxy/pull/6935

[7]

链接: https://github.com/mitmproxy/mitmproxy_rs/pull/148

[8]

链接: https://github.com/mitmproxy/mitmproxy_rs/pull/158

[9]

链接: https://github.com/mitmproxy/mitmproxy/pull/6975

[10]

链接: https://github.com/mitmproxy/mitmproxy/pull/7066/files

[11]

链接: https://github.com/mitmproxy/mitmproxy/issues/6936

[12]

链接: https://github.com/mitmproxy/mitmproxy/pull/6954

[13]

链接: https://github.com/mitmproxy/mitmproxy/pull/7022

[14]

链接: https://github.com/mitmproxy/mitmproxy/issues/7025

[15]

链接: https://github.com/mitmproxy/mitmproxy/pull/7067

[16]

链接: https://github.com/mitmproxy/mitmproxy/pull/7093

[17]

链接: https://github.com/mitmproxy/mitmproxy/pull/7114

[18]

链接: https://github.com/mitmproxy/mitmproxy/pull/6930

[19]

str]` 成为可编辑选项:[链接: https://github.com/mitmproxy/mitmproxy/pull/7001

[20]

链接: https://github.com/mitmproxy/mitmproxy_rs/pull/161

[21]

链接: https://github.com/rust-lang/rust/issues/128072

[22]

链接: https://github.com/mitmproxy/mitmproxy_rs/pull/167

[23]

链接: https://github.com/mitmproxy/mitmproxy/pull/7084

[24]

链接: https://github.com/mitmproxy/mitmproxy/pull/6910

[25]

链接: https://github.com/mitmproxy/mitmproxy/pull/6952

[26]

链接: https://github.com/mitmproxy/mitmproxy/pull/7031

[27]

链接: https://github.com/mitmproxy/mitmproxy/pull/7037

[28]

链接: https://github.com/mitmproxy/mitmproxy/pull/7041

[29]

链接: https://github.com/mitmproxy/mitmproxy/pull/7073

[30]

链接: https://github.com/mitmproxy/mitmproxy/pull/7119

[31]

链接: https://github.com/mitmproxy/mitmproxy/pull/7115

[32]

链接: https://github.com/mitmproxy/mitmproxy/issues/7033

[33]

链接: https://github.com/mitmproxy/mitmproxy/issues/7117

[34]

链接: https://github.com/mitmproxy/mitmproxy/issues/7038

[35]

链接: https://github.com/mitmproxy/mitmproxy/issues/7083


编程悟道
自制软件研发、软件商店,全栈,ARTS 、架构,模型,原生系统,后端(Node、React)以及跨平台技术(Flutter、RN).vue.js react.js next.js express koa hapi uniapp Astro
 最新文章