dsh-web-lan-access:讓 DSH Web UI 在局域網 HTTP 下可用

前言

DeepSeek Harness(DSH)的 Web UI 默認適合在本機或 HTTPS 環境下使用。若把服務暴露在局域網 IP、Tailscale 地址或非 loopback 主機名上,並以明文 HTTP 訪問,頁面可能在啓動階段就失敗:會話列表和模型選擇區空白,RPC 調用持續報錯。

根因在於 Web UI 在啓動關鍵路徑裏調用 crypto.randomUUID(),而該 API 僅在安全上下文(HTTPS,或 http://localhost / http://127.0.0.1)中可用。在 http://192.168.x.x:3080 這類地址上,crypto.randomUUIDundefined,後續 RPC 無法正常工作。

下面介紹社區插件 dsh-web-lan-access:在不改動 DSH 產品源碼的前提下,通過宿主側注入 polyfill 並自動放寬 /api 信任邊界,使局域網與 Tailscale 訪問可以正常加載會話與模型。

這是什麼

dsh-web-lan-access 是 AcidGr 維護的 DSH Web 側插件,歸類爲聯網工具。它在 npm 上發佈爲 dsh-web-lan-access(當前版本 1.2.1,MIT 許可證),GitHub 倉庫約 25 stars。

插件做三件事:

  1. 通過 webServer.tapIndex 擴展點,在 <head> 最前面注入基於 crypto.getRandomValues 的 RFC 4122 v4 polyfill;在安全源上該腳本爲 no-op。
  2. 通過 bundle patch 將 webserver 綁定地址設爲 0.0.0.0,無需再傳已被新版本 CLI 拒絕的 --host 0.0.0.0
  3. 自動根據主機當前非內網 IPv4(含 192.168.x、Tailscale 100.x、VPN 接口)擴展 /api 信任圍欄。

全程只變換服務端輸出的 index.html 與配置,不修改產品源碼,卸載即可回滾。

核心功能

crypto.randomUUID polyfill

DSH Web UI 在 RPC id、消息 id、草稿附件等路徑依賴 crypto.randomUUID()。插件在 boot manifest 與 shell 入口之前注入一小段腳本,用 crypto.getRandomValues(在非安全源上仍可用)實現 v4 UUID。HTTPS 或 localhost 訪問時腳本不生效。

自動綁定與信任圍欄

bundle patch 將 webserver 監聽 0.0.0.0。啓動時插件會從主機網卡推導所有非 internal IPv4,與 resolveLanTrust 已有結果合併,寫入 /api 信任圍欄。因此 LAN IP 與 Tailscale IP 字面量訪問通常無需額外配置——前提是遠程接口在 dsh web 啓動前已就緒。

MagicDNS 主機名支持

信任圍欄只能發現 IP 字面量,不能自動識別 xxx.tailXXXX.ts.net 這類主機名。若要用域名而非 IP 訪問,需把短名與完整域名分別加入 web-runtimetrustedHosts,或使用 CLI:

dsh --profile web --trusted-host myhost --trusted-host myhost.tailXXXX.ts.net

注意:Host 頭按字面量匹配。用 http://myhost:3080 訪問時,短名 myhost 必須單獨列出,否則頁面殼能加載但 /api 返回 403。不要把主機名配置寫到 connection 行——那會覆蓋 bundle 的動態圍欄表達式,導致自動推導的 LAN/Tailscale IP 信任失效。

安裝與啓用

推薦通過 npm 安裝到 web profile:

dsh plugin --profile web add dsh-web-lan-access

無 npm 或本地開發時,可指向 GitHub 倉庫:

dsh plugin --profile web add github:AcidGr/dsh-web-lan-access

安裝後重啓 dsh web,並在瀏覽器中硬刷新。

離線手動安裝時,將插件目錄複製到 $DSH_HOME/profiles/web/plugins/lan-access,建立 @dsh-profile/lan-access 符號鏈接,並在 cordis.patch.yml 中插入對應 id。具體路徑與 YAML 片段見倉庫 README。

安裝前應閱讀插件源碼與 MIT 許可證;插件以當前 dsh 進程權限運行。

典型用法

安裝完成後,正常啓動即可,不必傳 --host

dsh --profile web --port 3080

在同一局域網的另一臺設備打開 http://<server-ip>:3080http://<tailscale-ip>:3080,會話與模型應能加載。

驗證 polyfill 是否注入:

curl http://127.0.0.1:3080/ | grep lan-access-polyfill

有匹配輸出即表示腳本已寫入首頁。

若不想由插件接管綁定地址(例如只想 loopback 加端口轉發),可從配置樹中去掉 webserver 行覆蓋,改用 socat、rinetd 或 Tailscale serve 轉發,並手動維護 trustedHosts

適用場景與注意

適合誰: 需要在家庭或辦公室局域網、Tailscale 組網內,用 HTTP 從手機或其他電腦訪問 DSH Web UI 的開發者;不想爲內網調試單獨搭 HTTPS 反向代理的場景。

安全: 綁定 0.0.0.0/api 僅有來源圍欄、無登錄鑑權,同一網段內任何人均可訪問智能體。公網 IP 主機上切勿直接暴露;應配合防火牆(如 ufw allow from 192.168.0.0/16)、Tailscale 或帶認證的反代。若已用 TLS 反代,通常不再需要此 polyfill。

已知限制: 在未修改上游的 harness 構建中,settings.*credentials.*llm.discoverModels 等敏感 API 仍固定只允許 loopback,遠程訪問時設置頁與憑證 UI 可能爲空或報錯;聊天與會話功能不受影響。需在 http://127.0.0.1:3080 本地管理這些項,或自行修改上游 isTrustedApiRequest 一行代碼。

回滾:

dsh plugin --profile web remove dsh-web-lan-access

手動安裝則刪除 cordis.patch.yml 中的 lan-access 插入塊。

結尾

dsh-web-lan-access 針對 DSH Web UI 在非安全 HTTP 源上無法啓動的問題,用宿主插件方式注入 polyfill 並自動配置監聽與 API 信任,使局域網與 Tailscale 訪問可以開箱使用。插件來自 DSH 社區生態,SkillHub 目錄頁與 GitHub 倉庫相互獨立,與 DeepSeek / 幻方無官方從屬關係。

  • 目錄頁:https://www.skillhub.cn/plugins/AcidGr/dsh-web-lan-access
  • GitHub:https://github.com/AcidGr/dsh-web-lan-access
羽毛球分组比赛记分
小程序二维码

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

小夜