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 in 0.2.0
- No more
.rdpdownload. Connect now launches an ephemeral, single-use session file that is deleted seconds aftermstscreads 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_logtable): 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\databy default on Windows. - One active reservation per machine, auto-released on expiry.
- One-click brokered
mstsc.exelaunch — 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_Processover WinRM showing who is runningETGui.exe,ETOU.exe,MobaXterm.exe,MobaXterm_Personal.exe, andputty.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:
- Tighten every inbound
Remote Desktoprule'sRemoteAddressfilter to the reserver's IP. - Add
RDD-Block-Other-RDP(Block, TCP 3389, RemoteAddress=Any). - 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-Commandon 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file remote_desktop_dashboard-0.2.0.tar.gz.
File metadata
- Download URL: remote_desktop_dashboard-0.2.0.tar.gz
- Upload date:
- Size: 35.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
168605ed937dc359665f6b0d3e0f86ddea8d86ecf7b1453ad8b5648db4e3acf0
|
|
| MD5 |
f041457210f249cbe19440b1b591a0a8
|
|
| BLAKE2b-256 |
31cd42013354cc1e175373541299ab88bbc2bc9eadc13d98bacaf8273eac9125
|
File details
Details for the file remote_desktop_dashboard-0.2.0-py3-none-any.whl.
File metadata
- Download URL: remote_desktop_dashboard-0.2.0-py3-none-any.whl
- Upload date:
- Size: 34.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77a0b4769ffa887932f55d43ee0b69d3dd96eca4c52f40cb512861275c3e2cae
|
|
| MD5 |
caa42aa1964b2e2f3e45a9a7cf09303e
|
|
| BLAKE2b-256 |
504de7ef005faf998d8bd0dea20a0071ddbdf9a2cb18b720d7764a0e9c047d0b
|