Architecture
Linux server
+------------------------+
| RemoteServer |
| |
Windows agent --->| /agent WSS + mTLS | signed commands
SYSTEM | /api/* mTLS | telemetry, access results, update packages
| /ssh WSS + mTLS | SSH bridged over WebSocket (TLS-only networks)
| /enroll token based |
| /auth/* login/TOTP |
| /admin/* localhost |
+-----------+------------+
|
| MariaDB
v
audit, users, devices,
groups, packages, events
Windows agent -- ssh -R --> bastion loopback port --> console --> TightVNC viewer
Console -- named pipe --> local agent broker -- ssh -L --> bastion / admin API
Routing rules
- Agents initiate every connection. Managed Windows devices need no inbound ports.
/agent is the WebSocket command channel; it requires the device's client certificate. The server pushes signed commands down it and the agent answers on /api/*.
/api/* carries telemetry (every minute), access results, the VNC and SSH certificate requests and the update package downloads; nginx enforces mTLS on it.
/ssh bridges SSH over a WebSocket for devices on networks that let only TLS through; the inner SSH still authenticates at the bastion.
/admin/* is localhost only on the server. The Windows console reaches it through the local agent's broker, which opens ssh -L with the enrolled device's identity; the Lite and Linux consoles with a short-lived certificate of their own. Server-side authentication and grants decide what the signed-in user may do.
- 443 carries everything. nginx's stream module tells TLS from raw SSH on the one port: TLS goes to the HTTPS server (which serves the WebSockets and the API), raw SSH goes to the bastion's sshd. Clients that cannot reach raw SSH use
/ssh instead.
- The VNC server stays on the device's loopback. It is reachable only through the reverse tunnel the agent opened, and only by whoever holds the session's password.
The projects
| Project |
Purpose |
Runs on |
RemoteAgent |
The Windows service: enrollment, the command channel and its signature checks, telemetry, VNC provisioning, the local broker, the reverse tunnel, the file service, the ssh-agent for the TPM key, updates |
Managed Windows devices, as SYSTEM |
RemoteAgent.Updater |
The helper service: watchdog, heartbeat, executable replacement for agent updates |
Managed Windows devices, as SYSTEM |
RemoteClient |
The WinForms console for operators and administrators |
Windows admin and operator devices |
RemoteClient.Lite |
Viewer-only Windows console that signs in with an ephemeral SSH certificate; no local agent |
Windows operator devices |
RemoteClient.Linux |
Viewer-only Avalonia console for Linux operators |
Linux operator devices |
RemoteClient.Cli |
racctl: the server's log, health, fleet listings and self-update from the command line, with an access token |
Enrolled Windows devices |
RemoteClient.Core |
Shared console logic: admin API client, tunnel transports, localization |
Referenced by the consoles and racctl |
RemoteServer |
ASP.NET Core: enrollment, auth, admin API, command signing, telemetry ingest, package store, MSI generation, audit, diagnostics |
Linux |
RemoteAgent.Contracts |
Shared DTOs and the canonical command signature |
Referenced by client, agent and server |
RemoteAgent.Resources |
Shared resources |
Referenced by the applications |
Repository layout
src/ the projects above
deploy/ from-scratch server installer: setup.sh, steps/01-prereqs … 11-verify,
backup.sh / restore.sh, fetch-tightvnc.sh, KEYS.md
tests/ xunit tests (run in CI)
docs/ website/ mkdocs.yml this website
icon/ the application icon
third_party/ the pinned TightVNC MSI and its GPL source, fetched, not committed
.github/workflows/ build.yml (every push; release on v* tags), codeql, docs
build.ps1 the Windows build: agent, updater, console, Lite, server package, signing
RemoteAppClient.slnx