ITADN
klzgrad/naiveproxy
klzgrad/naiveproxy · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

NaïveProxy build workflow

NaïveProxy 使用 Chromium 的网络栈来伪装流量,具有强大的抗审查能力和低可检测性。复用 Chrome 的网络栈也确保了在性能和安全性方面的最佳实践。

通过使用 Chromium 的网络栈,可以缓解以下流量攻击:

  • 网站指纹识别 / 流量分类:通过 HTTP/2 中的流量复用 和模仿前导部分来缓解。
  • TLS 参数指纹识别:通过复用 Chrome 的网络栈 来击败。
  • 主动探测:通过 应用前置(application fronting)来击败,即将代理服务器隐藏在一个常用的前置服务器之后,并进行应用层路由。
  • 基于长度的流量分析:通过填充和分片来缓解。

架构

[浏览器 → Naïve 客户端] ⟶ 审查者 ⟶ [前置服务器 → Naïve 服务器] ⟶ 互联网

NaïveProxy 使用 Chromium 的网络栈,在常规 Chrome 浏览器和标准前置服务器之间模仿流量。

前置服务器可以是任何知名的反向代理,能够基于 HTTP 授权头路由 HTTP/2 流量,从而防止对代理存在性的主动探测。已知的包括带有 forwardproxy 插件的 Caddy 和 HAProxy。

此处的 Naïve 服务器作为正向代理和包长度填充层工作。Caddy forwardproxy 也是一个正向代理,但它缺少填充层。一个 分支 将 NaïveProxy 填充层添加到 forwardproxy 中,将两者合二为一。

下载 NaïveProxy

下载此处。支持的平台包括:Windows、Android(需配合 ExclavehusiNekoBox)、Linux、Mac OS 以及 OpenWrt(支持状态)。

用户应始终使用最新版本,以保持签名与 Chrome 一致。

从源码构建:请参阅 .github/workflows/build.yml

服务器设置

以下描述的是 Caddy forwardproxy 设置的 naïve 分支。

下载此处或从源码构建:

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
~/go/bin/xcaddy build --with github.com/caddyserver/forwardproxy=github.com/klzgrad/forwardproxy@naive

Caddyfile 示例(请相应替换 userpass):

{
  order forward_proxy before file_server
  log {
    exclude http.log.error # Avoid logging user activity
  }
}
:443, example.com {
  tls me@example.com
  encode
  forward_proxy {
    basic_auth user pass
    hide_ip
    hide_via
    probe_resistance
  }
  file_server {
    root /var/www/html
  }
}

:443 必须出现在最前面,此 Caddyfile 才能正常工作。请参阅 Caddyfile 文档 以自定义 TLS 证书。对于更高级的用法,请考虑使用 Caddy 2 配置的 JSON

使用 Caddyfile 运行:

sudo setcap cap_net_bind_service=+ep ./caddy
./caddy start

另请参阅 Systemd 单元示例HAProxy 设置

客户端设置

使用以下 config.json 运行 ./naive,以在本地端口 1080 获取 SOCKS5 代理。

{
  "listen": "socks://127.0.0.1:1080",
  "proxy": "https://user:pass@example.com"
}

或者使用 quic://user:pass@example.com,如果它效果更好。另请参阅 参数用法性能调优

第三方集成

下游注意事项

不要使用 master 分支来跟踪更新,因为每次新的 Chrome 发布都会从新的根提交进行 rebase。请使用稳定版本及其关联的标签来跟踪新版本,其中也提供了简短的发布说明。

Padding 协议,一份非正式规范

该填充协议的设计选择了低开销和更简单的实现方式,其理念是,大量涌现的、可弃用的、临时拼凑的规避协议设计,比精巧的设计更能从后勤上阻碍审查研究。

代理负载填充

NaïveProxy 通过 HTTP/2(或 HTTP/3)CONNECT 隧道代理双向流。双向流以一系列的数据读取和写入操作运行。在流建立后,双向流中的前 kFirstPaddings(8)次读取和写入采用此格式进行填充:

struct PaddedData {
  uint8_t original_data_size_high;  // original_data_size / 256
  uint8_t original_data_size_low;  // original_data_size % 256
  uint8_t padding_size;
  uint8_t original_data[original_data_size];
  uint8_t zeros[padding_size];
};

padding_size 是 [0, kMaxPaddingSize](kMaxPaddingSize:255)范围内均匀分布的随机整数。original_data_size 不能大于 65535,否则必须拆分为多次读取或写入。

kFirstPaddings 被选为 8,以平滑由常见初始握手形成的包长度分布峰值:

  • 常见客户端初始序列:1. TLS ClientHello;2. TLS ChangeCipherSpec, Finished;3. H2 Magic, SETTINGS, WINDOW_UPDATE;4. H2 HEADERS GET;5. H2 SETTINGS ACK。
  • 常见服务器初始序列:1. TLS ServerHello, ChangeCipherSpec, ...;2. TLS Certificate, ...;3. H2 SETTINGS;4. H2 WINDOW_UPDATE;5. H2 SETTINGS ACK;6. H2 HEADERS 200 OK。

kFirstPaddings 之后的后续读取和写入不进行填充,以避免性能开销。此外,后续包长度通常被认为信息量较少。

H2 RST_STREAM 帧填充

在实验中,NaïveProxy 倾向于在每个会话中发送过多的 RST_STREAM 帧,这是一种常规浏览器中不常见的行为。为了解决这个问题,一个总长度分布在 [48, 72] 之间的 END_STREAM DATA 帧被填充并前置到 RST_STREAM 帧之前,使其看起来像一个 HEADERS 帧。服务器通常会对此回复一个 WINDOW_UPDATE,因为填充部分计入流量控制。这是否会导致新的不常见行为目前尚不清楚。

H2 HEADERS 帧填充

CONNECT 请求和响应帧过短且不常见。为了使长度与真实的 HEADERS 帧相似,一个 padding 头部被填充了一串未进行 Huffman 编码且伪随机程度足以避免被索引的符号。填充序列的长度随机分布在 [16, 32](请求)或 [30, 62](响应)之间。

填充协议的可选加入

NaïveProxy 客户端应与任何不了解此填充协议的常规 HTTP/2 代理互操作。NaïveProxy 服务器(即任何支持此填充协议的代理服务器)应与任何不了解此填充协议的常规 HTTP/2 客户端(例如常规浏览器)互操作。

NaïveProxy 服务器和客户端通过 CONNECT 请求和响应中是否存在 padding 头部来确定对端是否支持此填充协议。仅当存在 padding 头部时,填充协议才会启用。

对服务器的首个 CONNECT 请求无法使用 "Fast Open" 在响应之前发送负载,因为服务器的填充能力尚未从首个响应中确定,且未知对于 Fast Open 应发送带填充还是不带填充的负载。

与 Chromium 上游的差异

  • 最小化源代码和构建体积(为原始大小的 0.3%)
  • 禁用异常和 RTTI,Mac 和 Android 除外。
  • 支持 OpenWrt 构建
  • (Android、Linux)使用内置验证器而非系统验证器(在 Linux 上移除对 NSS 的依赖),并按照 Go 在 crypto/x509/root_unix.go 和 crypto/x509/root_linux.go 中的行为读取系统信任存储:
    • 环境变量 SSL_CERT_FILE 中的文件
    • 以下第一个可用文件
      • /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu/Gentoo 等)
      • /etc/pki/tls/certs/ca-bundle.crt (Fedora/RHEL 6)
      • /etc/ssl/ca-bundle.pem (OpenSUSE)
      • /etc/pki/tls/cacert.pem (OpenELEC)
      • /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem (CentOS/RHEL 7)
      • /etc/ssl/cert.pem (Alpine Linux)
    • 环境变量 SSL_CERT_DIR 目录中的文件
    • 以下第一个可用目录中的文件
  • 处理 PKCS#7 格式的 AIA 响应
  • 允许代理使用更高的套接字限制
  • 强制所有套接字使用隧道
  • 支持使用 fastopen 头部的 HTTP/2 和 HTTP/3 CONNECT 隧道快速打开
  • 填充 RST_STREAM 帧