Skip to main content

Python browser dashboard for reserving, locking, and launching shared Windows Remote Desktop machines, with per-IP firewall lockdown over WinRM.

Project description

Remote Desktop Dashboard

A Python-based, browser-driven dashboard for managing a pool of shared Windows machines: see every machine, see who is using which one, reserve / lock a machine so others can't grab it, and connect with one click. Connecting is brokered — the dashboard launches the session and never hands out a reusable .rdp file. Access is enforced on the host through a configurable enforcement mode (the real "teeth"; a browser app alone cannot stop native mstsc.exe).

What's new

0.3.0WinRM now uses NTLM (pywinrm), like TurboSSH/TurboADB. Onboarding, firewall lock, rdp-toggle, Verify, Diagnose, and the live process/serial probes previously ran through PowerShell Invoke-Command -ComputerName, which needs Kerberos/TrustedHosts and fails in workgroup or cross-domain labs. They now go through pywinrm with NTLM transport using the credentials you set in Admin → Settings (DOMAIN\user or .\Administrator) — no Kerberos, no TrustedHosts. The target just needs Enable-PSRemoting -Force and a local-admin account. (Without credentials set, it still falls back to Invoke-Command for domain-joined hosts.)

pywinrm is an optional install — pip install "remote-desktop-dashboard[winrm]" — because it pulls cryptography, which has no win_arm64 wheel. The base package stays ARM-clean (advisory mode and the reservation board need nothing extra). On Windows-on-ARM, run the dashboard under an x64 Python (it runs emulated); then the [winrm] extra and all its wheels install cleanly — the same reason TurboSSH/TurboADB ship as x64 builds.

0.2.3WinRM credentials. Onboarding/enforcement reach each target as the dashboard's own user by default; that fails when the lab machines need explicit admin credentials (workgroup, IP-addressed, or a different domain than the host running the dashboard). You can now set a WinRM user/password in Admin → Settings (held in memory only) or via the RDD_WINRM_USER / RDD_WINRM_PASSWORD env vars (persist across restarts). For workgroup/IP targets also run, on the dashboard host (elevated): Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force.

0.2.2 — Installs cleanly on Windows on ARM (win_arm64): dropped the uvicorn[standard] extra, which pulled in httptools (C) and watchfiles (Rust) — neither ships ARM64 Windows wheels, so pip tried to compile them and failed. The dashboard uses the pure-Python h11 HTTP path and doesn't need them.

0.2.1 — UI fix: the machine table's Actions column (Connect / Reserve / Release) no longer clips the Release button on the default desktop layout; the table also scrolls horizontally as a safety net. The detail panel's stale "Firewall lock" label is now "Enforcement".

0.2.0

  • No more .rdp download. Connect now launches an ephemeral, single-use session file that is deleted seconds after mstsc reads it — nothing reusable is ever handed to the user.
  • Three enforcement modes (Admin → Settings, or RDD_ENFORCEMENT):
    • firewall — lock the target's TCP 3389 to the current holder's IP (per-IP rules over WinRM). Strongest.
    • rdp-toggle — no per-IP firewall edits; RDP is enabled on the host only while it's reserved, disabled when free. Answers "how do you control without firewall rules."
    • advisory — reservation lock only; no host enforcement (native RDP is honestly not blocked).
  • Real audit log (audit_log table): reserve, connect, release, force-release, add/delete machine, onboarding, and mode changes are all recorded with actor + timestamp.
  • Admin force-release to override a stuck/abandoned hold, and a guided Onboard action that tests connectivity, applies the secured baseline for the active mode, and marks the machine secured/failed.

Install

pip install remote-desktop-dashboard
remote-desktop-dashboard

The dashboard opens at http://127.0.0.1:8000. It binds to 0.0.0.0 so other laptops on your LAN can reach it via the host machine's IP (use the host's LAN address, not localhost, so the server can read each user's real client IP for the firewall rules).

How it relates to the build spec

The reference spec calls for a clientless Apache Guacamole HTML5 gateway that streams the desktop inside the browser. That requires standing up guacd + the Guacamole web app as separate infrastructure. This tool implements the same enforcement principle — the dashboard is the sole legitimate gatekeeper and every other path is blocked at the host firewall — but using a zero-infrastructure model suited to a single Windows host on a LAN:

Spec component This tool
Clientless HTML5 gateway (Guacamole) Brokered, ephemeral mstsc.exe launch — no reusable .rdp file is created
Per-IP firewall lockdown to the gateway Per-IP firewall lockdown to the holder's IP (firewall mode), or host-level RDP on/off (rdp-toggle mode), pushed over WinRM
Backend records intent, executes on endpoint Reservation records enforcement status (applied/failed/advisory/skipped) + allowed IP; every action lands in the audit log
Reservation / lock & release One active reservation per machine, auto-released on expiry; admin force-release
Onboarding (admin) Connectivity test → apply secured baseline for the active mode → mark secured/failed
Audit log Real audit_log table; plus live session view via quser, tool-activity + serial-port probes

Swapping in a true Guacamole gateway for in-browser streaming is the natural extension point.

Features

  • Dark dashboard with machine list, sectioned detail card, admin modal, and audit log.
  • SQLite persistence under %LOCALAPPDATA%\RemoteDesktopDashboard\data by default on Windows.
  • One active reservation per machine, auto-released on expiry.
  • One-click brokered mstsc.exe launch — an ephemeral, single-use connection file (clipboard, drives, USB, printers, smart cards, audio, multi-monitor, dynamic resolution, keyboard hook, font smoothing all enabled) is written, consumed, and deleted; nothing is handed to the user.
  • Live machine detail card with four sections:
    • Status — reservation, firewall lock, allowed IP, auto-release time.
    • Sessions — every row from quser: console (physical) user + every RDP user, each tagged.
    • Tool activity — remote Get-CimInstance Win32_Process over WinRM showing who is running ETGui.exe, ETOU.exe, MobaXterm.exe, MobaXterm_Personal.exe, and putty.exe.
    • Serial ports — live list of COM ports on the target host.
  • Favorites — per-browser favourite machines (localStorage), pinned to the top, with "★ Favorites only" / "Free only" filter chips.
  • Windows firewall lockdown ON by default: on reservation, the target's port 3389 is restricted to the reserver's IP and an explicit Block-Other-RDP rule is pushed.
  • Per-machine Verify lock + Diagnose buttons return structured WinRM/ping/firewall reports.
  • Admin PIN gate with single browser-session unlock and bulk delete/release/refresh controls.
  • Admin modal split into Settings, Inventory, and Manage Machines tabs.

Configuration

Setting Default Override env var
Admin PIN admin ADMIN_PIN
Bind host 0.0.0.0 RDD_HOST
Browser launch host 127.0.0.1 RDD_BROWSER_HOST
Port 8000 RDD_PORT
Data dir %LOCALAPPDATA%\RemoteDesktopDashboard\data RDD_DATA_DIR
Default domain EU RDP_DOMAIN
Enforcement mode firewall RDD_ENFORCEMENT=firewall|rdp-toggle|advisory
Background session refresh ON RDD_AUTO_REFRESH_SESSIONS=0 to disable
Session refresh interval 30s RDD_SESSION_REFRESH_SECONDS
Firewall PowerShell timeout 20s RDD_FIREWALL_TIMEOUT_SECONDS
Auto-open browser yes RDD_OPEN_BROWSER=0 to disable

You can also switch the enforcement mode at runtime from Admin → Settings (persisted in SQLite), and run Admin → Manage Machines → Onboard / Force-release per machine.

How the native-RDP block works

When RDP lock is ON, on every reservation the dashboard runs the following on the target over WinRM:

  1. Tighten every inbound Remote Desktop rule's RemoteAddress filter to the reserver's IP.
  2. Add RDD-Block-Other-RDP (Block, TCP 3389, RemoteAddress=Any).
  3. Add RDD-Block-Other-RDP-Allow (Allow, TCP 3389, RemoteAddress=).

On release/revoke/delete those RDD-* rules are removed and the Remote Desktop rules are restored to RemoteAddress=Any.

Requirements for this to actually block native RDP:

  • The dashboard host is Windows and runs as a user that can Invoke-Command on the targets.
  • WinRM (winrm quickconfig / Enable-PSRemoting) is enabled on every target.
  • Users open the dashboard via the server's LAN hostname/IP, not localhost.

Use Admin → Manage Machines → Verify lock / Diagnose to confirm the lock and read the exact WinRM/ping/firewall state.

Development

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn remote_desktop_dashboard.main:app --reload --host 0.0.0.0 --port 8000

Out of scope (extension points)

Multi-gateway/HA, true Guacamole in-browser streaming, session recording, scheduled/timed reservations, calendar booking, and Active Directory group sync are not built in.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

remote_desktop_dashboard-0.3.0.tar.gz (40.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

remote_desktop_dashboard-0.3.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

Details for the file remote_desktop_dashboard-0.3.0.tar.gz.

File metadata

  • Download URL: remote_desktop_dashboard-0.3.0.tar.gz
  • Upload date:
  • Size: 40.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for remote_desktop_dashboard-0.3.0.tar.gz
Algorithm Hash digest
SHA256 048871b82ff1640359f535276d95af917f8c60d2b8b47920787188f79070eac8
MD5 989fd4bd4dab5b38d318ae04d3fba1ea
BLAKE2b-256 a73655ea787173985970d9fa4d8d0c14d04d2bf7275f0c5827cb8587a0683e1c

See more details on using hashes here.

File details

Details for the file remote_desktop_dashboard-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for remote_desktop_dashboard-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57581318e1f6402a995002d44825fe140e43babe09d5c56cf59a355e9ec98629
MD5 40cfd553da1dd471914d4d2a85841d93
BLAKE2b-256 0951d4743bc77af3685caf00f3e1c4076839475387c47d7ccda7c751e19ff86a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page