Introduction

When DSH’s Web GUI is bound to the local loopback address, developers find it difficult to access it directly from other devices. Allowing DSH to listen on 0.0.0.0 exposes the Web API to untrusted networks easily.

rice-awa/dsh-lan-gateway resolves this contradiction using a reverse proxy gateway: it keeps DSH bound exclusively to 127.0.0.1, while the plugin runs a separate 0.0.0.0 gateway to forward traffic to the loopback port, applying different strategies for LAN and non-LAN sources.

Below is an introduction to its installation, activation, and configuration.

What is it

rice-awa/dsh-lan-gateway is a DSH plugin, owned by rice-awa, and licensed under MIT.

It securely exposes the DeepSeek Harness Web GUI to the LAN / WAN. The plugin provides a reverse proxy, a login page, session validation, optional TLS, a settings page card, and a lan_gateway management entry within the conversation.

The DSH ecosystem emphasizes “everything is a plugin”; the community directory is an independent site with no official affiliation to DeepSeek / Huanfang.

Core Features

Reverse Proxy and Source Classification

The plugin first ensures DSH remains bound only to 127.0.0.1, then launches a separate 0.0.0.0 reverse proxy gateway to forward traffic to DSH’s loopback port.

It rewrites the Host/Origin headers to pass through the /api trust fence.

Source classification relies solely on socket.remoteAddress and never trusts X-Forwarded-For.

  • LAN and loopback sources are proxied without password.
  • Non-LAN sources must complete the login page first and present an HMAC cookie.

Login and Sessions

The gateway provides a /__login login page with password validation using scrypt.

Login attempts are rate-limited to 5 times per minute based on the source.

Session cookies use HMAC-SHA256 and include:

HttpOnly; SameSite=Lax

Sessions can be invalidated using lan_gateway rotate-secret.

If authRequired: true and no password is set, enable will reject listening to avoid opening a door for remote code execution to non-LAN sources.

TLS

The plugin offers two TLS modes:

  • self-signed: Automatically generates and persists self-signed certificates.
  • custom: Mounts your own PEM certificate and private key.

A browser warning will be shown upon the first visit to a self-signed certificate; this is expected behavior.

After enabling TLS:

  • Login cookies automatically include the Secure flag.
  • The gateway’s own response includes HSTS.
  • Connections forwarded to DSH’s loopback remain plaintext HTTP.

Settings and Conversation Management

The official settings page card allows configuring port, subnet, authentication, and TLS, taking effect immediately upon saving.

The plugin also provides a lan_gateway tool to manage the gateway within DSH conversations.

It also provides the lan-gateway companion skill.

Password hashes and cookie secrets are stored at:

~/.dsh/lan-gateway/state.json

Keys are not included in the configuration.

Request Compatibility and CSRF Fence

The plugin provides crypto.randomUUID for the gateway’s plain HTTP pages.

For /api* requests, the gateway checks if sec-fetch-site matches the Origin; cross-site requests receive a direct 403.

WebSocket /api upgrade requests also undergo login validation before being forwarded to DSH.

Installation

The npm package is a pre-built artifact; building scripts do not need to be approved during installation. If prompted, you can write allowBuilds according to INSTALL.md.

dsh plugin --profile web add @riceawa/dsh-lan-gateway

After installation, the plugin does not listen on network ports by default; enabled is false by default.

Activation

First, enable the gateway:

lan_gateway enable

Check status:

lan_gateway status

Set password for non-LAN access:

lan_gateway set-password

Regenerate self-signed TLS certificate:

lan_gateway tls-regenerate

Disable the gateway:

lan_gateway disable

You can also speak directly in the DSH conversation:

  • Set gateway password to…
  • View gateway status
  • Enable / Disable gateway

After the steps above, the gateway will listen on network ports according to the current configuration and require login for non-LAN sources.

Configuration Example

In DSH Settings → Plugins → Configurable Plugins, expand the “LAN Gateway” card to modify configuration; changes take effect upon saving.

The example below enables self-signed TLS:

- id: dsh-lan-gateway
  config:
    enabled: true
    gatewayPort: 8443
    tlsEnabled: true
    tlsMode: self-signed
    tlsSelfSignedHosts: localhost, 192.168.1.5

When using your own PEM certificate and private key, you can switch to custom mode:

- id: dsh-lan-gateway
  config:
    tlsEnabled: true
    tlsMode: custom
    tlsCertPath: /path/to/cert.pem
    tlsKeyPath: /path/to/key.pem

Here, tlsCertPath is for the PEM certificate path and tlsKeyPath is for the PEM private key path.

Use Cases and Notes

Suitable for:

  • Developers who need to access the DSH Web GUI from devices other than the host.
  • LAN or WAN usage where LAN access is password-free and non-LAN requires login.
  • Users who require optional TLS and wish to manage gateway configuration via the settings page.

Notes:

  • The plugin runs with the current DSH process permissions; you should check the source code and license before installing.
  • Disabled by default; it only listens on network ports after running lan_gateway enable.
  • Non-LAN sources rely on the login page and session cookies; enabling it without a password is rejected.
  • Source classification relies solely on socket.remoteAddress and never trusts X-Forwarded-For.
  • First visits to self-signed certificates trigger browser warnings; this is expected behavior.
  • Connections forwarded to DSH’s loopback remain plaintext HTTP, relying on local loopback isolation.
  • For mobile access, it is recommended to install dsh-web-mobile for use in conjunction.

Resources

  • GitHub: https://github.com/rice-awa/dsh-lan-gateway
  • Community Directory: https://www.skillhub.cn/plugins/rice-awa/dsh-lan-gateway