Back to home@ZnFr60

dsh-lan-access-for-rpi-os-or-debian

Raspberry Pi 64-bit (aarch64) LAN access + boot auto-start installer for the DeepSeek Harness (dsh) Web UI: phone/LAN devices control dsh from a browser (0.0.0.0 bind, /api trust fence, crypto.randomUUID polyfill, privileged-API fix, systemd auto-start).

Stars
1
Language
Shell
Created
Aug 26, 2026
Updated
Aug 26, 2026

Introduction

dsh-lan-access for RPI OS or Debian

⚠️ 安全警告 / SECURITY WARNING 仅限可信局域网内部使用!严禁暴露公网! 当前版本没有身份认证,局域网内任何人只要访问该网页,即可操控本机执行 shell 命令。请在可信网络内使用,并参考下方「安全说明」加固。 Trusted LAN only! Never expose to the public internet! There is no authentication in the current version — anyone on your LAN who can open the page can control the machine and run shell commands. Use only on a trusted network and follow the Security notes below.

DeepSeek Harness (dsh) LAN-access for Raspberry Pi OS / Debian (64-bit, aarch64) — a one-shot installer that opens LAN access and boot auto-start for the dsh Web UI, so any device on your trusted home network can fully control dsh from a browser (phone / computer / others), exactly like on the Pi itself.

专为 Raspberry Pi OS / Debian(64 位, aarch64) 上的 DeepSeek Harness(dsh)Web UI 提供局域网访问 + 开机自启动的一键工具,让同局域网内任意设备(手机/电脑/其他设备)都能用浏览器完整操控 dsh,与树莓派本机完全一致。

中文 | English


中文

这是什么

适用平台:Raspberry Pi OS / Debian(64 位, aarch64)。脚本为 Bash,面向 Linux 系(Debian)环境; Windows 用户请使用专门的 dsh-lan-access-for-windows

本仓库是一个 DSH 局域网访问 + 开机自启动的一键自动化脚本(配套 systemd 服务模板与特权接口修复工具)。安装后,同局域网内任意设备(电脑 / 手机 / 其他设备)都能用浏览器完整操控 dsh Web:发送指令、审批权限弹窗、查看编译日志,以及设置 / 凭据页面 —— 与树莓派本机完全一致。

只改动 DSH 自身配置 / 插件用户目录下的 systemd 配置不触碰 Raspberry Pi OS 系统核心文件,不绑定公网。

它解决什么(背景)

dsh 官方出于安全考虑(DNS rebinding / 跨站防护)默认仅允许本机回环访问

现象原因
局域网 / 手机访问 /api/* 返回 403browser-trust 围栏只信任回环或 --trusted-host
明文 HTTP 下会话 / 模型列表空白crypto.randomUUID() 仅存在于安全上下文
设置 / 凭据页空白特权接口(settings.*credentials.* 等)被硬编码为仅回环

官方 CLI 还禁止 --host 0.0.0.0。本工具通过社区插件 + 一处 DSH 自身代码的最小改动,完整解决以上全部问题。

原理(技术栈)

  1. dsh-web-lan-access 插件(npm 包,作者 AcidGr)—— 自包含的 DSH bundle,自动完成:
    • 把 webserver 绑定改为 0.0.0.0(绕开 CLI 对 --host 0.0.0.0 的拒绝)
    • /api 信任围栏扩展到本机所有非内网 IPv4(局域网 / Tailscale / VPN)
    • 注入 crypto.randomUUID polyfill(修复明文 HTTP 下 UI 空白)
  2. 特权接口修复src/apply-privileged-fix.sh)—— 把 DSH 自身插件里硬编码的回环门禁改为跟随部署的 trusted-hosts,使设置 / 凭据页在局域网可用。
  3. systemd 用户服务src/dsh-web.service)—— 开机自启动,linger 让其在无登录状态下运行。

快速开始

git clone https://github.com/ZnFr60/dsh-lan-access-for-rpi-os-or-debian.git
cd dsh-lan-access-for-rpi-os-or-debian

# (可选)先按需改配置:cp config.env.example config.env && nano config.env

./install.sh

完成后会打印局域网访问地址,类似:

================= RESULT =================
[dsh-rpi-lan] dsh web is running: pid=... cwd=/home/pi/Desktop/dsh
[dsh-rpi-lan] listening on:  0.0.0.0:3080

  手机 / 电脑 / 局域网任意设备浏览器访问:
      http://192.168.1.27:3080
==========================================

在手机 / 电脑 / 其他设备浏览器打开 http://<树莓派局域网IP>:3080 即可。

命令一览

命令作用
./install.sh一键配置 + 安装 + 开机自启 + 重启 + 打印 URL(幂等,可重复运行)
./install.sh status只查看当前状态,不做任何改动
./install.sh uninstall停止并禁用自启服务(插件保留,可按提示手动移除)
./install.sh help显示帮助

兼容性

本工具针对 DSH v0.18.0 设计并实测通过。 后续版本若 DSH 内部 API / 插件机制(webserver 配置、browser-trust 篱笆、特权接口门禁)发生变动,本工具可能失效;升级 DSH 后请重新验证,或关注本仓库更新。

前置要求

  • Raspberry Pi OS(Debian 系,aarch64)已安装 Node.js + npm
  • 已全局安装 DeepSeek Harnessnpm install -g @deepseek-ai/dsh
  • 需要 sudo(用于 loginctl enable-linger,实现无登录自启动)
  • 树莓派与手机等设备处于同一局域网

脚本会自动完成:安装 pnpm(用户目录,无需 sudo)、补齐 PATH / DSH_HOME 环境变量、安装插件、写 systemd 服务、启用 linger、重启服务。

配置变量(config.env,全部可用环境变量覆盖)

复制 config.env.exampleconfig.env 后编辑;也可直接命令行覆盖:PORT=3080 ./install.sh

变量默认值说明
DSH_HOME$HOME/.dshDSH 安装根目录
PROFILEweb托管浏览器 UI 的 profile
PORT3080Web 监听端口
PLUGIN_NAMEdsh-web-lan-accessnpm 插件名
PLUGIN_GITHUBgithub:AcidGr/dsh-web-lan-accessnpm 不可用时回退的 GitHub 源
WORKSPACE_DIR$HOME/Desktop/dsh工作目录(即 agent 的 workspace / 你的项目目录)
PNPM_PREFIX$HOME/.npm-globalpnpm 用户安装前缀
PNPM_VERSIONlatestpnpm 版本
SERVICE_NAMEdsh-websystemd 用户服务名
SYSTEMD_USER_DIR$HOME/.config/systemd/usersystemd 用户单元目录
ENABLE_PRIVILEGED_FIX1是否应用特权接口修复(设 0 关闭;仅影响设置/凭据页)

目录结构

dsh-lan-access-for-rpi-os-or-debian/
├── install.sh                     # 主自动化脚本(幂等)
├── config.env.example             # 全部变量 / 环境变量说明与默认值
├── README.md                      # 双语说明(中文 / English)
├── LICENSE
├── src/
│   ├── dsh-web.service            # systemd 用户服务模板(占位符由 install.sh 替换)
│   └── apply-privileged-fix.sh    # 特权接口修复工具(on/off/status,幂等,含备份)

安全说明(请务必阅读)

  • 绑定 0.0.0.0 意味着同一局域网内任何人无需登录即可访问(/api 是来源围栏,不是身份认证)。
  • 仅用于可信的家庭局域网不要做公网端口转发。
  • 如需更强隔离,建议:
    • 本机防火墙限制来源,例如:sudo ufw allow from 192.168.0.0/16 to any port 3080
    • 或用 Tailscale / 带认证的反向代理接入。
  • 本项目只修改 DSH 自身配置 / 插件,以及 ~/.config/systemd/user/ 下的服务文件,不修改系统核心文件。

故障排查

手机 / 局域网设备打不开网页或 /api 403

  • 确认树莓派与设备在同一局域网。
  • 确认服务在监听:systemctl --user status dsh-web.service 应为 active (running);端口 ss -tln | grep :3080 应显示 0.0.0.0:3080
  • 局域网请求被防火墙拦截:用 ufw 放行端口(需管理员):
    sudo ufw allow from 192.168.0.0/16 to any port 3080 proto tcp
    sudo ufw status
    
    若用其他防火墙(firewalld/iptables),按同理放行 TCP 3080
  • 换用本机回环测试确认服务本身正常:curl http://127.0.0.1:3080/ 应返回 HTML。

设置 / 凭据页在手机端空白或报错

  • 多为特权接口回环门禁未放行。确认 ENABLE_PRIVILEGED_FIX=1 且已应用:
    bash src/apply-privileged-fix.sh status   # 应显示 fix APPLIED
    

DSH 升级后失效

  • 见「兼容性」说明:升级后重新运行 ./install.sh 并验证;若仍异常,请提 issue 并注明 DSH 版本。

Windows 用户(另见 dsh-lan-access-for-windows

  • 端口被 Windows 防火墙拦截:需放行入站规则;PowerShell 执行策略报错:用 powershell -ExecutionPolicy Bypass -File install.ps1

卸载(零残留)

下面步骤完整移除本工具留下的所有痕迹(服务、插件、特权修复、配置文件):

# 1) 停止并禁用自启服务,删除 systemd 用户单元文件
systemctl --user stop  dsh-web.service
systemctl --user disable dsh-web.service
rm -f ~/.config/systemd/user/dsh-web.service
systemctl --user daemon-reload

# 2) (可选)还原特权接口修复为官方原版
bash src/apply-privileged-fix.sh off

# 3) 从 DSH web profile 移除插件依赖
dsh plugin --profile web remove dsh-web-lan-access

# 4) 删除本工具本地副本(含 config.env)
rm -rf /path/to/dsh-lan-access-for-rpi-os-or-debian

说明:脚本写入 ~/.bashrc / ~/.profilePATH 追加行($HOME/.npm-global/bin)为幂等增量,如需彻底清理可手动删除该行;sudo loginctl enable-linger 如需撤销可执行 sudo loginctl disable-linger $(whoami)

许可证

MIT


English

What is this

Supported platforms: Raspberry Pi OS / Debian (64-bit, aarch64). This is a Bash installer for Linux (Debian-family) systems. Windows users should use the dedicated dsh-lan-access-for-windows.

This repository is a one-shot automation installer for DSH LAN access + boot auto-start (plus a systemd service template and a privileged-API fix tool). After installing, any device on the same LAN — computer, phone, others — can fully control the dsh Web UI from a browser: send commands, approve permission popups, view compile logs, and use Settings / credentials pages, exactly like on the Pi itself.

It modifies only DSH's own config/plugins and the systemd config in your home directory — it never touches Raspberry Pi OS core system files, and never exposes your server to the public internet.

Background / the problems it solves

For security (DNS-rebinding and cross-site defense), dsh by default only allows loopback access:

SymptomCause
/api/* returns 403 from LAN / phonebrowser-trust fence trusts only loopback or --trusted-host
sessions / model list is blank over plain HTTPcrypto.randomUUID() exists only in secure contexts
Settings / credentials pages are blankprivileged methods (settings.*, credentials.*, …) are hard-pinned to loopback

The official CLI also rejects --host 0.0.0.0. This project fixes all of the above via a community plugin plus one minimal change to DSH's own code.

How it works (tech stack)

  1. dsh-web-lan-access plugin (npm package by AcidGr) — a self-contained DSH bundle that automatically:
    • switches the webserver bind host to 0.0.0.0 (bypassing the CLI's --host 0.0.0.0 rejection)
    • widens the /api trust fence to every non-internal IPv4 on the host (LAN / Tailscale / VPN)
    • injects a crypto.randomUUID polyfill (fixes the blank UI over plain HTTP)
  2. Privileged-API fix (src/apply-privileged-fix.sh) — relaxes the hard-coded loopback gate in DSH's own plugin so those methods follow the deployment's trusted hosts, making Settings / credentials usable over the LAN.
  3. systemd user service (src/dsh-web.service) — auto-starts on boot; linger lets it run without any login.

Quick start

git clone https://github.com/ZnFr60/dsh-lan-access-for-rpi-os-or-debian.git
cd dsh-lan-access-for-rpi-os-or-debian

# (optional) copy and edit config first: cp config.env.example config.env && nano config.env

./install.sh

When finished it prints your LAN address, e.g.:

================= RESULT =================
[dsh-rpi-lan] dsh web is running: pid=... cwd=/home/pi/Desktop/dsh
[dsh-rpi-lan] listening on:  0.0.0.0:3080

  Open in a browser from any phone / computer / LAN device:
      http://192.168.1.27:3080
==========================================

Then open http://<your-pi-LAN-IP>:3080 in a browser on any device.

Commands

CommandEffect
./install.shconfigure + install + auto-start + restart + print URL (idempotent; safe to re-run)
./install.sh statusreport current state only, change nothing
./install.sh uninstallstop and disable the auto-start service (plugin kept; remove manually if desired)
./install.sh helpshow help

Compatibility

Designed and tested against DSH v0.18.0. Future releases may change internal DSH APIs / plugin mechanisms (the webserver config, the browser-trust fence, or the privileged-method gate) and could break this tool. Re-verify after upgrading DSH, and watch this repo for updates.

Prerequisites

  • Raspberry Pi OS (Debian-family, aarch64) with Node.js + npm
  • DeepSeek Harness installed globally: npm install -g @deepseek-ai/dsh
  • sudo access (for loginctl enable-linger, so it auto-starts without login)
  • The Pi and your devices are on the same LAN

The script automatically: installs pnpm (into your home dir, no sudo), adds the PATH / DSH_HOME environment variables, installs the plugin, writes the systemd service, enables linger, and restarts the service.

Configuration (config.env, every value overridable via environment)

Copy config.env.example to config.env and edit; or override inline: PORT=3080 ./install.sh

VariableDefaultDescription
DSH_HOME$HOME/.dshDSH install root
PROFILEwebprofile hosting the browser UI
PORT3080web listen port
PLUGIN_NAMEdsh-web-lan-accessnpm plugin name
PLUGIN_GITHUBgithub:AcidGr/dsh-web-lan-accessGitHub source fallback if npm unavailable
WORKSPACE_DIR$HOME/Desktop/dshworking dir (the agent's workspace / your project)
PNPM_PREFIX$HOME/.npm-globaluser install prefix for pnpm
PNPM_VERSIONlatestpnpm version
SERVICE_NAMEdsh-websystemd user service name
SYSTEMD_USER_DIR$HOME/.config/systemd/usersystemd user unit dir
ENABLE_PRIVILEGED_FIX1apply the privileged-API fix (0 disables; only Settings/credentials pages are affected)

Directory layout

dsh-lan-access-for-rpi-os-or-debian/
├── install.sh                     # main automation script (idempotent)
├── config.env.example             # all variables / environment variables
├── README.md                      # bilingual (中文 / English)
├── LICENSE
├── src/
│   ├── dsh-web.service            # systemd user service template (placeholders filled by install.sh)
│   └── apply-privileged-fix.sh    # privileged-API fix tool (on/off/status, idempotent, keeps a backup)

Security notes (please read)

  • Binding 0.0.0.0 means anyone on the same LAN can access without logging in (/api is an origin fence, not authentication).
  • Use only on a trusted home network; do NOT port-forward it to the public internet.
  • For stronger isolation, consider:
    • a host firewall limiting source, e.g. sudo ufw allow from 192.168.0.0/16 to any port 3080
    • or Tailscale / an authenticated reverse proxy.
  • This project only touches DSH's own config/plugins and files under ~/.config/systemd/user/; it does not modify system core files.

Troubleshooting

Can't open the page from a phone / LAN device, or /api returns 403

  • Make sure the Pi and your device are on the same LAN.
  • Confirm the service is running: systemctl --user status dsh-web.service should be active (running); the port ss -tln | grep :3080 should show 0.0.0.0:3080.
  • LAN requests blocked by the firewall — allow the port with ufw (admin):
    sudo ufw allow from 192.168.0.0/16 to any port 3080 proto tcp
    sudo ufw status
    
    For other firewalls (firewalld/iptables), allow TCP 3080 the same way.
  • Sanity-check the server itself on loopback: curl http://127.0.0.1:3080/ should return HTML.

Settings / credentials pages are blank or error on the phone

  • Usually the privileged-API loopback gate wasn't relaxed. Confirm ENABLE_PRIVILEGED_FIX=1 is applied:
    bash src/apply-privileged-fix.sh status   # should show "fix APPLIED"
    

Broken after upgrading DSH

  • See the Compatibility note: after upgrading, re-run ./install.sh and verify; if it still fails, open an issue and mention your DSH version.

Windows users (see also dsh-lan-access-for-windows)

  • Port blocked by Windows Firewall: add an inbound allow rule; PowerShell execution-policy error: run powershell -ExecutionPolicy Bypass -File install.ps1.

Uninstall (zero residue)

These steps remove everything this tool leaves behind (service, plugin, privileged fix, config):

# 1) Stop & disable the auto-start service, delete the systemd user unit
systemctl --user stop  dsh-web.service
systemctl --user disable dsh-web.service
rm -f ~/.config/systemd/user/dsh-web.service
systemctl --user daemon-reload

# 2) (optional) revert the privileged-API fix to stock dsh
bash src/apply-privileged-fix.sh off

# 3) remove the plugin dependency from the dsh web profile
dsh plugin --profile web remove dsh-web-lan-access

# 4) delete the local copy of this repo (incl. config.env)
rm -rf /path/to/dsh-lan-access-for-rpi-os-or-debian

Note: the script appends an idempotent PATH line ($HOME/.npm-global/bin) to ~/.bashrc / ~/.profile; delete that line manually if you want a fully clean shell. To undo linger, run sudo loginctl disable-linger $(whoami).

License

MIT