跳到內容
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 — temperature 與快取控制規則
  • 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 Proxy(Antigravity、Linux/macOS/Windows)

Section titled “MITM Proxy(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 是智慧代理程式開發工作台,結合結構化工作流程、多代理程式執行與 Hero Dungeon 介面,將想法化為交付成果。

以更聰明、更快速且更有趣的智慧代理程式工作流程,打造實用的軟體。

HagiCode 淺色主題介面畫面
  • Smart結構化流程將意圖轉化為從構想到交付的可執行步驟。
  • Efficient多代理程式工作流程讓研究、實作與審查並行進行。
  • FunHero Dungeon 讓長時間的程式協作更直覺、更有參與感。
造訪 HagiCode