前言¶
DSH 的 Web UI 長期只有進程級 ?token=:每次重啓換一次,得從終端抄出來,HTTP 反代之後 /api 還容易直接 403。dsh-web-guard(倉庫 lvxianchao/dsh-web-guard,維護者 lvxianchao,MIT 許可證)把這幾個部署問題收進一個插件:一個訪問密碼、可吊銷會話、原生設置頁,以及 TLS。下面介紹它的定位、安裝、配置和運維注意事項。
生態背景:DSH 的理念是「一切皆插件」;本文的目錄頁來自第三方社區站點 SkillHub,與 DeepSeek 官方無從屬關係。星標 1、分類 admin-security 爲該目錄頁所載,截至撰寫時無其他獨立佐證。
它解決什麼¶
README 把原生行爲與插件行爲對比成一張表,四個問題如下:
| 問題 | 原生行爲 | dsh-web-guard |
|---|---|---|
| 沒有人類登錄 | 只有啓動時打印的 ?token=,重啓就換 |
一個密碼 + 可吊銷會話 |
| 反代一律 403 | /api 柵欄要求 Host 原樣可達,NPM/Caddy 會改寫它 |
代理把 Host/Origin 改寫成迴環 authority |
| token 要挖日誌 | 得 journalctl \| grep token 才能進站 |
進程內兌換,瀏覽器見不到 token |
| 明文 HTTP 報錯 | crypto.randomUUID is not a function |
注入 polyfill |
零運行時依賴,只用 Node 標準庫;npm 包裏是預構建好的 JavaScript,dsh plugin add 不需要工具鏈。
它怎麼工作¶
browser ──HTTP(S)──> dsh-web-guard :3081 ──> DSH listener (loopback)
│
├─ not signed in → /login
├─ signed in → forward, Host/Origin rewritten to loopback
└─ injects the harness cookie (never exposed to the browser)
DSH 的 /api 柵欄接受迴環 authority,所以讓每個上游請求看起來都來自迴環,就消掉了 403。鑑權發生在代理裏,不是前端遮罩:沒有會話 cookie 的請求到不了 DSH。瀏覽器半(dsh.client)只負責把管理頁掛進 DSH 的設置面板;閘門本身完全在服務端,瀏覽器半加載失敗也不影響使用。
安裝與啓用¶
三種安裝方式,命令來自 README:
# npm
dsh plugin --profile web add @lvxianchao/dsh-web-guard
# from GitHub
dsh plugin --profile web add "github:lvxianchao/dsh-web-guard"
# from a local checkout
dsh plugin --profile web add /path/to/dsh-web-guard
main 分支只放已發佈代碼(開發在 dev 分支),所以這條命令裝到的是最新穩定版。包裏聲明瞭 dsh.bundle,guard 行會自動疊加,裝完重啓 dsh 即可。
首次啓動會自動生成一個密碼,打印在終端,並以哈希形式存到 <profile>/data/dsh-web-guard.json(0600)。想固定實例,改 ~/.dsh/profiles/web/cordis.patch.yml:
- id: guard
config:
listenHost: '0.0.0.0'
listenPort: 3081
注意 profile patch 會整體替換 config,要保留的鍵都得重寫一遍。
從 v2 升級:右下角浮動盾牌和 /__guard/admin 已移除,管理入口改爲「設置 → DSH Web Guard」。重新安裝(或升級到 3.0.0)並重啓 DSH;密碼哈希、會話緩存和設置文件格式不變,升級不踢人。
前提:DSH 自己必須綁回環(默認即 127.0.0.1)。如果綁在局域網 IP 上,客戶端可以繞過閘門直連——插件啓動時會檢測並告警。
典型用法¶
讓插件終結 TLS(沒有反向代理)¶
config:
listenHost: '0.0.0.0'
listenPort: 8443
tls:
certFile: /path/fullchain.pem
keyFile: /path/privkey.pem
瀏覽器訪問 https://<host>:8443,會話 cookie 自動帶 Secure。
放在反代之後¶
反代只做 TLS,上游填 http://<dsh-host>:3081,並開啓 WebSocket。不需要任何 Host 改寫配置——這正是插件要消掉的部分。
純局域網¶
明文 HTTP + 密碼,最簡單也最不安全,會話 cookie 可被嗅探。
常用配置鍵¶
| 鍵 | 默認 | 說明 |
|---|---|---|
listenHost |
0.0.0.0 |
閘門監聽地址 |
listenPort |
3081 |
閘門端口,不能與 DSH 端口相同 |
password |
— | 明文密碼(啓動時哈希) |
passwordHash |
— | scrypt$N$r$p$salt$key,優先於 password |
sessionDays |
7 |
會話時長;0 = 關瀏覽器即失效 |
maxAttempts |
5 |
連續失敗次數,超過臨時鎖定 |
lockMinutes |
5 |
鎖定時長 |
polyfill |
true |
注入 crypto.randomUUID 兜底 |
title |
DSH Web Guard |
登錄頁標題 |
tls |
null |
{certFile, keyFile},啓用 HTTPS |
生成 scrypt 哈希:
node -e "import('./lib/auth.js').then(m=>console.log(m.hashPassword(process.argv[1])))" 'your-password'
它是什麼,不是什麼¶
這是一道「入口」,不是可選插件。裝上之後,它監聽 3081,請求轉給只聽迴環的 DSH(3080)。插件一旦不加載,3081 就停止監聽,內網和外網會同時打不開——而 DSH 本體還在跑,會話和數據都在,只是夠不着。如果已經把這地址開放到公網,這一點需要格外當心。
安全模型上要說清楚邊界:一個密碼、一個權限級別,它不是多用戶系統。DSH 的 agent 本身能執行代碼,任何登錄者都擁有該機器的執行權限——這是產品設計,不是閘門的缺陷。
前面表格裏做的事——把 /api 的 403 歸因於 Host 被反代改寫,以及「代理把 Host 改寫成迴環 authority 就能放行」——都出自該項目 README 的表述。如果這個模型與你環境裏柵欄的實際行爲不一致,先查 DSH 官方文檔再改配置。
適用場景與注意¶
適合:想把 DSH Web UI 暴露到內網或公網、又不想繼續抄 token 的人;已經架好 NPM/Caddy/Traefik、被 /api 403 卡住的人;想用一個原生設置頁管理密碼與會話的人。
務必注意:
- 不要卸載、也不要禁用它。不要執行
dsh plugin --profile web remove @lvxianchao/dsh-web-guard;不要從 profile 的package.json裏刪掉dsh.profile.bundles中這一項;也不要在cordis.patch.yml裏給它加disabled: true。DSH 的「設置 → 插件」頁是隻讀清單,只有狀態標籤,沒有開關,誤關基本發生在命令行。 - 要求 DeepSeek Harness
0.2.2-rc.1或更新(engines.dsh: >=0.2.2-rc.1 <0.3.0),Node>=22.19,許可證 MIT。宿主版本不匹配時整個 bundle 會被跳過——這時是閘門不啓動,應該升級 DSH,而不是刪掉插件。 - 插件以當前 dsh 進程權限運行,裝前應檢查源碼與許可證。
- 會話表會落盤到
<profile>/data/dsh-web-guard-sessions-<port>.json(0600,臨時文件 + rename 原子寫入),重啓 DSH 不會把已登錄瀏覽器踢下線——但重啓不等於吊銷,要全部吊銷用設置頁的「退出所有設備」。
如果不小心關掉了,恢復命令不依賴插件本身:
# 1) 重新裝回(本地目錄裝的就用 file:)
dsh plugin --profile web add file:/path/to/dsh-web-guard
# 或:dsh plugin --profile web add github:lvxianchao/dsh-web-guard
# 2) 重啓,3081 會重新監聽
sudo systemctl restart dsh-web
如果當初是加了 disabled: true,把那行刪掉再重啓;密碼哈希在 <profile>/data/dsh-web-guard.json,不丟。
真正的坑不在這兩條命令,而在於此刻你已經連不上這臺機器。閘門只代理 HTTP 入口,不碰 SSH;但如果遠程訪問都收在這一個域名上,插件一沒,只剩一條路——一條不經過它的後路。至少準備一條:宿主控制台(PVE / ESXi / 雲廠商 VNC)進容器或虛機執行上面兩條命令,或一條獨立 SSH 通道(內網直連、跳板機、VPN)。並且在今天、現在就驗證它能用,然後把恢復命令抄一份到你能從外面打開的地方。
結尾¶
dsh-web-guard 的價值在於把「抄 token、改 Host、挖日誌、明文 HTTP 報錯」這四件事收斂成一個插件,代價是它成了唯一的入口——好處和風險都來自這一點。安裝前先確認 DSH 版本夠新,裝後留一條不經過閘門的後路。
目錄頁:https://www.skillhub.cn/plugins/lvxianchao/dsh-web-guard
GitHub:https://github.com/lvxianchao/dsh-web-guard
npm:https://www.npmjs.com/package/@lvxianchao/dsh-web-guard