NaiveProxy(常写作 NaïveProxy)是一种以“复用 Chromium 网络栈”为核心思路的代理实现:客户端发出的外层流量,在 TLS 握手、HTTP/2 多路复用和常见前导行为上尽量贴近真实 Chrome 访问普通网站,而不是另造一套可被指纹化的私有协议外壳。它要对抗的不是“内容能否被读懂”,而是“这条连接像不像值得封锁的专用隧道”。

先分清:NaiveProxy 解决什么问题

把代理流量放在 443 端口、外面再包一层 TLS,并不等于不可识别。深度包检测仍可观察:

  • ClientHello 的密码套件、扩展集合与顺序(TLS 参数指纹);
  • 握手后包长、时序与上下行节奏;
  • 对可疑服务器的主动探测响应;
  • 长期连接是否呈现“代理会话”而不是“网页浏览”的统计特征。

NaiveProxy 的设计假设是:与其不断打磨一套自制 TLS/HTTP 实现去“模仿浏览器”,不如直接把 Chrome 已经在数十亿设备上跑过的网络栈拿来用。这样,指纹不是“仿出来的近似值”,而是与真实浏览器同源的实现产物。

官方仓库将这一思路概括为:用 Chromium 网络栈伪装流量,以获得较强的抗审查能力与较低的可探测性,同时继承 Chrome 在性能与安全上的既有实践。详见 klzgrad/naiveproxy

架构:不是“裸节点”,而是“网站前面的应用层路由”

典型路径可以写成:

本机应用 → Naive 客户端 → (审查网络) → 前端站点 → Naive 服务端 → 互联网

其中最关键的一跳是前端(frontend)。前端通常是 Caddy、HAProxy 这类常见反向代理:对外提供正常网站或至少表现得像正常 HTTPS 服务;对内根据 HTTP 层信息(尤其是 Authorization)把合法代理请求路由到 Naive 服务端,把其余请求交给普通站点逻辑。

官方称这种思路为 application fronting(应用层前置):代理隐藏在常用前端服务之后,用应用层路由区分“普通访客”和“持有凭据的代理客户端”。它与历史上的 domain fronting(域名前置)不同——后者依赖 CDN 对 SNI 与 Host 路由差异的特定行为,多数平台已限制;应用层前置则把“看起来像网站”和“如何把代理请求转走”明确交给你控制的前端配置。

因此,主动探测者如果只是对服务器发起未认证请求,更可能看到普通站点响应,而不是一个自报家门的代理错误码。抗主动探测的详细背景,可对照VPN 抗封锁技术演进

它具体削弱了哪些识别手段

根据项目说明,Chromium 网络栈与配套设计主要针对四类攻击面:

攻击面观察者在看什么NaiveProxy 的应对
TLS 参数指纹ClientHello 等握手字段组合直接复用 Chrome 网络栈,而不是手写“像 TLS 的东西”
网站指纹 / 流量分类会话结构、前导帧、流特征HTTP/2 多路复用,并模仿常见前导行为
主动探测未认证请求是否暴露代理身份前端站点 + 基于 Authorization 的应用层路由
基于长度的分析包长尖峰与握手长度模板填充与分片,压平常见初始握手的长度分布

这四条要合在一起理解。只解决 TLS 指纹、却在主动探测时返回独特错误,或只解决探测、却让包长分布长期呈代理模板,整体仍可能被分类。NaiveProxy 的价值在于把“浏览器外形 + 网站前置 + 长度扰动”绑成同一条链路。

HTTP/2 CONNECT:代理载荷如何藏进网页会话

NaiveProxy 通过 HTTP/2(也可使用 HTTP/3)的 CONNECT 隧道承载双向字节流。对中间观察者而言,外层是一次 HTTPS 会话;对端点而言,CONNECT 建立后,里面跑的是代理转发的上下行数据。

客户端配置上,常见形态是本地提供 SOCKS 入口,再把流量经 https://user:[email protected] 送到前端;在部分环境下也可尝试 quic://...,把外层换成基于 QUIC 的 HTTP/3 路径。选择 HTTP/2 还是 HTTP/3,往往取决于当地网络对 UDP 的限制、延迟表现和稳定性,而不是“哪一个名字更新”。

需要强调:CONNECT over TLS 本身不是 NaiveProxy 的发明。许多 HTTPS 代理都这么做。NaiveProxy 的差异在于:外层栈来自 Chromium,并增加了与前端、填充协议的配合,使“代理 CONNECT”在指纹和长度上更接近真实浏览器行为。

填充协议:为什么前几个读写特别重要

长度分析常盯住连接建立后的前几轮包:TLS 握手、HTTP/2 魔数与 SETTINGS、首个 HEADERS、窗口更新等,都会在统计上形成尖峰。NaiveProxy 用一套非正式但明确的填充约定来压这些尖峰。

其要点可以概括为:

  1. 载荷填充:每个双向流建立后,前 kFirstPaddings(8)次读写使用带长度头的填充格式;填充字节数在 0–255 间均匀随机。之后为降低开销不再填充,因为后续长度信息通常不如开局阶段“好用”。
  2. HEADERS 填充:CONNECT 请求/响应本身偏短、偏罕见。通过添加伪随机的 padding 头,把帧长拉近真实浏览器 HEADERS 的常见范围。
  3. RST_STREAM 相关处理:实验中 NaiveProxy 可能发送偏多的 RST_STREAM。设计上会在其前附加一段填充后的 END_STREAM DATA,使外观更接近普通浏览器结束流的方式。
  4. 能力协商:双方通过 CONNECT 请求/响应中是否存在 padding 头,判断对端是否支持该填充协议;从而保持与普通 HTTP/2 代理或普通客户端的互操作空间。

项目文档对设计哲学写得很直白:宁可选择开销低、易实现、可快速更替的方案,也不把抗审查压在单一“精巧但稀有”的协议上——因为审查研究面对的是大规模、可消耗的实现多样性,而不只是某一个完美算法。

为什么必须跟着 Chrome 升级

Chrome 的 TLS 行为会变。例如扩展顺序随机化会改变传统 JA3 一类指纹的稳定性;HTTP/2、QUIC、证书校验路径也会随版本演进。NaiveProxy 既然把“与 Chrome 同款签名”当作核心资产,客户端就需要持续跟踪 Chromium,而不是长期冻结在某个旧版本。

官方明确建议:始终使用最新版本,以保持签名与 Chrome 一致。 对下游打包者,也不应盲目跟踪会不断 rebase 的 master,而应使用稳定 release 与对应 tag。

这带来一个实际运维结论:NaiveProxy 的安全更新成本,不只是修漏洞,更是“维持伪装同步”。版本滞后的节点/客户端,可能重新变成“差一点的假 Chrome”,而差一点往往比完全不像更容易被模型盯上。

和其他常见方案怎么比

把 NaiveProxy 放进常见协议光谱里,边界会更清楚:

方案外层外形抗指纹思路典型代价
原生 WireGuard / OpenVPN专用隧道基本不做浏览器伪装实现简单,但协议特征明显
Trojan / 普通 TLS 代理HTTPS借用 TLS,实现多为自研栈易部署,但 ClientHello 等仍可能偏离浏览器
Reality 类接近真实 TLS 会话借用真实站点证书/握手上下文,强调抗主动探测重点在探测与证书语义,不等于完整浏览器栈
NaiveProxyChrome ↔ 常规前端同源网络栈 + 应用层前置 + 填充二进制与更新绑定 Chromium,资源占用更高

没有一种方案在所有维度同时最优。NaiveProxy 更擅长“TLS/HTTP 行为像真浏览器,并且前面还有一个可对外服务的网站”;在高丢包链路上追求极致吞吐时,基于自定义拥塞控制的 QUIC 类方案有时更有优势;在企业标准远程接入场景,IPsec/WireGuard 仍然更常见。协议选择应回到网络环境、设备资源和威胁模型,而不是名字新旧。

代价与不适用场景

复用 Chromium 不是免费午餐:

  • 体积与内存:即使项目已大幅裁剪构建,客户端仍比轻量代理重;
  • 更新频率:要追随 Chrome 签名,发布节奏更紧;
  • 运维复杂度:需要靠谱的前端站点、证书、鉴权与日志策略;前端若本身被标记,协议优势会被地址信誉抵消;
  • 性能特征:填充和 HTTP/2 封装有开销;是否适合大流量、低延迟场景,取决于具体路径与参数,不能从“抗审查强”直接推导“一定更快”;
  • 不是隐身斗篷:出口 IP、SNI/域名、证书历史、用户规模与长期流量形态仍可被关联分析。

另外,NaiveProxy 解决的是传输外形问题,不自动解决 DNS 泄漏、IPv6 旁路或应用层指纹。设备侧仍需配合合理的接管方式(例如系统代理或 TUN 全局代理)和完整的双栈/DNS 配置。

理解它的正确方式

把 NaiveProxy 记成三句话即可:

  1. 它首先是一套“Chrome 同款网络栈上的 HTTPS CONNECT 代理”,不是新密码学原语;
  2. 抗探测依赖“前端像网站 + 鉴权后才进入代理路径”,而不是把端口改成 443;
  3. 抗分类依赖同源指纹、HTTP/2 多路复用与开局填充,并且必须持续与 Chrome 同步。

若要把它放回更大的技术史坐标,可继续阅读VPN 抗封锁技术演进现代 VPN 技术架构。评估任何抗封锁工具时,都应同时问:未认证探测看到什么、握手像不像常见客户端、失败时如何回退、入口暴露后多久能替换——这些问题比协议名称本身更能预测真实可用性。

主要技术资料