DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

hxt9805 /

hxt9805/dsh-remote-tailscale

Verified

DSH plugin: open the local DSH web UI on your other Tailscale devices

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@1d3319d0

dsh-remote-tailscale

English | 中文

A DSH plugin that publishes the full local DSH web UI to your other devices — phone, tablet, or another computer — over your Tailscale tailnet.

No shared LAN or Wi-Fi is needed. The two devices do not have to be on the same network: Tailscale builds the network, and signing in to the same Tailscale account is both the connectivity and the authentication. If you don't have Tailscale yet, install it on this computer and on the other device, and sign in with the same account.

Security scope — read this first

  • Never Funnel, never public. This plugin only uses tailscale serve on its own HTTPS port (default 8455, never 443) and only binds a loopback proxy on 127.0.0.1. It never runs tailscale funnel and never puts DSH on the public internet.
  • Do not enable Funnel, and do not forward or publish port 8455 / DSH by any other public means. If you enable Funnel or any other public exposure yourself, that is your own action outside this plugin — the plugin cannot manage or undo it, and the risk is yours.
  • Who gets in: devices signed in to the same Tailscale account (your tailnet). They see the full DSH web UI — same live page, WebSocket included. There is no second password: your Tailscale account is the authentication.
  • Off by default. Publishing is opt-in: nothing is served until you flip the switch in Settings → Remote access (or check the auto-start box). When DSH stops, the plugin removes its own serve mapping and nothing else.

Install

On a machine that already has DSH and Tailscale:

dsh plugin --profile web add github:hxt9805/dsh-remote-tailscale

Then restart DSH (dsh web) so the plugin loads.

Notes for humans and AI agents alike:

  • The install ships the committed lib/ bundle — no build step and no prepare script is needed or expected; do not run anything that would require allowBuilds.
  • Do not run tailscale funnel, do not publish port 8455 or DSH to the public internet, and do not change anything on port 443 — that is Tailscale's default HTTPS root and may be owned by another local app.

Or install from a local checkout:

dsh plugin --profile web add /absolute/path/to/dsh-remote-tailscale

A local-path install links this directory; do not move or delete it after install.

Uninstall:

dsh plugin --profile web remove dsh-remote-tailscale

Restart DSH again. On exit the plugin removes only its own Tailscale serve mapping.

First use

  1. On this computer and on the other device, sign in to the same Tailscale account. They do not need to be on the same Wi-Fi or LAN — that is the point of Tailscale.
  2. Start DSH (dsh web). Remote access is off by default.
  3. Open Settings → Remote access in the DSH web UI and flip the switch on.
  4. On the other device, open the URL the page shows, e.g. https://<machine>.<tailnet>.ts.net:8455/ — or just scan the QR code.

Windows: allow incoming connections for Tailscale (Windows Firewall / the Tailscale client), otherwise tailnet devices cannot connect. Tailscale not installed, not running, or signed out is reported honestly on the settings page — the plugin never pretends to be ready.

What it does

  1. Starts a loopback-only reverse proxy in front of DSH web (127.0.0.1, never 0.0.0.0). The proxy stays up even while remote access is off, so the status endpoint always answers.
  2. Publishes via tailscale serve on its own HTTPS port (default 8455, never 443, never Funnel) — but only when you turn it on.
  3. Exposes a local status endpoint so other tools on the same machine can see whether it is ready and what URL to open.

While the switch is on, the plugin probes Tailscale every few seconds (backend liveness first, then its own serve port). If Tailscale drops, it immediately reports not-ready, clears the URL and QR code, and shows the reason; when Tailscale comes back and the switch is still on, it republishes once with backoff (5/15/30/60 s) — it never hammers serve enable. If you flip the switch off, it never re-enables by itself; turning off only removes the mapping on its own port — never serve reset, never 443.

It does not do LAN passwords, public tunnels, desktop auto-update, or HTML injection.

The settings page (the only entry)

Remote access has exactly one entry: Settings → Remote access, a top-level settings page (same level as General / Models / Plugins). It carries:

  • the on/off switch, with live status (Ready / Off / Not ready / Switching) and the honest failure reason plus a Retry button when on-but-failed;
  • the full https://…ts.net:8455/ URL, one-click Copy URL, and a QR code;
  • the Auto-enable when DSH starts checkbox (off by default, persisted in $DSH_HOME/dsh-tailscale/prefs.json);
  • a short Never Funnel reminder — this plugin only serves your private tailnet.

The page follows the DSH UI language (Chinese and English are both built in; it tracks <html lang>, with the browser language as fallback). A former sidebar-footer entry and overlay were removed (2026-08): the footer row was crowding the Settings button.

Ports

What Default Notes
Loopback proxy 127.0.0.1:3091 Override with DSH_TS_PORT
Device HTTPS 8455 Override with DSH_TS_SERVE_PORT. 443 is refused so this plugin never takes Tailscale's default HTTPS root.

WSL: the plugin looks for Windows tailscale.exe (or DSH_TS_TAILSCALE). Mirror networking is required so Windows loopback reaches the WSL DSH process.

Local status (optional)

GET http://127.0.0.1:3091/__dsh_tailscale_status

{
  "ok": true,
  "ready": true,
  "url": "https://machine.tailnet.ts.net:8455/",
  "error": "",
  "proxyPort": 3091,
  "servePort": 8455,
  "dshPort": 3080,
  "ts": 1760000000000
}

A copy is also written to $DSH_HOME/dsh-tailscale/status.json (default ~/.dsh/dsh-tailscale/status.json) for humans. The folder and HTTP path keep the dsh-tailscale names so existing local tools keep working. Preferences (autoEnable, default false) live next to it in prefs.json. The settings UI talks to the host over a loopback Connection RPC on channel /dsh-remote-tailscale (tailscale.status / tailscale.setEnabled / tailscale.setAutoEnable); desired / autoEnable / busy / qr only exist on the RPC, not in the file or HTTP endpoint.

Develop

npm test              # pure functions + fake processes/ctx; never touches real Tailscale / real DSH
npm run build:client  # rebuild lib/client.js after changing client/ sources (esbuild, devDependency)

Structure:

  • lib/: the host half (proxy, tailscale commands, single-source status lib/status.js, prefs lib/prefs.js, RPC lib/rpc.js, built-in QR lib/qr.js). Host-side error copy is Chinese and asserted by tests.
  • client/: the web half sources (the settings page, the only entry; client/api.js is the RPC contract shared by both halves; client/i18n.js is the zh/en dictionary + UI-language detection + host-error EN translation).
  • lib/client.js: the build product (DSH window.__ModuleLoader__.load format), committed to the repo; after changing sources you must re-run npm run build:client (tests verify sync).
  • QR codes are zero-dependency: lib/qr.js ports the qrcode-generator algorithm (byte mode + ECC M + v1..10); golden vectors in test/qr-vectors.json.

License

MIT © 2026 hxt9805

—/ 5

No ratings yet

Verified DSH bundle

Commit 1d3319d0ebc6

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout