dsh-remote-access: Remote Access DSH Desktop via Private Networks (e.g., Tailscale)

Introduction

The desktop version of DSH binds the Web listener to loopback by default: dsh web’s --host only accepts specific addresses, and 0.0.0.0 is explicitly rejected at startup; desktop applications even launch the harness directly with --host 127.0.0.1 --port 0. Therefore, there is no native provision for opening this interface on devices outside the office.

The answer provided by the dsh-remote-access plugin maintained by icrefin is to introduce a gateway: instead of attempting to change the binding method of the existing listener, it adds a layer of reverse proxy on the mesh network address to forward requests to the harness on the local loopback. The installation panel is located at Settings → Remote Access and is disabled by default.

What Problem Does This Plugin Solve?

In a nutshell: On private mesh networks like Tailscale, ZeroTier, and NetBird, accessing the full client interface of your local DeepSeek Harness on a phone, tablet, or another computer, rather than a stripped-down remote control page.

Here is how it works:

 phone / laptop                    this machine
┌──────────────┐   WireGuard   ┌─────────────────────────────┐
│ browser      │──────────────▶│ 100.x.y.z:3080              │
│ (real DSH UI)│               │  └─ key gate → replay ──┐   │
└──────────────┘               │                          ▼  │
                               │   127.0.0.1:<random>  harness│
                               │   (unchanged, loopback only)  │
                               └─────────────────────────────┘

The browser loads the same page loaded by the local window; sessions, prompts, streaming outputs, terminals, and settings are naturally complete. The gateway only does a few things for each request: checks its own cookie, attaches the harness cookie it issued, rewrites Host to loopback, removes Origin/Referer/Sec-Fetch-*, and then streams the response back. WebSocket upgrades are transparently passed through as raw socket tunnels.

Since the mesh transmission itself is encrypted with WireGuard, the gateway runs plain HTTP on port 3080, does not terminate TLS, and explicitly does not pretend to terminate TLS.

Core Features

  1. A switch to enable remote access. The panel displays listener status, available links, and binding addresses.
  2. By default, it uses the detected 100.64.0.0/10 mesh address (shared by Tailscale, ZeroTier, and NetBird), prioritized over LAN addresses, to avoid exposing the agent to the local network on Wi-Fi in cafes.
  3. No key is set by default; the network itself is the access boundary: any mesh device that can reach that port has access.
  4. Optional Browser access key: Once enabled, enter the key once in each new browser; the browser only holds an HMAC cookie. Replacing the key invalidates all existing cookies.
  5. Tailscale’s MagicDNS names are used preferentially for links (e.g., http://host.tailnet.ts.net:3080/), remaining usable even if the address changes. Bare IP links also work when the CLI is unavailable.
  6. When the key is enabled, there is a login rate limit: a maximum of 8 failed attempts per client every 15 minutes.

The interface provided by the plugin (all from the README):

Interface Purpose
GET /api/dsh-remote-access/status Status of the listener, detected interfaces, binding errors
POST /api/dsh-remote-access/config Modify settings online, persisted via settings service
GET /api/dsh-remote-access/key Returns the link (includes key in link if enabled)
POST /api/dsh-remote-access/regenerate Replace key and invalidate all cookies
http://<mesh-address>:3080/ Optional key gate, then replay harness on loopback

Configuration fields:

Field Default Meaning
enabled false Whether the listener is running
port 3080 TCP port on mesh address
bindHost auto auto (detect mesh interface), all (0.0.0.0), or IPv4 address
requireKey false Whether the browser must provide a key first

The panel writes to harness’s settings service, and the configuration falls into cordis.patch.yml in the profile, persisting after restart. If a write fails to persist, the interface will display Applied, but not saved.

The plugin is installed as a bundle, comes with cordis.patch.yml, requires dsh 0.2.1-rc.5, Node >=22.17.0, and is licensed MIT.

Installation and Activation

The installation method given in the README is to build locally and install the tarball from the settings interface, not a direct CLI connection to the repository:

pnpm install
pnpm check        # typecheck both halves, build, run 86 tests
pnpm run pack     # -> dist/dsh-remote-access-0.1.2.tgz
scripts/install.sh

Note that the version number in the artifact name from pnpm run pack is a repository example; the current package.json version is 0.1.3, please refer to the actual build output.

After building is complete:

  1. Install the packaged tarball in Settings → Plugins, then restart the application. Running profiles cannot import new bundles; a restart is required.
  2. Open Settings → Remote Access.
  3. Click Enable mesh access; the panel will bind to the detected mesh address and display the link.
  4. Open the link on a device within the same mesh. By default, no key is required: the private network is the access boundary, and the node membership you manage in Tailscale/ZeroTier/NetBird is the authorization.
  5. Optional: If the network is shared, open Browser access key and enter the key once for each new browser; Replace key can revoke all access.

When used with Tailscale, it is recommended to restrict the port in the tailnet ACL. The example given in the README:

{ "action": "accept", "src": ["autogroup:member"], "dst": ["tag:my-mac:3080"] }

It is also emphasized: Do not use Tailscale Funnel. Funnel exposes the port to the public internet; the premise of this plugin is a private network.

Use Cases and Notes

Who is it for: People already using Tailscale/ZeroTier/NetBird who want to temporarily use their local DSH interface on another device within the mesh. This plugin provides you with an entry point with one address and one switch, without exposing the port to the public internet or planning to set up your own SSH tunnel yourself.

A few limitations you must know:

  1. The harness must be running. The gateway lives inside the harness process; if the machine sleeps, remote access is cut off.
  2. One process proxies one harness instance (i.e., this profile).
  3. There is no TLS termination, nor certificate management. Security relies on the WireGuard layer and your tailnet ACL.
  4. Mesh addresses are not affected by LAN changes, but Tailscale re-logins may change the address; the panel will re-bind within one minute.
  5. This plugin runs with the permissions of the current dsh process. You should read the source code and check the license (MIT) before deciding whether to install.
  6. Revoking access requires either removing the device from the network ACL or, if the key is enabled, replacing the key. There is no per-device key list.

Conclusion

The value of dsh-remote-access lies in the fact that it does not attempt to rewrite harness’s listening strategy, but rather fills the gap of a “full client accessible within a private network”: a gateway, a switch, and a link, disabled by default and bound to mesh addresses by default. If your access needs are limited to a mesh you manage yourself, this is currently a relatively clean solution.

  • Directory page: https://www.skillhub.cn/plugins/icrefin/dsh-remote-access
  • GitHub: https://github.com/icrefin/dsh-remote-access
羽毛球分组比赛记分
小程序二维码

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

Xiaoye