dsh-system-proxy:DSH 出站 HTTP(S) 路由插件

前言

DSH 的理念是插件化,插件和模型調用經常要訪問外部 HTTP/HTTPS 接口。實際運行中,目標地址、provider、plugin 可能不同;有的請求需要直連,有的請求需要走代理;直連失敗時還需要安全地換到代理。

dsh-system-proxy 把這類出站路由放到 DSH host plugin 層處理,避免每個插件各自拼接代理邏輯。

這是什麼

dsh-system-proxy 是一個 DSH host plugin,用於在 DSH 主進程中統一處理出站 HTTP/HTTPS 路由。倉庫地址所有者爲 khiqwq,源碼倉庫是 https://github.com/khiqwq/dsh-system-proxy

它解決的核心問題是:

  • HTTP、HTTPS、SOCKS4、SOCKS4a、SOCKS5、SOCKS5h 代理;
  • 多個具名代理(named proxies);
  • hostproviderplugin 路由;
  • directproxyfallbackblock 四種動作;
  • 直連失敗或延遲過高時使用代理保底;
  • 每目標 EWMA 延遲、失敗冷卻(cooldown)與健康記憶;
  • 顯式 provider / plugin 上下文,不僞造調用方身份;
  • 代理憑據脫敏、安全日誌和熱重載恢復;
  • 包裝 globalThis.fetch
  • patchNodeHttp: true 時包裝 node:http / node:httpsrequestget
  • 內網 / 雲元數據端點的默認保護;
  • 交互式配置卡;
  • passwordRef / credentials 保存密碼。

運行要求 Node >=22。

核心能力

路由動作

插件把出站請求歸到四類動作:

  1. direct:只直連。
  2. proxy:強制使用指定具名代理。
  3. fallback:先直連,滿足條件時改用代理。
  4. block:本地拒絕請求。

引用不存在或當前不可用的代理名會報 UNKNOWN_PROXY,不會靜默降級直連。

fetch 與 node http/https

插件會包裝 globalThis.fetch。配置中啓用 patchNodeHttp: true 時,還會包裝 node:http / node:httpsrequestget

這是進程級全局補丁。同一進程內不應同時加載多個相互競爭的傳輸包裝插件。

provider / plugin 上下文

全局 fetch 本身不能可靠判斷請求來自哪個插件。調用方需要顯式提供上下文:

await ctx.networkRoute.run({ provider: 'openai', plugin: 'my-plugin' }, () => fetch('https://api.openai.com/v1/models'))

對於流式響應,可以用 iterable 包裝惰性異步迭代器:

const attributed = ctx.networkRoute.iterable({ provider: 'openai' }, response.body)

這樣在消費 response.body 時,可以保留 provider / plugin 歸屬。

安全與回退

自動回退不是普通重試。默認只允許 GETHEADOPTIONSTRACE 自動換路;POST 默認不重放。

以下情況不重放:

  • 流式上傳;
  • FormData
  • 超出緩衝上限的 body
  • 用戶主動 abort
  • 已經收到響應頭或 SSE 字節;
  • 無法證明請求字節尚未寫出的連接後失敗。

只有連接前失敗才安全換路。主動健康探測默認關閉。

內網與雲元數據保護

安全默認讓 localhostloopback169.254.0.0/16、雲 metadata 端點、RFC1918 內網和 IPv6 ULA 一律直連。內網和雲 metadata 流量因此保持直連,不會被交給外部代理。

密碼與憑據

插件支持 passwordRef / credentials 保存代理密碼。密碼僅通過單向 credentials.set() 提交,絕不會保存到 settings;保存後密碼草稿立即清空。

trustRouteHeaders 默認關閉;內部路由控制頭會在發出請求前自動剝離。

SOCKS 限制

SOCKS4 / SOCKS4a 面對 IPv6 目標時,會在握手前顯式拋錯 SOCKS4_IPV6_UNSUPPORTED,不會靜默直連。

安裝與啓用

發佈後可在對應 profile 中安裝:

dsh plugin --profile <name> add dsh-system-proxy

運行環境需要 Node >=22。

安裝前應檢查源碼與許可證,並確認插件以當前 dsh 進程權限運行是否符合預期。

配置與覆蓋

配置位於 profile 的 cordis.patch.yml。基本結構是:

  • proxies 是對象,用來聲明多個具名代理;
  • rules 是數組,用來描述路由規則;
  • default 是對象,用來聲明默認策略。

Loader 配置是整體替換:增加一條規則時,必須重述完整 config,不能只寫增量字段。

環境變量可用於覆蓋或禁用:

DSH_PROXY_URL
DSH_PROXY_MODE
DSH_PROXY_DISABLE
NO_PROXY/no_proxy

適用場景

適合以下情況:

  • 在 DSH 中統一處理出站 HTTP/HTTPS 請求;
  • 按目標主機、provider、plugin 選擇直連或代理;
  • 直連優先,並在連接前失敗時回退到代理;
  • 保護 localhostloopback、雲 metadata 和 RFC1918 內網地址不被外部代理轉發;
  • 需要爲代理密碼使用 passwordRef / credentials,而不是把密碼寫入 settings。

鏈接

源碼倉庫:https://github.com/khiqwq/dsh-system-proxy

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜