前言¶
DeepSeek Harness(DSH)的 WebUI 默認在本機或局域網內監聽 HTTP 服務。只要知道地址和端口,未登錄的訪問者同樣可以加載頁面、調用 /api、建立 WebSocket。對放在公網反代後面、或多人共用同一臺機器的場景,這等於把智能體配置、憑證和會話面完全暴露在網絡可達範圍內。
社區裏常見做法是依賴反向代理層的 Basic Auth,或只在防火牆側收口;它們要麼與 DSH 自身的 Host 信任、Cookie 交換機制脫節,要麼無法在同一層同時攔住靜態資源、插件 bundle 和 RPC。下面介紹 multidsh 維護的 dsh-webui-auth(npm 包 @multidsh/dsh-webui-auth):在插件層對 WebUI 做傳輸層強制認證,會話落盤,重啓進程不丟登錄態;本倉庫在 npm 包 dsh-webui-auth@0.3.6 基礎上合併 0.3.7 補丁,修復 nginx 等反代強制改寫 Host 時登錄跳轉錯誤的問題。
這是什麼¶
dsh-webui-auth 是 DSH 的持久化 WebUI 身份認證插件(組合包 bundle)。在「設置 → 身份認證」或首次訪問登錄頁創建賬號密碼後,未認證的瀏覽器無法加載 WebUI 任何資源、調用任何接口或建立任何實時連接;認證在 HTTP/傳輸層執行,不能靠瀏覽器開發者工具繞過。
維護與發佈:multidsh(GitHub 倉庫 multidsh/dsh-webui-auth);上游基於 Yuuz12 的 dsh-webui-auth@0.3.6(MIT),許可證與版權聲明原樣保留。社區目錄分類爲 admin-security。當前 npm 版本 0.3.7,零額外 npm 依賴。
核心功能¶
四層路由包裝,不改核心源碼¶
認證通過運行時包裝 webServer 路由實現,不修改 DSH 核心包源碼。大致分工如下:
| 層 | 未認證時的行爲 |
|---|---|
WebUI 資源(index.html、/assets/*、SPA 路由) |
302 到登錄頁 |
/plugins/* |
401 |
/api RPC |
401 |
WebSocket(含 /api/remote.mux 等) |
401,拒絕升級 |
插件每次啓動會重做路由包裝,並用 2s→10s 重掃捕獲晚註冊路由。若預期路由包裝不完整,setup/configure 會拒絕啓用認證(fail-closed),宿主日誌與設置頁同時報錯,避免「開了登錄卻 /api 裸奔」。
同前綴的頂層 exact 路由(例如 client-hmr 的 /plugins/events)也會被納入包裝,避免匿名讀取客戶端插件圖或長期掛着 SSE。
會話與口令¶
會話爲服務端會話,持久化到磁盤(sessions.jsonl),重啓 DSH 不掉線,到期自動失效。瀏覽器通過 HttpOnly; SameSite=Lax Cookie(dsh_wua_session)攜帶,前端 JS 無法讀取。修改密碼會弔銷所有其他會話。
與核心瀏覽器認證協作¶
DSH 核心 v0.1.2-alpha.2 及以上自帶 launch-token 交換的簽名 Cookie(dsh-auth-*)。插件登錄成功後會引導瀏覽器到核心的帶 token 根 URL 完成 Cookie 交換;/api 在插件會話校驗後原樣轉交核心。瀏覽器須同時持有插件會話 Cookie 與核心 Cookie。
0.3.7:反代 Host 與登錄跳轉¶
部分 nginx 部署會 proxy_set_header Host localhost;,舊邏輯會把登錄成功後的跳轉 authority 退化成 http://localhost/?token=…。0.3.7 構造跳轉 authority 時優先採用 X-Forwarded-Host(嚴格校驗爲裸 host[:port]),失敗纔回退到 Host。
部署側通常還需要:
dsh web --public-url http://web.example.com決定打印/打開的入口地址;- 非迴環域名加入信任列表,例如
dsh web --trusted-host web.example.com(等價於client-connection.trustedHosts),否則核心/api與 WebSocket 仍可能按 Host 柵欄拒絕。
WebSocket 在反代/局域網下還需在 DSH 配置裏把對外域名加入 client-connection.trustedHosts,否則已登錄也可能無法完成 WS 升級。
DSH Desktop 適配¶
桌面端使用獨立 profile desktop。插件 0.3.6 起提供「宿主直連信任橋」:對已被核心認證過的迴環宿主直連請求放行,並原樣處理核心的 token→cookie 交換(303 + Set-Cookie),避免桌面端因 shell 丟棄 set-cookie 而卡在「Desktop Host authentication failed」。桌面端窗口在傳輸層無法像瀏覽器一樣落插件會話 Cookie,因此採用 UI 級鎖(解鎖令牌存 sessionStorage / localStorage,語義見 README)。
DSH Desktop 的 dsh-desktop-* URL 標記在登錄跳轉中可能丟失;0.3.5 起通過 Cookie dsh_wua_desktop 在文檔加載前補投帶標記的同源 /,邏輯隔離在 lib/desktop-adapter.js。
安裝與啓用¶
前提:機器上可用 pnpm(Node 自帶 corepack 時可執行 corepack enable pnpm)。
Web profile(推薦,npm):
npx @deepseek-ai/dsh plugin --profile web add @multidsh/dsh-webui-auth
Web profile(GitHub 源碼):
npx @deepseek-ai/dsh plugin --profile web add github:multidsh/dsh-webui-auth
DSH Desktop:
npx @deepseek-ai/dsh plugin --profile desktop add @multidsh/dsh-webui-auth
安裝後無需給核心打補丁、不改 node_modules 裏的核心包;重啓 DSH 即生效。成功啓動時宿主日誌應出現 [dsh-webui-auth] started, credentials file: ...;若出現 ROUTE GATE INCOMPLETE,認證不會啓用。
手動備用方式:將包目錄放入 profiles/web/node_modules/@multidsh/,並在對應 profile 的 cordis.patch.yml 的 insert 列表增加插件行(字段見倉庫 README)。
典型用法¶
1、按上一節命令把插件加入 web 或 desktop profile,重啓 DSH。
2、瀏覽器打開 WebUI,按提示在登錄頁或「設置 → 身份認證」創建賬號與密碼。
3、若前面有 nginx 反代且改寫了 Host,確保配置 X-Forwarded-Host(nginx 常用 proxy_set_header X-Forwarded-Host $host;),並按 README 設置 public-url 與 trusted-host。
4、桌面端安裝到 desktop profile 後,日誌出現 host carrier bridge active 表示宿主橋就緒;口令管理與審計在設置頁仍可用,瀏覽器訪問宿主 WebUI 依舊需要登錄。
適用場景與注意¶
適合誰: 需要給 DSH WebUI 加賬號口令、且希望未登錄時靜態資源與 API 一併拒絕的場景;公網或局域網反代部署、以及使用 DSH Desktop 且希望與宿主 Web 認證策略對齊時,README 中的 Host / trustedHosts / Desktop 橋接說明需要一併閱讀。
安全與信任: 插件以當前 DSH 進程權限運行,憑證與會話文件位於 DSH 數據目錄;安裝前應在 GitHub 倉庫 查看源碼與 MIT 許可證。社區插件目錄 skillhub.cn 與 DeepSeek / 幻方無官方從屬關係,安裝決策以你方環境爲準。
反代舊核心: README 提到在 ≤alpha.1 核心下,已認證請求可能以迴環形狀轉交核心,以便反代部署下使用迴環釘死的特權 RPC;具體邊界以倉庫文檔爲準。
結尾¶
dsh-webui-auth 把 WebUI 認證做成可安裝的持久化插件:四層路由閘門、磁盤會話、fail-closed 啓用策略,並在 multidsh fork 中補上反代 Host 導致的登錄跳轉問題,同時覆蓋 Desktop 宿主橋與 UI 鎖。需要進一步瞭解版本變更時,可查看倉庫 CHANGELOG.md。