JUANWANG-BUAA/dsh-full-remote ↗★ 44

dsh-full-remote

通过令牌保护的反向代理实现安全的远程访问。 适合需要跨设备远程访问、穿透公网且需保障配置与凭据安全的用户。

包名
dsh-full-remote
兼容性
待验证
Harness 依赖范围
>=0.1.1-rc.1 <0.2
Cordis 依赖范围
>=4.0.1 <5
版本
0.3.12
许可证
MIT
最近更新
2026年9月19日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:JUANWANG-BUAA/dsh-full-remote

Usage

Starting and stopping

On the settings page, press Start proxy to start the listener and Stop proxy to stop it.

Listen address

BindPurpose
127.0.0.1 (default)The tunnel runs on the same machine
192.168.x.xA device on the same network, without a tunnel
0.0.0.0 / ::Bind every interface. This is not an address to open; the panel reports a separate reachable address.

The listen address can be changed at runtime and persists across restarts. If a new address fails to bind, the proxy rolls back to the previous working address.

The copyable tunnel target (and any extra reachable URL the panel lists) is what a remote client should open. Binding 0.0.0.0 only listens; it is not a URL.

backendHost is the address the proxy connects to, not the address it listens on. Keep it at 127.0.0.1.

Phone invite

The QR encodes a one-time login URL. Public / reachable Origin is the host the scanning device will request: the tunnel's https://…, or the LAN URL from the panel. Leave it empty only when the tunnel target above is already that address.

Do not put 127.0.0.1 in Origin. That address is the Harness machine; a phone would open its own loopback and never reach the proxy.

Then press Generate invite. After a scan (or opening the link) the login page submits once. The invite expires in 15 minutes, works once (same-IP retries within 60 s reuse the original session), and does not contain the standing token. Invites can only be generated while the proxy is running.

Upgrade

Download the current GitHub release and add its tarball to the existing web profile:

curl -fLO https://github.com/JUANWANG-BUAA/dsh-full-remote/releases/download/v0.3.12/dsh-full-remote-0.3.12.tgz
dsh plugin --profile web add ./dsh-full-remote-0.3.12.tgz

Then restart dsh web. This replaces an older registry-installed or tarball version with v0.3.12.

Language

The plugin panel has a Language / 语言 selector: Auto, English, or 中文. Auto follows the Harness locale when available, otherwise your browser language (English for non-Chinese browsers). An explicit choice is saved per browser and origin and also applies to remote confirmation overlays. Login, approval-wait, and device-home pages continue to follow the browser’s HTTP language header.

Configuration

Common options:

- id: reverse-proxy
  name: dsh-full-remote
  config:
    listenHost: 127.0.0.1
    listenPort: 3081
    approvalMode: false          # true: approve each new device locally
    allowedCidrs: []             # e.g. ["192.168.1.0/24"]; empty: any IP after login
    trustForwardedFor: false     # true: trust rightmost X-Forwarded-For from a trusted local tunnel
    trustCloudflareConnectingIp: false # true only with trustForwardedFor for a local Cloudflare connector
    upgradeMaxAttempts: 10       # failed WebSocket upgrades before lockout
    upgradeLockoutSeconds: 300   # lockout for repeated failed WebSocket upgrades
    headersTimeoutMs: 15000      # timeout for request headers
    requestTimeoutMs: 300000     # timeout for the complete request (headers + body); covers remote vision uploads
    upstreamTimeoutMs: 15000     # TCP connect + first POST byte after the body; not applied to SSE GET
    commandTimeoutMs: 300000     # first POST byte for host commands (/compact): /api/commands/execute, or a session.prompt whose single text part starts with "/"
    maxRequestBytes: 167772160   # 160 MiB; matches the Harness /api image envelope
    sessionIdleSeconds: 0        # 0: off; otherwise idle timeout in seconds
    auditLog: true
    allowTokenRead: false        # safer default; enable only for local token re-read
    cloudflaredPath: ""          # optional path to cloudflared for the one-click tunnel
    tlsCertFile: ""              # optional local HTTPS
    tlsKeyFile: ""
    compressResponses: true      # gzip JS/CSS/JSON/HTML ≥1KB; skip SSE/WebSocket/fonts/gate pages
    cacheHashedAssets: true      # immutable Cache-Control on hashed /assets/* only

The complete option list, with defaults and validation, is defined in the package Config schema (src/config.ts) and src/config-validation.ts (source is not included in the published package).

Two points to note:

  • Installing the plugin pins the in-app directory picker so that a phone can add workspaces. By default the stock adaptive picker is disabled and the browse pair is created at runtime unless another plugin already inserted it. Set DSH_FULL_REMOTE_USE_NATIVE_PICKER=1 before boot only when you deliberately want the host's native chooser and do not need remote directory browsing.
  • backendHost must remain a loopback address. A wildcard or non-loopback value is rejected at load time.