Skip to content

Add Remote Proxy & Network Devices (in-browser HTTP/HTTPS/SSH/Telnet access to LAN devices via an agent)#2485

Open
teknoprep wants to merge 1 commit into
amidaware:masterfrom
teknoprep:feature/remote-proxy
Open

Add Remote Proxy & Network Devices (in-browser HTTP/HTTPS/SSH/Telnet access to LAN devices via an agent)#2485
teknoprep wants to merge 1 commit into
amidaware:masterfrom
teknoprep:feature/remote-proxy

Conversation

@teknoprep

@teknoprep teknoprep commented Jun 10, 2026

Copy link
Copy Markdown

Remote Proxy & Network Devices

Adds the ability to reach a device on an agent's LAN (firewalls, switches, Proxmox/PBS, iDRAC, etc.) directly from the Tactical RMM UI — no MeshCentral Router, no local client, no manual port-forwarding, all over the existing HTTPS port.

Right-click an agent → Remote Proxy opens one window with a protocol selector:

Protocol What you get
HTTPS / HTTP the device's web UI embedded in the window (iframe)
VNC the device's screen via MeshCentral's built-in noVNC viewer, relayed through the agent (no client to install)
SSH / Telnet an in-browser xterm.js terminal

It also adds a Network Devices tab (next to Servers/Workstations/Mixed) where you register devices (name / protocol / IP / port / description / ordered preferred agents) and Connect with one click. Agent selection walks the preferred list and probes reachability, skipping agents that can't actually reach the device, falling back to a random online agent (servers first).

How it works

  • Reuses MeshCentral's relay (meshrelay.ashx) to open a raw TCP tunnel to addr:port through the agent (same mechanism as the existing WebVNC feature), with MemoryBIO TLS for HTTPS targets.
  • A small async reverse proxy (served by the ASGI server) speaks HTTP/1.1 (h11) over the tunnel and rewrites responses so the device renders in an iframe (strips X-Frame-Options/CSP, fixes redirects, root-relative URLs and ES-module imports; injects a runtime XHR/fetch/WebSocket shim for JS-built URLs). Cookies are forwarded byte-exact so __Host-/__Secure- tickets (Proxmox/PBS) survive.
  • WebSocket proxying is included so device consoles work (e.g. Proxmox/PBS noVNC & xterm).
  • VNC reuses MeshCentral's bundled noVNC viewer + meshrelay.ashx: the WebVNC endpoint accepts an optional ?addr=<ip> to relay to a device on the agent's LAN (instead of the agent itself) — no bundled client or extra dependency.
  • SSH uses asyncssh server-side bridged to xterm.js; Telnet is a raw bridge with minimal IAC negotiation.
  • All sessions are permission-gated (can_use_mesh) and written to the audit log / history.

Deployment — handled automatically

  • install.sh generates the location ^~ /agentproxy/ block (ASGI socket + WebSocket upgrade headers via a $connection_upgrade map) in both the API and frontend nginx vhosts.
  • update.sh idempotently patches the /agentproxy/ block into existing rmm.conf/frontend.conf on upgrade (backs up each file first) so existing installs get the feature without breakage. Validated with nginx -t.
  • New Python deps (asyncssh, h11, uvicorn[standard], websockets) install via requirements.txt; the ASGI server runs under uvicorn (daphne.service).

Note: web-proxy URL handling for JS-heavy appliance UIs has since moved to a root-scoped service worker that intercepts/re-prefixes requests generically (with per-session cookie isolation), which is far more robust than response rewriting. Validated against TrueNAS SCALE, Ricoh Web Image Monitor, pfSense, Proxmox, and generic firewalls. See the summary comment below for the full set of follow-up commits.

Notes

  • Developed against v1.4.0 (master); happy to rebase onto develop. maintainer_can_modify is enabled.
  • Frontend changes are in a companion PR to tacticalrmm-web (Brand new install can't login #50).

@CLAassistant

CLAassistant commented Jun 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@teknoprep

Copy link
Copy Markdown
Author

Summary of what this PR delivers (backend)

This adds Remote Proxy (reach a device's web UI / terminal / VNC on an agent's LAN through the agent, no inbound ports or local client) and Network Devices, plus the infra to run it. Everything tunnels over MeshCentral's existing relay (meshrelay.ashx) — no new services exposed to the internet.

Remote Web Proxy (agents/web_proxy.py)

Reach a LAN device's HTTP/HTTPS admin UI (firewall, NAS, printer, hypervisor…) through an agent. Raw TCP to addr:port over the Mesh relay, optional TLS, served under /agentproxy/<token>/.

The hard part is making arbitrary appliance UIs work under a path prefix. After hitting the usual per-app breakage, the approach converged on a service worker that intercepts requests generically instead of fragile server-side rewriting:

  • Service worker (__apxsw.js, root-scoped, referrer-gated): re-prefixes every escaping same-origin request (/x, location.host+'/x', <img>, CSS url(), etc.) from a proxied page; passes all non-proxied (RMM app) requests through untouched. Also redirects escaping GET navigations back into the prefix.
  • Per-session cookie isolation: forward to a device only the cookies that device set — fixes oversized-header 400s on small embedded web servers and prevents leaking RMM/other-device cookies.
  • Per-session cookie path scoping (/agentproxy/<token>/) so devices on the shared origin don't clobber each other (INVALID_SESSION_ID).
  • Don't inject our own <base> (broke sub-path docs/frames); keep/rewrite the device's own.
  • Inject the client shim only into document/iframe navigations (Sec-Fetch-Dest); leave XHR/fetch byte-exact.
  • Patch window.open, rewrite absolute same-origin URLs + document.write/writeln.
  • Relaxed TLS floor (TLSv1 / SECLEVEL=0) for legacy-HTTPS appliances (cert already not verified; rides the trusted LAN).

Validated working: TrueNAS SCALE, Ricoh Web Image Monitor (incl. login), pfSense, Proxmox, generic firewalls. (Toshiba TopAccess — a window.top/child-window React SPA — is the known remaining hard case.)

Remote Terminal (agents/term_proxy.py, consumer)

SSH / Telnet to a LAN device over the same tunnel, rendered with xterm.js.

VNC

Reuses MeshCentral's bundled noVNC viewer + meshrelay.ashx: WebVNC now accepts ?addr=<ip> to relay VNC to a LAN device through the agent (instead of the agent's own VNC). No bundled client, no extra dependency.

Network Devices (netdevices/)

Model + API for devices without an agent. Reachability-aware agent selection picks an agent that can actually reach the device; now caches the last-good agent and uses a short sequential probe so Connect is fast.

Infra (install/update)

  • requirements.txt: asyncssh, h11, uvicorn[standard], websockets.
  • ASGI server moved to uvicorn (daphne.service); install.sh creates/enables it, update.sh migrates existing installs.
  • nginx /agentproxy/ routing added to both vhosts (install + idempotent update patch); /ws/ consumers for terminal.

Paired frontend changes: amidaware/tacticalrmm-web#50.

…access to LAN devices via an agent)

Rebased onto master (v1.5.1), conflict-free.

Features:
- Network Devices app (netdevices): manage non-agent LAN devices per client/site
- Remote Web Proxy: reach a device's HTTP/HTTPS UI through an agent (web_proxy.py, ws_proxy.py)
- Remote Terminal: SSH/Telnet to a LAN device through an agent (term_proxy.py, AgentTerminalConsumer at ws/agent/<id>/term/)
- VNC relay to a LAN device via the agent (WebVNC ?addr= + MeshCentral noVNC)
- nginx /agentproxy/ routing added to install.sh and update.sh

Coexists with the built-in agent terminal (TerminalStreamConsumer at ws/agent/<id>/terminal/<session_id>/).
Adds deps: asyncssh, h11.
@teknoprep
teknoprep force-pushed the feature/remote-proxy branch from fd00c95 to d7005b6 Compare June 22, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants