前言¶
把 dsh web 部署到服務器、想從瀏覽器遠程使用時,會先撞上一個問題:這個 Web 應用本身沒有密碼驗證,誰拿到地址都能打開。harness 本體按官方要求保持 127.0.0.1 迴環綁定(禁止綁 0.0.0.0),常見的做法是在前面自己架一層帶認證的反向代理,但這意味着額外維護一份代理配置。
下面介紹的 dsh-gateway-plugin 把這件事做成了 DSH 插件:裝進 profile 後,它會開一個自己的網關端口作爲唯一對外入口,網關端口上除登錄/首次設置頁外,不存在任何未認證可達的內容面。
這是什麼¶
dsh-gateway-plugin 由 laoin114514 維護,MIT 許可證,定位是 DeepSeek Harness Web 的訪問密碼網關插件。
它以插件形式實現了一道「密碼反代」:瀏覽器訪問網關端口,未認證的請求被攔下;通過認證的請求才反向代理到 harness,並由網關改寫 Host/Origin,放行 harness 內部的信任圍欄。整個過程不需要動 harness 本體。
核心能力¶
1、絕對門禁。網關監聽端口上只有 /gateway/login(GET 頁面 + POST 登錄/設密)未認證可達,沒有其他例外:未認證的頁面與靜態資源 302 到登錄頁,/api 返回 401,WebSocket 升級直接拒絕。
2、首次設置密碼。部署還沒有密碼時,登錄頁呈現設置表單,首個訪問者設置成功後立即獲得會話;之後所有人用該密碼登錄。
3、修改密碼。在設置的獨立「安全」頁完成(當前密碼 + 新密碼 ×2);修改成功後所有已登錄會話立即失效(簽名密鑰輪換)。
4、防爆破。密碼比對先做 SHA-256,再用 timingSafeEqual 做恆定時間比較;登錄失敗按來源地址限流,默認連續 5 次失敗冷卻 30 秒。
5、無狀態會話。會話是 HMAC-SHA256 簽名的 cookie(HttpOnly、SameSite=Lax),簽名密鑰每次進程啓動隨機生成——重啓即全員重新登錄,屬有意的 fail-closed 行爲。
6、兩種認證方式。支持會話 cookie,或請求頭 Authorization: Bearer <密碼>。
7、開箱即用。構建產物(lib/)已隨倉庫提交,git 安裝後無需運行構建腳本、無需放行 build 權限。
安裝與啓用¶
前提是 dsh CLI 已安裝(或使用源碼檢出)。執行:
dsh plugin --profile web add github:laoin114514/dsh-gateway
爲防止倉庫後續推送悄悄改變安裝到的代碼,推薦固定到具體 commit:
dsh plugin --profile web add github:laoin114514/dsh-gateway#<commit-sha>
安裝後啓動 dsh web,日誌中會打印網關地址:
dsh-gateway: http://127.0.0.1:3088 (gateway, password required) -> harness http://127.0.0.1:3080
經過上面的步驟,注意此後要打開的是網關地址,而不是 harness 地址。首次訪問時登錄頁會引導設置訪問密碼,之後每次訪問輸入該密碼即可。
典型用法¶
暴露到網絡¶
默認網關只綁 127.0.0.1。需要從其他機器訪問時,在 $DSH_HOME/profiles/web/cordis.patch.yml 中爲 dsh-gateway 行覆蓋 gatewayHost:
- id: dsh-gateway
config:
gatewayHost: '0.0.0.0'
harness 本體仍保持迴環綁定(官方禁止 0.0.0.0),網關是唯一對外入口。
可配置項¶
網關在 cordis.patch.yml 的 dsh-gateway 行上提供以下配置:
gatewayHost、gatewayPort:網關監聽地址與端口;sessionTtlHours:會話有效期;minKeyLength:密碼最短長度;maxLoginFailures、loginCooldownSeconds:登錄失敗限流的閾值與冷卻時長(默認連續 5 次失敗冷卻 30 秒);accessKey:初始密碼,留空即進入首次設置模式。
安裝失敗排查¶
如果 dsh plugin add 報 ERR_PNPM_ENOENT 一類錯誤(常見於之前失敗安裝留下的半裝目錄),先清理再重裝:
dsh plugin --profile web remove dsh-gateway-plugin
# 或手動刪除半裝目錄:
rm -rf "$DSH_HOME/profiles/web/node_modules/dsh-gateway-plugin"
dsh plugin --profile web add github:laoin114514/dsh-gateway
源碼檢出下的本地開發¶
需要與倉庫源碼聯動時,先檢出源碼,再在倉庫根執行:
pnpm dsh web --patch <dsh-gateway>/cordis.dev.yml --no-open --port 3082
注意:以 --patch overlay 方式啓動時,瀏覽器側的「安全」設置頁不會加載——只有 profile 行才能被客戶端模塊系統發現。
適用場景與注意¶
適合的場景:把 dsh web 跑在服務器或內網中、希望通過瀏覽器訪問、又不想讓端口裸奔的部署。
使用前注意以下幾點:
- 插件不提供 TLS。公網或跨網段傳輸需在網關前再放一個終結 TLS 的反向代理,或把網絡限制在內網。
- 密碼以明文存於用戶設置文件(設置命名空間
dsh-gateway,字段accessKey,聲明爲role('secret'),任何 wire 響應都不會攜帶它),請按機密文件的權限管理該文件。 - 會話簽名密鑰每次進程啓動隨機生成,重啓後所有會話失效、需重新登錄,這是有意的 fail-closed 行爲。
- 默認網關只綁
127.0.0.1;harness 本體應保持迴環綁定(官方禁止0.0.0.0)。 - 與安裝任何 DSH 插件一樣,插件以當前 dsh 進程的權限運行,安裝前建議先查看源碼與許可證(本項目爲 MIT)。
小結¶
dsh-gateway-plugin 用一條 profile 安裝命令的代價,換來了網關端口上「沒有未認證內容面」的保證:密碼的首次設置、修改、登錄限流、會話失效策略都是現成的,harness 本體可以繼續安全地留在迴環地址後面。
插件收錄在社區插件目錄(獨立站點,與 DeepSeek / 幻方無官方從屬關係):https://www.skillhub.cn/plugins/laoin114514/dsh-gateway ,源碼倉庫:https://github.com/laoin114514/dsh-gateway 。