跳转到内容
OmniRoute source

Stealth Guide (中文 (简体))

open-sse/utils/tlsClient.ts — wreq-js(Chrome 124)

Section titled “open-sse/utils/tlsClient.ts — wreq-js(Chrome 124)”

持久化 wreq-js 会话会按账户作用域和已解析代理进行惰性创建。进程级 TlsClient 池最多容纳 128 个会话;针对受 Cloudflare 保护的上游,这些会话会模拟 macOS 上的 Chrome 124。当原生运行时不可用时,TlsClient.fetch() 会以关闭方式失败;调用方可以在此封装器之外显式选择回退方案。

  • 会话配置:browser: "chrome_124", os: "macos"
  • 代理解析(按优先级):HTTPS_PROXY → HTTP_PROXY → ALL_PROXY(也包括小写形式)
  • 超时:TLS_CLIENT_TIMEOUT_MS(继承自 FETCH_TIMEOUT_MS,默认值为 600000)
  • wreq-js Response 与 fetch 兼容(headers、text()、json()、clone()、body)。
  • 首字节看门狗(open-sse/utils/tlsFirstByteWatchdog.ts,#12656):TlsClient.fetch() 会在上游响应头到达后立即完成,因此仅靠 TLS_CLIENT_TIMEOUT_MS 无法限制一个始终不返回首字节的 响应体。guardTlsFirstByte() 会让响应体的首次 read() 与 TLS_FIRST_BYTE_WATCHDOG_MS(默认值为 10000,设为 0 可禁用)进行竞速;正常的响应体 不受影响,而停滞的响应体会取消 wreq 读取器,并使 proxyFetch 的现有 TLS 回退逻辑继续转入直连/代理分发器(不可安全重放的请求,例如 带有请求体的 POST,仍会抛出错误,而不会被静默重试)。
Section titled “Web Cookie 提供者传输层 — wreq-js 3.2.0”

open-sse/services/tlsClientBase.ts 是下述五种专用 Web Cookie 传输的共享适配器。每个轻量级提供者封装器都会选择浏览器/操作系统配置。该适配器 使用 open-sse/utils/tlsClient.ts 中唯一的 wreq 运行时加载器和传输池,并按 配置 + 操作系统 + 已解析代理建立键值,同时每个请求都使用 cookieMode: "ephemeral"。因此,账户和 请求会共享传输层连接,但绝不会共享 wreq 会话或 Cookie Jar。

提供者 配置 模拟的操作系统 流 EOF 策略
Claude chrome_146 Linux 包含 [DONE]
Perplexity firefox_148 macOS 包含 event: end_of_stream
Grok chrome_146 Linux 排除 [DONE]
Notion chrome_146 Windows 包含 [DONE]
LMArena chrome_146 Windows 无哨兵标记;在原生 EOF 时关闭
  • 流式处理直接消费原生响应的 ReadableStream;不会创建临时文件或伴随进程。
  • 在向外暴露流之前,最多会检查起始的 256 个字节。SSE 提供者会缓冲非 SSE 错误;Grok/LMArena 会将 Cloudflare 质询映射为 403,并将 HTML 中间页映射为 502。
  • 原生请求超时仍由绝对的 JS 硬性截止时间封装。发生挂起时,只会使受影响的配置/操作系统/代理传输 失效并关闭;下一次请求会重新创建该传输。
  • 代理解析优先级为:每次调用的 proxyUrl → 请求作用域的账户/控制面板上下文 → HTTPS_PROXY/HTTP_PROXY/ALL_PROXY(包括小写变体)。解析错误会以关闭方式失败, 而不是泄漏直连连接。LMArena 会特意基于 arena.ai 进行解析。
  • byteResponse 会返回带有内容类型的 data: URL,且不会造成 UTF-8 损坏。
  • 错误类型包括 TlsClientUnavailableError(软件包/插件不可用)、TlsClientHangError (超过截止时间),以及当所有 128 个有界配置/操作系统/代理槽位均处于活动或关闭过程中时抛出的 WreqTransportCapacityError(共享会话容量错误码)。

上述通用 TlsClient 会话仍专用于持久化、由浏览器支持的 Cookie 状态。两条路径会复用同一个已缓存的 wreq 模块加载器和进程生命周期钩子;由于二者的 Cookie 生命周期 有意设计为不同,其池仍保持分离。

固定版本的软件包支持这些配置,但真实 WAF 的接受情况可能会独立于本地契约测试发生变化。 在声称与上游浏览器具有同等能力之前,请使用经过明确授权的真实账户验证指纹变更。


启用 cliCompatMode 后,OmniRoute 会重塑发出的 Claude 请求,使其与 claude-cli 流量无法区分。三个模块协同工作:

计算嵌入计费请求头中的 3 字符 cc_version 指纹:

SHA256(SALT + msg[4] + msg[7] + msg[20] + version)[:3]
  • FINGERPRINT_SALT = "59cf53e54c78"(硬编码;与官方客户端一致)
  • 输入:第一条用户消息文本中索引为 4、7、20 的字符 + 版本字符串
  • 输出:3 字符十六进制前缀

claudeCodeCCH.ts(客户端内容哈希)

Section titled “claudeCodeCCH.ts(客户端内容哈希)”

官方 Claude Code CLI 通过 Bun/Zig 计算的服务端完整性校验。OmniRoute 使用 xxhash-wasm 重新实现:

  1. 使用 cch=00000; 占位符序列化请求体
  2. xxhash64(bytes, seed) & 0xFFFFF
  3. 补零至 5 字符的小写十六进制值
  4. 将 cch=00000; 替换为计算出的令牌

常量:

  • 种子:0x6e52736ac806831e
  • 模式:/\bcch=([0-9a-f]{5});/

在“敏感”客户端名称的第一个字符后插入 Unicode 零宽连接符(U+200D),使上游过滤器无法通过 grep 检测它们。默认词语列表:

opencode, open-code, cline, roo-cline, roo_cline, cursor, windsurf,
aider, continue.dev, copilot, avante, codecompanion

应用于:system 块、所有 messages[].content,以及 tools[].description / tools[].function.description。操作员可通过 setSensitiveWords() 覆盖。

claudeCodeCompatible.ts — anthropic-compatible-cc-* 提供者

Section titled “claudeCodeCompatible.ts — anthropic-compatible-cc-* 提供者”

适用于只接受“真实 Claude Code”流量的第三方 Anthropic 中继:

  • CLAUDE_CODE_COMPATIBLE_USER_AGENT = "claude-cli/2.1.258 (external, sdk-cli)"
  • CLAUDE_CODE_COMPATIBLE_STAINLESS_PACKAGE_VERSION = "0.112.1"
  • CLAUDE_CODE_COMPATIBLE_STAINLESS_RUNTIME_VERSION = "v26.3.0"
  • anthropic-beta = "claude-code-20250219,interleaved-thinking-2025-05-14,effort-2025-11-24"(默认值)
  • 当某个 CC Compatible 上游明确要求经过删减的思考流时,单连接的“启用 redact-thinking beta”开关会添加 redact-thinking-2026-02-12
  • 单连接的“启用摘要式思考显示”开关会存储 providerSpecificData.requestDefaults.summarizeThinking,并为尚未设置显示模式的 CC Compatible 思考请求添加 display: "summarized"
  • CONTEXT_1M_BETA_HEADER = "context-1m-2025-08-07"(Opus/Sonnet 4.x 系列)
  • 默认路径:/v1/messages?beta=true

同一套件中的配套模块:

  • claudeCodeConstraints.ts — 温度 + 缓存控制规则
  • claudeCodeToolRemapper.ts — 工具名称重映射
  • claudeCodeExtraRemap.ts — 额外的载荷规范化

Antigravity 请求会逐字节保留调用方文本。OmniRoute 不会在提示词中插入零宽字符,也不会重命名/注入工具来模仿 IDE 客户端。

转发前移除 Stainless SDK 标记(x-stainless-lang、x-stainless-package-version、x-stainless-os、x-stainless-arch、x-stainless-runtime、x-stainless-runtime-version、x-stainless-timeout、x-stainless-retry-count、x-stainless-helper-method)。

⚠️ 风险:ANTIGRAVITY_CREDITS=always(账号封禁高发点)

Section titled “⚠️ 风险:ANTIGRAVITY_CREDITS=always(账号封禁高发点)”

ANTIGRAVITY_CREDITS=always(由 open-sse/executors/antigravity.ts 使用)会将每个请求都通过 Antigravity AI Credit Overages(付费 Google 积分)路由,而不是由 Google 的免费层级配额进行限制。该行为在文档中被描述为一项功能,但它是我们看到的最常见 ToS 违规报告来源——多个 Google Ultra 账号在使用 =always 运行数小时后,因 403 / "service disabled for ToS violation" / insufficient_quota 而被封禁。

上游强制措施发生在 Google 一侧,并非 OmniRoute 所能阻止。该环境变量的名称和现有文档让它看起来像一个可以安全启用的选项;事实并非如此。

为什么与仅使用免费层级相比,这种方式更容易触发滥用检测:

  • 在单个 Google 账号上持续进行自动化消费,其风险标记方式不同于免费层级达到配额后即停止的情况。
  • 超额积分没有速率上限,因此配置错误的客户端可能在几分钟内消耗数百美元,并呈现出类似 API 密钥转售或机器人流量的特征。
  • 多个 OmniRoute 用户从同一外部 IP 并行使用超额积分会进一步放大这一信号。

建议做法:

  1. 除非操作员明确接受付费积分和账号风控风险,否则请保持默认的 ANTIGRAVITY_CREDITS=off。retry 会先发送普通请求,仅在出现符合条件的配额 429 后最多注入一次积分;always 则会在第一次请求时就注入积分。
  2. 通过 Auto-Combo 将负载分散到多个提供者(model: "auto" 或 kr/glm/etc-combo),而不是让单个 Antigravity 账号达到饱和。
  3. 设置单连接 RPM 限制,位置在 Antigravity 提供者的编辑页面(Dashboard → Providers → Antigravity → connection → rate limit)。对于持续使用,30–60 RPM 是一个合理且可辩护的上限。
  4. 使用稳定、由操作员控制的上游网络,并避免在互不相关的用户或工作负载之间共享同一个账号。
  5. 如果被封禁:通过 support.google.com → “Restore Workspace/Account access” 提交申诉,并附上 Google 返回的完整 quota_exceeded / service disabled 响应正文。无法保证账号一定会恢复。

环境参考文档说明了每种积分模式对账号和支出的影响。

涉及位置:

  • open-sse/executors/antigravity.ts — 读取 process.env.ANTIGRAVITY_CREDITS
  • src/lib/oauth/providers/antigravity.ts — 凭据传递
  • 原始事件报告:讨论 #1183

CLI 指纹注册表 — open-sse/config/cliFingerprints.ts

Section titled “CLI 指纹注册表 — open-sse/config/cliFingerprints.ts”

按提供者划分的表,用于固定从官方 CLI 的 mitmproxy 跟踪记录中捕获的精确请求头顺序和 JSON 请求正文字段顺序。当前已注册:codex、claude,以及 providerHeaderProfiles.ts 中为 antigravity 和 github 运行时派生的配置文件。

interface CliFingerprint {
headerOrder: string[]; // 区分大小写
bodyFieldOrder: string[]; // 顶层 JSON 键
userAgent?: string | (() => string);
extraHeaders?: Record<string, string>;
}

可通过环境变量为每个提供者切换启用状态(见下文)。禁用后,请求头/正文键将按照 Node/JSON 生成的任意顺序出现,因此很容易被识别出指纹。


MITM 代理(Antigravity、Linux/macOS/Windows)

Section titled “MITM 代理(Antigravity、Linux/macOS/Windows)”

对于二进制文件无法通过 OPENAI_BASE_URL 重定向的 CLI,OmniRoute 会运行本地 TLS 终止代理。端点位于 src/app/api/cli-tools/antigravity-mitm/ 下。

方法 端点 用途
GET /api/cli-tools/antigravity-mitm 状态 — running、pid、dnsConfigured、certExists
POST /api/cli-tools/antigravity-mitm 启动 MITM(需要 apiKey + sudoPassword)
DELETE /api/cli-tools/antigravity-mitm 停止 MITM
GET /api/cli-tools/antigravity-mitm/alias 列出模型别名
PUT /api/cli-tools/antigravity-mitm/alias 保存工具的模型别名

目标拦截主机:daily-cloudcode-pa.googleapis.com(Antigravity 的上游)。

启动流程(src/mitm/manager.ts::startMitm)

Section titled “启动流程(src/mitm/manager.ts::startMitm)”
  1. 通过 selfsigned 生成自签名证书(RSA-2048、SHA-256、1 年)— cert/generate.ts
  2. 将证书安装到系统信任存储区 — cert/install.ts
  3. 添加 hosts 条目 127.0.0.1 daily-cloudcode-pa.googleapis.com — dns/dnsConfig.ts
  4. 使用 ROUTER_API_KEY + MITM_LOCAL_PORT(默认为 443)生成 src/mitm/server.cjs 进程
  5. 将 PID 持久化到 <DATA_DIR>/mitm/.mitm.pid

Linux 动态信任存储区检测 — cert/install.ts

Section titled “Linux 动态信任存储区检测 — cert/install.ts”

getLinuxCertConfig() 按优先级遍历列表,并选择首个存在的目录:

发行版系列 目录 更新命令
Debian / Ubuntu /usr/local/share/ca-certificates update-ca-certificates
Arch / CachyOS / Manjaro /etc/ca-certificates/trust-source/anchors update-ca-trust
Fedora / RHEL / CentOS /etc/pki/ca-trust/source/anchors update-ca-trust
openSUSE /etc/pki/trust/anchors update-ca-certificates

证书文件名:omniroute-mitm.crt。通过 getCertFingerprint() 进行指纹匹配(DER 的 SHA-1)。

此外,当 certutil 可用时,updateNssDatabases() 会将证书安装到每个用户的 NSS DB 中:~/.pki/nssdb、~/snap/chromium/.../nssdb、所有 Firefox 配置文件(包括 snap),使用的昵称为 OmniRoute MITM Root CA。

  • macOS: security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain
  • Windows: 提权的 PowerShell → certutil -addstore Root

所有 MITM 端点都需要管理身份验证(requireCliToolsAuth)。sudo 密码缓存在模块作用域中(绝不存入 globalThis),并在 stopMitm() 时清除。


User-Agent 覆盖项 — 环境变量(.env.example 第 12 节)

Section titled “User-Agent 覆盖项 — 环境变量(.env.example 第 12 节)”
变量 默认值
CLAUDE_USER_AGENT claude-cli/2.1.258 (external, cli)
CODEX_USER_AGENT codex-cli/0.155.0 (Windows 10.0.26200; x64)
GITHUB_USER_AGENT GitHubCopilotChat/0.54.0
ANTIGRAVITY_USER_AGENT antigravity/2.0.1 linux/arm64 google-api-nodejs-client/10.3.0
KIRO_USER_AGENT AWS-SDK-JS/3.0.0 kiro-ide/1.0.0
QODER_USER_AGENT Qoder-Cli
CURSOR_USER_AGENT Cursor/3.4

由 open-sse/executors/base.ts::buildHeaders() 通过动态查找读取。当提供者发布新的 CLI 版本时,请更新这些值——过期的 UA 字符串会因客户端版本过旧而开始被拒绝。

CLI 兼容模式开关(.env.example 第 13 节)

Section titled “CLI 兼容模式开关(.env.example 第 13 节)”
变量 效果
CLI_COMPAT_CODEX=1 Codex 指纹
CLI_COMPAT_CLAUDE=1 claude-cli 指纹
CLI_COMPAT_GITHUB=1 GitHub Copilot Chat 指纹
CLI_COMPAT_ANTIGRAVITY=1 Antigravity 指纹
CLI_COMPAT_KIRO=1 Kiro
CLI_COMPAT_CURSOR=1 Cursor
CLI_COMPAT_KIMI_CODING=1 Kimi Coding
CLI_COMPAT_KILOCODE=1 KiloCode
CLI_COMPAT_CLINE=1 Cline
CLI_COMPAT_ALL=1 启用上述所有模式

提供者 IP 始终会被保留——该开关仅重塑请求的网络传输特征,不会切换出口 IP。


OmniRoute 会在转发前清理入站客户端请求头,避免来自 Cursor 的请求将 User-Agent: Cursor/X.Y.Z 泄露给 Claude 上游。拒绝列表请参阅 src/shared/constants/upstreamHeaders.ts;该列表与 Zod 模式及单元测试保持同步。


  1. 使用 mitmproxy 捕获官方 CLI 流量(TLS 拦截 + 转储)
  2. 提取 JA3/JA4 和实际的请求头顺序
  3. 更新相关的 CLI_FINGERPRINTS[...] 条目
  4. 更新 .env.example 中对应的 *_USER_AGENT 默认值
  5. 如果 TLS 握手本身发生变化,请更新相关的提供者包装器或 wreq-js 的 browser: 选项
  6. 运行特定于提供者的 TLS 测试,并针对线上提供者执行手动金丝雀测试
  7. 在补丁版本中发布,并记录到 CHANGELOG.md

  • open-sse/services/__tests__/claudeTlsClient.test.ts — 共享 TLS 包装器行为
  • tests/unit/anthropic-cache-fingerprint.test.ts — 指纹确定性
  • tests/unit/chatgpt-web-source-retirement.test.ts — 确保通用 ChatGPT Web 隐匿来源保持移除状态,同时 Codex Web 仍然存在


OmniRoute 源码 (a58000c7685f)

HagiCode

HagiCode 是一套智能体编码工作台:结构化工作流、多 Agent 并行执行与 Hero Dungeon 视图,把想法变成真正交付的软件。

让想法更快变成好用的软件,让智能编码更聪明、更高效,也更有趣。

HagiCode 浅色主题主界面截图
  • Smart结构化工作流将意图转化为从想法到交付的可执行路径。
  • Efficient多 Agent 工作流让调研、实现与审阅并行推进。
  • FunHero Dungeon 让长时间编码协作更直观、更有参与感。
访问 HagiCode