DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Tailscale Console — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-tailscale-console

Tailscale Console

DeepSeek Harness 的 Tailscale 远程访问运营面板:健康检查、HTTPS 入口开关、macOS 代理绕过、中继服务器运维、ACL 片段生成。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-tailscale-console@0.4.7
README兼容性版本

兼容性与来源证明

Tailscale Console 以 dsh-tailscale-console 发布,当前版本为 0.4.7。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/20

版本

0.4.7stable
2026/9/14
0.4.6stable
2026/9/14
0.4.5stable
2026/9/8
查看其余 10 个版本收起版本
0.4.4stable
2026/9/8
0.4.3stable
2026/9/7
0.4.2stable
2026/9/7
0.4.1stable
2026/9/7
0.4.0stable
2026/9/7
0.3.0stable
2026/9/7
0.2.6stable
2026/9/7
0.2.5stable
2026/9/7
0.2.3stable
2026/8/22
0.2.2stable
2026/8/20

相关插件

正在加载相关插件…

最新版
0.4.7
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
116.9 kB
文件数
13
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 1
周下载
382
安全扫描
✓ v0.4.7 扫描通过
最近提交
2026/9/14
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 security-access 分类下经过校验的插件。

Doctor@linxin666/dsh-doctorDSH 配置档案的事务性救援模式,配备受监督的启动器、隔离的恢复容器、确定性修复、健康监控以及本地 Web 恢复控制台Pocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。Auto Reviewdsh-auto-review针对 DeepSeek Harness 审批请求的第二模型 AI 自动审查:只读审查子代理在审批应答链上决定允许或拒绝,并采用故障关闭回退机制和完整的会话日志审计。

README

dsh-tailscale-console

A control panel for the DeepSeek Harness web GUI that operates secure remote access over Tailscale: one-click health checks, HTTPS entry (Tailscale Serve) toggle, macOS proxy bypass repair, relay-server ops, and an ACL snippet generator.

UI language: Chinese. Docs: English · 中文


Features

CardDescription
① Devices & online alertsPer-device online/offline state; auto-alerts when an offline device comes online
② Health checkOne-click verification of HTTPS entry, page, /api session list, remote /api RPC over HTTPS, server direct path, proxy bypass
③ HTTPS entryTailscale Serve status / URL + on/off toggle (with verification & retry)
④ Proxy bypassChecks *.ts.net / 100.64.0.0/10 in the macOS system proxy bypass list; one-click re-apply (macOS only)
⑤ Relay serverTailnet status of your relay server + enable Peer Relay + ping verify
⑥ AccessRemote HTTPS URL, local URL, and the exact dsh web start command
⑦ ACL snippetGenerates the tailscale.com/cap/relay grants JSON from live device IPs
⑧ Device pairingOne-click login link/QR for remote devices — re-pair from a device bookmark after restarts, with Add-to-Home-Screen (PWA)

Full Setup Guide (server → local machine → DSH)

Target architecture: the server joins the tailnet as a Peer Relay; the local machine exposes HTTPS via Tailscale Serve; DSH keeps listening on 127.0.0.1 only.

0. Prerequisites

  • Tailscale account (enable 2FA), MagicDNS enabled
  • A Linux server with a public IP (Ubuntu 22.04 in this guide)
  • Local macOS with the tailscale CLI installed and logged in
  • A dsh web profile (~/.dsh/profiles/web) — requires dsh ≥ 0.1.0-rc.6 (for --trusted-host and the webRuntime service)
  • Node 20.x + pnpm ≥ 9 for the profile (pnpm-lock.yaml is v9; the default pnpm 8 under Node 24 will fail. Verified with Node 20.19.2 + pnpm 10.27.0)
  • A phone with the Tailscale app installed and logged into the same account (for remote access testing)

How to find your tailnet values (the <...> placeholders below):

  • Local tailnet IP: tailscale ip -4
  • All devices: tailscale status
  • MagicDNS name (<hostname>.<tailnet>.ts.net): tailscale status --json | python3 -c "import json,sys; print(json.load(sys.stdin)['Self']['DNSName'].rstrip('.'))", or read it from the Tailscale admin console → Machines, or from the output of tailscale serve status once serve is up (section 2.1)
  • Server tailnet IP: tailscale status on the Mac (the Linux peer)

Tip: you can bring the panel up locally first with dsh web (loopback default) — card ⑥ then shows the real remote URL, start command and ACL JSON, which you can copy back into the steps below.

1. Server side

1.1 Install & authenticate Tailscale

ssh <server> 'curl -fsSL https://tailscale.com/install.sh | sh'
ssh <server> 'nohup tailscale up >/tmp/ts-up.log 2>&1 & sleep 4; cat /tmp/ts-up.log'
# Open the https://login.tailscale.com/a/xxxx link printed, authorize with your account.
# The server comes online automatically; `tailscale status` on the Mac should list it.

1.2 Enable the Peer Relay port + firewall

ssh <server> 'tailscale set --relay-server-port=40000 && ufw allow 40000/udp && ufw allow 41641/udp'
# 41641 = WireGuard direct port; 40000 = Peer Relay port

⚠️ Your cloud security group must also allow inbound UDP 40000 and 41641 (source 0.0.0.0/0) — the guest ufw cannot protect the cloud edge.

1.3 Verify the direct path (run on the Mac)

tailscale ping -c 3 <server-tailnet-ip>   # expect "via <public-ip>:41641" (tens of ms); DERP means 41641 is blocked

2. Local machine

2.1 HTTPS entry: Tailscale Serve (the core)

tailscale serve --bg 3080    # https://<hostname>.<tailnet>.ts.net → 127.0.0.1:3080, tailnet-only
tailscale serve status       # inspect; `tailscale serve reset` to disable

Why HTTPS is mandatory: browsers expose crypto.randomUUID only in secure contexts (HTTPS or localhost), and every DSH client RPC depends on it. The GUI at http://<tailnet-ip>:3080 will never work — debug only.

2.2 Proxy bypass (required if you run Clash-family proxies on macOS)

A local Clash proxy hijacks the private ts.net domain and breaks HTTPS in the browser. Add *.ts.net and 100.64.0.0/10 to the bypass list in Clash Verge → Settings → System proxy; or apply immediately:

networksetup -getproxybypassdomains "Wi-Fi"   # first: back up the current list
networksetup -setproxybypassdomains "Wi-Fi" "*.ts.net" "100.64.0.0/10" "*.local" "<local>" "localhost" "127.0.0.1" "192.168.0.0/16" "10.0.0.0/8" "172.16.0.0/12"

⚠️ -setproxybypassdomains replaces the whole exception list of that service — back it up first with -getproxybypassdomains. Non-macOS: the panel hides card ④ automatically; for Linux/Windows set the equivalent bypass, e.g. export NO_PROXY="*.ts.net,100.64.0.0/10" in your proxy tool or environment.

2.3 (Optional) socat debug forward

brew install socat
socat TCP-LISTEN:3080,bind=<local-tailnet-ip>,reuseaddr,fork TCP:127.0.0.1:3080
# curl/API debugging only; the GUI is unusable over plain HTTP (non-secure context)

3. DSH configuration

3.1 Start command (use this every time)

dsh web --trusted-host <local-tailnet-ip>:3080 --trusted-host <hostname>.<tailnet>.ts.net

⚠️ Every change below (cordis.patch.yml, plugin code, better-sidebar patch) requires restarting dsh web, which interrupts the currently running session — save/finish your work first. The web profile has HMR disabled.

3.2 Static trustedHosts (belt & braces)

Append to ~/.dsh/profiles/web/cordis.patch.yml:

- id: connection
  config:
    trustedHosts: ['<local-tailnet-ip>:3080', '<hostname>.<tailnet>.ts.net']

3.3 Known third-party issue: dsh-better-sidebar

If your profile installs dsh-better-sidebar, its /sidebar/api fence has a bug in version 0.10.3 (the latest published): trustedHostsOf() matches entry.options.name against "connection", but name is the package name, so the trust list is always empty and /sidebar/api/* is loopback-only (403 remotely — the sidebar breaks). No fixed upstream version exists yet.

Patch trustedHostsOf() in node_modules/dsh-better-sidebar/lib/index.js (back up the file first) to read the webRuntime service:

function trustedHostsOf(ctx) {
  const hosts = []
  const runtime = ctx.get("webRuntime")
  if (runtime !== void 0 && Array.isArray(runtime.trustedHosts)) hosts.push(...runtime.trustedHosts)
  for (const entry of ctx.loader.entries()) if (entry.options.id === "connection") {
    const cfg = entry.options.config?.trustedHosts
    if (Array.isArray(cfg)) hosts.push(...cfg)
  }
  return [...new Set(hosts)]
}

⚠️ The patch lives in node_modules and is lost on the next pnpm install — re-apply after every reinstall (check with grep -c 'options.id === "connection"').

4. ACL grant (required for phone relaying)

console.tailscale.com/admin/acls → JSON editor, add to grants:

{
  "grants": [
    {
      "src": ["<device-A-ip>", "<device-B-ip>"],
      "dst": ["<server-tailnet-ip>"],
      "app": { "tailscale.com/cap/relay": [] }
    }
  ]
}

(src = devices allowed to relay, dst = the relay server. Without it, phone traffic falls back to official DERP, 400ms+. Card ⑦ generates this for you.)

5. Install this plugin

The package declares dsh.bundle, so the official CLI installs and auto-mounts it into the profile's bundle stack — one command, no profile file edits:

# npm source (published): auto-appends to dsh.profile.bundles + mounts
dsh plugin --profile web add dsh-tailscale-console

# or install straight from the repo (also auto-mounts — the repo ships cordis.patch.yml at its root)
dsh plugin --profile web add github:evanfang0054/dsh-tailscale-console

Restart dsh web → Settings → Tailscale Console.

Optional per-user options (like sshAlias) are machine-specific and are not part of the bundled patch. Override them from the profile's own cordis.patch.yml by targeting the same entry id:

cd ~/.dsh/profiles/web
pnpm add "dsh-tailscale-console@file:./packages/dsh-tailscale-console"   # local dev: file: reference
# append to ~/.dsh/profiles/web/cordis.patch.yml (optional overrides)
- id: tailscale-console
  config:
    sshAlias: my-server    # optional: ssh alias for server-side mutations (install/relay)

⚠️ If you previously mounted this plugin the manual way (an - insert: line in cordis.patch.yml), remove that line before switching to the dsh plugin add bundle channel — keeping both double-mounts the plugin (two host halves, two panels).

6. Verification checklist

# HTTPS entry
curl -s -o /dev/null -w "%{http_code}\n" --noproxy '*' https://<hostname>.<tailnet>.ts.net/      # 200
# /api fence
curl -s --noproxy '*' -X POST https://<hostname>.<tailnet>.ts.net/api/session.list \
  -H 'content-type: application/json' \
  -d '{"type":"client-request","rpcId":"t-1","method":"session.list","payload":{}}' | head -c 120  # ok:true
# panel host route
curl -s -o /dev/null -w "%{http_code}\n" --noproxy '*' -X POST \
  https://<hostname>.<tailnet>.ts.net/tsctl/api/config -H 'content-type: application/json' -d '{}'   # 200
# direct path
tailscale ping -c 3 <server-tailnet-ip>
# Final: open https://<hostname>.<tailnet>.ts.net on any tailnet device — the sidebar lists all sessions

Configuration

All values come from the plugin Config; the code contains no personal identifiers. MagicDNS URLs and tailnet IPs are auto-derived from tailscale status --json when not configured.

KeyTypeDefaultMeaning
dshPortnumber3080DSH web GUI port
relayPortnumber40000Relay server's Peer Relay UDP port
tailnetUrlstringautoHTTPS base, e.g. https://myhost.tail1234.ts.net
sshAliasstring—SSH alias for server-side mutations (install / relay)
serverPeerPatternstringfirst Linux peerRegex to identify the relay server peer
proxyServicesstring[]macOS setNetwork services for the bypass apply

Security model

  • Fixed command allowlist: every button maps to a hard-coded command; the client cannot pass free-form input.
  • Sandbox: commands run with an explicit danger-full-access sandbox policy (same as the model's bash tool session policy). The default workspace-write confinement kills the detached child of tailscale serve --bg, breaking the HTTPS "on" toggle. Blast radius stays bounded by the allowlist.
  • Browser-trust fence: the /tsctl/api prefix accepts only loopback Hosts or hosts in dsh's --trusted-host list (same fence as dsh's own /api).
  • Platform: proxy bypass cards are macOS-only; other platforms degrade gracefully.

Troubleshooting

SymptomCauseFix
Panel missing after restart, host route 200exports lacks "./package.json" — client scan (require.resolve('<pkg>/package.json')) is blocked by Node exports encapsulationadd "./package.json": "./package.json" to exports; restart
Stale code served after editing sourcespnpm file: deps are hard-linked copiesre-symlink: ln -s ../packages/dsh-tailscale-console node_modules/dsh-tailscale-console
HTTPS "on" fails silentlysandbox kills serve --bg's daemonfixed in code (explicit policy + verify/retry)
"On" button dead after HTTPS entry is offchicken-and-egg: the HTTPS page itself is unreachable once serve is off (connection refused)open the panel at http://127.0.0.1:<port> on the local machine and toggle on (remote page shows a hint)
Settings/credentials page 403 remotelydsh PRIVILEGED_METHODS design limitoperate locally; do not relax
Health check "/api session list" always ✗, detail shows a mid-body fragment (e.g. 2144},"contextBreakdown"...)dsh's shell service truncates long stdout keeping only the tail (~63KB cap); the session.list response far exceeds it, so curl-based stdout loses its head and JSON.parse always failsfixed built-in (0.2.3+): Host requests 127.0.0.1 directly via node:http, bypassing the shell
Phone access is slowACL grants not savedsee section 4
tailscale ping (TSMP) works, but real TCP/ICMP all time outcontrol-plane ACL lost the default allow rule (only custom rules like the Peer Relay grant remain); tailscaled logs show Drop: ... no rules matchedre-add the default rule at the top of grants (below) — propagates in ~30s, no restart

Default ACL rule (new grants format — three requirements)

When configuring a Peer Relay, the default "allow all connections" rule is easily overwritten. Once lost, every real packet is dropped by the ACL filter with no rules matched, while TSMP ping keeps working (internal path, bypasses ACL) — the classic "ping works, data doesn't" illusion. Always keep the default rule first:

{
  "grants": [
    { "src": ["*"], "dst": ["*"], "ip": ["*"] },
    { "src": ["<device IP>"], "dst": ["<relay server IP>"],
      "app": { "tailscale.com/cap/relay": [] } }
  ]
}

New grants requirements: dst takes no port; an explicit ip field is mandatory; app and ip cannot both be empty.

Inspect commands:

  • Server: journalctl -u tailscaled | grep "no rules matched"
  • macOS: log show --last 30m --predicate 'eventMessage CONTAINS "no rules matched"'

License

MIT. The browser-trust fence mirrors dsh's api-request-trust logic (see @deepseek-ai/dsh-client-connection).