@pananfly/dsh-lan-access
v0.1.1
Published
Helper for dsh web LAN access: 127.0.0.1|0.0.0.0|::|custom IP webServer with BrowserAuth token, optional isLoopback patch
Maintainers
Readme
@pananfly/dsh-lan-access
Repository: https://github.com/pananfly/dsh-lan-access · npm:
@pananfly/dsh-lan-access
中文 | English
Helper plugin for dsh web — a drop-in webServer that binds 127.0.0.1 | 0.0.0.0 | :: | specific LAN/Tailscale IP, supports dual-stack and per-interface binding, keeps DSH's own BrowserAuth as the single auth source (process ?token= + HttpOnly;SameSite=Strict 30-day HMAC cookie), and patches the client's isLoopback so remote sessions get a persistent settingsScope. Ships ops helpers (async firewall rule sync + Host-fence posture probe) while relying on official directory-picker-auto for seamless native/browse directory selection.
Trusted-network only. Plain HTTP. Anyone with the
?token=URL or the derived cookie has full UI access. Do not expose the port to the public internet without TLS/tunnel.
What it does
- Flexible
webServerbinding — replaces officialwebServer, binds127.0.0.1(loopback),0.0.0.0(LAN IPv4),::(dual-stack with explicitipv6Only: false), or any specific LAN / Tailscale IP. - Auth delegated to DSH —
BrowserAuth(@deepseek-ai/dsh-client-connection) remains the only gate: rootGET /?token=<256-bit>mints an authority-bounddsh-auth-<hash>=v1.<body>.<sig>cookie (30d; HttpOnly; SameSite=Strict), and/apiis additionally gated by theHostfence (isLoopbackHostname || trustedHosts) +Origin == Host+Sec-Fetch-Site != cross-site. This plugin performs no request inspection. - Optional
isLoopbackpatch —--lan-patch(orDSH_LAN_PATCH=1) makesservePatchedBundlebuffer/pluginsbundles served by the client module registry (including??a,b&rev=...combo URLs), defensively gunzips if needed, flexibly rewritesisLoopback: true, stripscontent-encoding/length, forcescache-control: no-store, and re-negotiates gzip. RemotesettingsScopethen resolves tohostinstead ofmemory(remote edits persist across reload). - Guaranteed LAN
trustedHostsinjection — incordis.patch.yml,connectionexplicitly injectswebStartup, guaranteeing thattrustedHostsreceives private network literals, Tailscale IPs, and explicit--trusted-hostarguments, eliminating 403 Host-fence blocking. - Non-blocking firewall sync — asynchronously manages TCP allow rules (scoped with port names
dsh-lan-access (<port>)), supportingnetsh(Windows),firewalld/ufw/iptables(Linux, withip6tablessupport on::). - Posture probe — ~2.5 s after a LAN bind, probes loopback with forged LAN
Hostheaders to verify fence traversal without false positives. - Official adaptive directory picker — eliminates custom hybrid picker code and delegates directly to official
@deepseek-ai/dsh-host-directory-picker-auto: loopback sessions automatically use native OS dialogs, while LAN and remote sessions use the official in-app directory browser. crypto.randomUUIDpolyfill — a<head>regex tap injects a guarded polyfill for non-securehttp://<lan-ip>contexts.
Architecture
browser --http://<host>:3080/--> webServer (polyfill, optional patch)
--> DSH host /api (Host fence + BrowserAuth)
--> Harness| cordis row | id | provides | note |
|---|---|---|---|
| web-lan-startup | @pananfly/dsh-lan-access/startup | webStartup{host, port, trustedHosts} | replaces web-startup, validates bind host, gathers LAN & Tailscale IP literals |
| web-lan-webserver | @pananfly/dsh-lan-access/webserver | webServer (fakeRes compatibility + patch + polyfill) | replaces webserver, listens on configured IP/dual-stack, async firewall + posture probe |
| directory-picker | @deepseek-ai/dsh-host-directory-picker-auto | official | official adaptive chooser (native on loopback, browse on LAN/remote) |
Usage
Install
dsh plugin --profile web add @pananfly/dsh-lan-access
# or local development
dsh plugin --profile web add ./path/to/dsh-lan-accessHost / env
| var / flag | default | description |
|---|---|---|
| dsh web --host <host> | 127.0.0.1 | Bind host: 127.0.0.1, 0.0.0.0, ::, or specific LAN / Tailscale IP |
| dsh web --port <n> | 3080 | Listen port (0 lets the OS pick). |
| --no-open | | Do not open the browser (headless servers). |
| --trusted-host <authority...> | | Extra authority for the /api Host fence (host or host:port, repeatable) — public IPs/domains. |
| --lan-patch | false | Enable isLoopback patch for persistent remote settings. |
| DSH_LAN_PATCH | 0 | Set 1 to enable isLoopback patch. |
| connection.trustedHosts | auto | Injected from webStartup automatically. |
Examples
# 1. Loopback default
dsh web
# 2. LAN IPv4 bind-all
dsh web --host 0.0.0.0
# 3. Dual-stack bind (IPv4 + IPv6)
dsh web --host ::
# 4. Bind to specific interface (LAN IP or Tailscale IP)
dsh web --host 192.168.1.100
dsh web --host 100.64.0.5
# 5. LAN access with remote persistent settings (recommended: --lan-patch or DSH_LAN_PATCH=1)
dsh web --host 0.0.0.0 --lan-patch
# or: DSH_LAN_PATCH=1 dsh web --host 0.0.0.0
# 6. Reverse proxy / public domain
dsh web --host 0.0.0.0 --trusted-host dsh.example.comOpen the URL printed by dsh web (contains ?token=) to mint a 30-day HMAC cookie.
Development
pnpm install
pnpm build
pnpm typecheck
pnpm publish --access publicLicense
MIT
