返回目录
安全与治理 插件

dsh-rgate

raomaiping-hash/dsh-rgate

Remote access login gate for DeepSeek Harness Web: password wall, /api gating, session cookies, Remote Access settings.

Stars
0
Forks
0
Issues
0
更新
今天

PROJECT TOPICS

项目标签

INSTALL REFERENCE

安装参考

未验证
dsh plugin --profile web add github:raomaiping-hash/dsh-rgate

该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。

PROJECT README

README

dsh-rgate

CI version license

中文 | English

A remote access login gate for the DeepSeek Harness Web UI. Put a password wall in front of the whole browser surface: anonymous visitors on a public (non-loopback) address see only a login page, and every /api RPC is refused until they authenticate.

Why

The Harness's built-in browser-trust fence (trustedHosts) is a DNS-rebinding defense, explicitly not authentication. Anyone whose Host header passes the fence can use the Web UI. This plugin adds the missing authentication layer for self-hosted deployments: IP scanners hit a login page instead of your agent.

What it does

  • Full-page login wall — a gate script is injected into every index.html (via webServer.tapIndex); unauthenticated non-loopback visitors are redirected to /rgate-login, a self-contained login page.
  • Complete /api gating — exact routes shadow the shipped /api prefix for all 52 unary RPCs plus /api/respond and /api/session.export. Loopback requests pass through; everything else needs a session cookie or gets 401 before the body is even parsed.
  • Cookie sessionsrgate_session, HttpOnly + SameSite=Strict, 7-day in-memory sessions; logout and password change invalidate all sessions.
  • Login throttling — 5 failed attempts per client → exponential backoff (30s doubling, capped at 16 min). Behind Cloudflare Tunnel the client key is Cf-Connecting-Ip (fallback X-Forwarded-For, then socket address), so one attacker cannot lock everyone out.
  • Audit logging — login success/failure/lockout and password changes go to the harness log (journald) without passwords.
  • Hashed password storage — scrypt (N=16384, r=8, p=1) with a random salt and constant-time comparison in ~/.dsh/remote-auth.json (mode 0600). Legacy plaintext files are migrated automatically. A forgotten password is recovered by deleting the file and restarting: the fresh password is printed once in the service log.
  • Remote Access settings section — a settings.section entry showing gate status, login/logout, and password change. Password display is hashed-only by design.
  • Origin validation on login/logout/password endpoints (cross-site form posts are refused).

Install

From GitHub (plain ESM, no build step and no install scripts — nothing runs at install time):

dsh plugin --profile web add github:raomaiping-hash/dsh-rgate

Pin a commit sha for reproducibility: later pushes cannot silently change what runs on your machine (dsh plugin --profile web add github:raomaiping-hash/dsh-rgate#<commit-sha>).

From npm or a tarball:

dsh plugin --profile web add dsh-rgate          # npm
dsh plugin --profile web add ./dsh-rgate-0.1.0.tgz   # tarball

Then restart the web profile. The plugin prints [rgate] 门禁已启用 … (or [rgate] gate enabled …) when it activates, and creates ~/.dsh/remote-auth.json with a random password on first boot:

journalctl -u deepseek-harness | grep rgate

Configuration

There is no config file for the gate itself. Two behaviors are worth knowing:

  • Loopback is always trusted. 127.0.0.1 / localhost / ::1 never see the wall — that is the admin path.
  • All other Hosts require login (LAN, Tailscale, public domain alike). If you want a friction-free host, protect it upstream instead (see below).

The password file lives at $DSH_HOME/remote-auth.json (default ~/.dsh/remote-auth.json — the harness convention, beside settings.yaml):

field meaning
version: 2 scrypt-hashed storage
salt, N, r, p, hash scrypt parameters and derived key
createdAt, updatedAt bookkeeping

HTTP endpoints added

Endpoint Method Purpose
/rgate-login GET Self-contained login page (redirects to / when already allowed)
/api/remote-auth.login POST {password} Verify password, set session cookie
/api/remote-auth.logout POST Drop session + clear cookie
/api/remote-auth.status GET {configured, authenticated, loopback}
/api/remote-auth.secret GET Loopback only: {mode, path, createdAt, updatedAt} — never the password
/api/remote-auth.password POST {current?, next} Change password (authenticated session, or loopback + current password)

Known limitations

  • WebSocket event streams are not gated. /api/events.mux and /api/events.host upgrades are owned by the shipped dsh-client-connection plugin; registering the same upgrade path throws, and pre-registering breaks boot. A fence-passing client can still open them and receive live session event frames. The robust fix is upstream: enable Cloudflare Access (Zero Trust) on your public domain, or put an authenticating reverse proxy (e.g. nginx auth_request) in front. That closes UI, API and WebSockets before traffic reaches the Harness.
  • RPC surface is pinned to a snapshot. The gate shadows the unary method table of the Harness version it was tested against; a Harness upgrade that adds RPCs needs those paths added to the UNARY table.
  • Sessions are in-memory. A Harness restart signs everyone out (7-day cookie otherwise).
  • Static assets are still served to unauthenticated visitors (they are public code); all data lives behind the API gate.

Threat model

The gate is an authentication layer for a single-password, personal/small-team deployment. It assumes the Harness process and its host filesystem are trusted; anyone who can read remote-auth.json or the process memory already owns the host. It is not a substitute for OS/network hygiene, HTTPS termination, or upstream access control on the public entry point.

Test

tests/smoke.mjs runs the plugin's real route handlers against a stubbed context in an isolated HOME (no real credentials touched):

node tests/smoke.mjs

License

MIT

CLASSIFICATION EVIDENCE

分类依据

项目类型插件
功能分类安全与治理
规则置信度

系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: security。