Files
netdesk/README.md
T

280 lines
14 KiB
Markdown

# NetDesk — your own self-hosted remote desktop
<p>
<a href="https://netdesk.space"><img alt="Website" src="https://img.shields.io/badge/website-netdesk.space-19c87e"></a>
<img alt="Version" src="https://img.shields.io/badge/version-1.5.0-blue">
<img alt="Platform" src="https://img.shields.io/badge/platform-Windows%20%7C%20Web%20%7C%20macOS%20(build)-lightgrey">
<img alt="E2E" src="https://img.shields.io/badge/encryption-ECDH%20P--256%20%2B%20AES--256--GCM-orange">
</p>
**Website & live demo:** [netdesk.space](https://netdesk.space) · **Download:** [Windows agent](https://netdesk.space/download) · **Pricing:** [free to self-host](https://netdesk.space/pricing)
A TeamViewer/RustDesk-style remote desktop system you fully own: a signaling/relay
server for your VPS, a **Windows service** on your powerful PC (reachable at boot,
at the logon screen, and across UAC prompts), and a **zero-install web viewer**
(Chrome/Edge) you can use from any laptop or phone while traveling.
```
┌──────────────────────────┐ WSS outbound only ┌──────────┐ WSS ┌──────────────┐
│ HOME PC (Windows service)│ ──────────────────► │ VPS │ ◄────── │ TRAVEL laptop│
│ broker (SYSTEM, boot) │ │ netdesk │ │ any browser │
│ └─ desktop agent │ ◄──── relayed ────► │ server │ │ (phone works)│
│ (console session) │ E2E-encrypted └──────────┘ └──────────────┘
└──────────────────────────┘
│
└──── optional direct mode: ws://home-ip:8901 (LAN / port-forward) ────┘
```
## Features
**Access & unattended operation**
- Boot-time Windows service (SYSTEM): no auto-logon needed, survives reboots
- Reachable at the **Windows logon screen** — view and type credentials to log in
- Input works across desktop switches (user desktop, logon screen, UAC prompts) via desktop-following injection
- Auto-reconnect to server forever (works behind any NAT, no port forwarding)
- Wake displays automatically when a viewer connects
**Video / audio**
- H.264 (x264 ultrafast/zerolatency), up to 1080p60 @ 20 Mbps, idle screens send nothing
- Hardware decode in the browser (WebCodecs) + HTML5 canvas
- Adaptive **Auto quality** mode (RTT/decoder-queue based preset stepping)
- System audio (WASAPI loopback → Opus) — bundled in the packaged exe; `pip install PyAudioWPatch` for source runs
**Full control**
- Mouse (all buttons, wheel), keyboard via SendInput scancodes, keyboard-lock for Alt+Tab/Win/Ctrl+W in fullscreen
- **Privacy mode** — turn the physical monitor off while you keep working
- **Lock PC on disconnect** (per-viewer checkbox)
- Process manager — list & kill remote processes
- Remote power — lock, sign out, reboot, shut down, run command
- Clipboard sync (two-way), chat
**Files**
- Browse/download/upload/rename/delete/mkdir, **folder upload** with drag & drop
- Atomic uploads (.part → final), folder creation on demand
**Security**
- **End-to-end encryption** (default): ephemeral ECDH P-256 → AES-256-GCM per frame — the VPS cannot see your screen
- Password never leaves the host un-hashed (PBKDF2 200k challenge/response, 0.4 s throttle per bad attempt)
- Optional **TOTP 2FA** (`--set-totp auto` → authenticator code required at connect)
- Optional server registration key so only your hosts can register; `/status` API behind a token
- The service broker relays opaque bytes only — agents hold all keys
**Accounts (RustDesk-style)**
- Sign up / sign in **in the desktop app and on the website** — no email
verification wall (the account works immediately; the email only confirms it)
- **My computers**: every PC where you sign in with your account is listed on
the website for one-click connect (online/offline/in-session status shown)
- Server address is **pre-filled** (netdesk.space) and no registration key is
needed by default; point the app at your own server anytime
- Pre-configured builds: name the exe `NetDeskHost-host=your.server,key=SECRET.exe`
and it auto-configures — hand it out with zero setup
**Viewer niceties**
- Address book (saved connections), remember-password, view-only mode
- **Session recording** to .webm (one click)
- **TCP tunneling** — reach any TCP service on the host (SSH, RDP, web UIs) through the server; portal-gated, with a panel in the viewer
- **Installable app (PWA)** — install the viewer like a native app from Chrome/Edge/Safari on laptop or phone
- **Host-side remote printing** — send a file to the host's printer from the file manager
- Multi-monitor switching, quality presets, live stats (fps/RTT/bitrate/E2E badge)
## Quick start (try on one PC)
```bat
cd path\to\netdesk
scripts\run_local_demo.bat
```
First run prints and saves a 9-digit ID and a random password
(`%APPDATA%\NetDesk\config.json`). Automated end-to-end test:
`.venv\Scripts\python tools\smoke_test.py` (23 checks: auth, 2FA, E2E video,
clipboard, processes, privacy, files, input, broker path…).
## Portable exe — a regular desktop app, no Python needed
`portable\` (and `..\NetDesk-portable-win64.zip`) ships standalone Windows x64
binaries built with PyInstaller, **tested end-to-end** (full 20-check suite
passes against the packaged exes):
| File | Purpose |
|---|---|
| `NetDeskHost.exe` (54 MB, windowed) | the agent **desktop app** — double-click it: a control panel opens with live status, your ID, server settings, password/2FA management, start/stop, and one-click service install |
| `NetDeskServer.exe` (14 MB, console) | server for a Windows VPS; serves the viewer **and the portal** |
Double-clicking `NetDeskHost.exe` opens the control panel (config + logs are
created next to the exe — the folder is fully portable). Advanced users can
still drive everything from a terminal (`--server …`, `--install`,
`--set-password`, `--set-totp auto`, `--uninstall`); the app itself is
windowless, so CLI output goes to `host.log` next to the exe. `--install`
sets up the same boot-time SYSTEM service with full logon-screen/UAC access.
## macOS (MacBook M4 / Apple Silicon and Intel)
Mac binaries cannot be cross-compiled from Windows, so the repo builds them ON
the Mac — native, one command:
```bash
git scp the netdesk folder to the Mac, then:
bash scripts/build_mac.sh # -> dist/NetDeskHost + dist/NetDeskServer (arm64)
```
- `NetDeskHost` on the Mac = control the Mac remotely (capture via mss, input
via CoreGraphics CGEvent, clipboard via pbpaste/pbcopy, process manager,
power via osascript). First run: grant **Screen Recording** and
**Accessibility** permissions (System Settings → Privacy & Security); if
Gatekeeper complains: `xattr -cr NetDeskHost`.
- Autostart on login: `scripts/deploy/com.netdesk.host.plist` → copy to
`~/Library/LaunchAgents/` (edit the path/server inside first),
then `launchctl load ~/Library/LaunchAgents/com.netdesk.host.plist`.
- `NetDeskServer` also builds on the Mac if you want a Mac VPS.
- macOS audio capture needs a loopback device (e.g. BlackHole) — off by default.
- Connecting TO a Mac or PC from the MacBook: just the browser — open the
server URL in Chrome/Edge/Safari; nothing to install.
## Web management portal
Start the server with `--portal-password "YourPortalPassword"` and open
`https://your-server:8443/portal` — a TeamViewer-console-style dashboard:
- **Computers list** — every host that ever registered, online/offline status,
version, last-seen, and a **Connect** button that deep-links into the viewer
(`/?id=<id>` — ID prefilled, just type the host password)
- **Live stats** — hosts online, sessions total, relayed traffic, uptime
- **Activity feed** — host online/offline, connect attempts, accepted sessions,
wrong-password/2FA failures (auth failures are visible server-side; passwords
never are)
- **Downloads** — anything you drop into the server's `files/` folder
(e.g. `NetDeskHost.exe`) is offered to logged-in users, so your travel laptop
can always grab the current agent from your own server
Access control: single portal password (cookie session, HttpOnly, 7 days).
The portal runs over the same TLS as everything else — keep TLS on for
internet use. By design the portal **cannot** see or store host passwords
(end-to-end encryption); connecting always needs the host's own password.
## Production setup
### 1. Server on your VPS (Debian/Ubuntu)
```bash
cd netdesk/scripts/deploy && sudo bash deploy_vps.sh # installs systemd service, prints REG_KEY
# add --portal-password "..." to the unit for the web portal at /portal
sudo ufw allow 8443/tcp
```
TLS (recommended): Let's Encrypt via certbot, then add `--cert/--key` to the unit
and restart. Quick alternative: `--gen-cert` (self-signed, accept browser warning once).
### 2. Host on your powerful PC (twice, then forget it)
```bat
:: once, as your user: pick the password and server
.venv\Scripts\python host\netdesk_host.py --set-password "YourStrongPassword"
.venv\Scripts\python host\netdesk_host.py --server wss://desk.yourdomain.com:8443/ws --reg-key REG_KEY --listen 8901
:: once, as Administrator: install the boot-time service
scripts\install_autostart.bat (runs: netdesk_host.py --install)
```
The installer copies credentials to `C:\ProgramData\NetDesk` and creates a
SYSTEM scheduled task (ONSTART) running the **broker**. The broker spawns a
**desktop agent** into your console session and re-spawns it on user switches.
Optional: `--set-totp auto` for a 2FA secret (print → add to your authenticator).
Optional: `pip install PyAudioWPatch` for remote sound.
### 3. Travel
Open `https://desk.yourdomain.com:8443/` — enter ID (+ 2FA code if enabled) and
password. Save it in the address book. Works on phones too. At the office logon
screen after a reboot? Connect and type your Windows password — you're in.
## Security model
TLS to the server + end-to-end AES-GCM media + PBKDF2 password proof + optional
TOTP + registration key. Single session per host; second viewer gets "host busy".
Everything is stateless on the VPS.
## Silent operation & what "undetected" means here
Like RustDesk 1.2, NetDesk is invisible on the host while you work:
- The engine is **headless** — no window, no tray icon, nothing pops up when a
session starts. In service mode it runs as a hidden SYSTEM task from boot.
- **Privacy mode** turns the physical monitor off while you keep working.
Enable **"Blank the monitor while controlled"** in the app (or per-session
via the viewer's privacy button) and the screen goes dark the moment a
viewer connects; it comes back when the session ends.
- Sessions inject input only; a person sitting at the PC would see the mouse
move (true for RustDesk/TeamViewer too — blocking local input needs a driver).
Be honest about the detection surface, because "undetected" does not mean
"forensically invisible": the process shows in Task Manager, Windows sees the
scheduled task, the host keeps logs (`host.log`), and the machine makes an
outbound connection to your VPS. RustDesk has the same surfaces. That is the
correct trade-off for administering **your own or explicitly authorized
computers**; covertly controlling a machine you do not own or are not
authorized to manage is illegal in most jurisdictions and this tool is not
designed for it.
## Honest limitations
- No UDP P2P hole-punching: browsers can't send raw UDP, so traffic relays
through your VPS (~1 extra RTT; same as RustDesk when its punch fails). Direct
mode (`--listen` + port-forward) bypasses the VPS on your LAN.
- Remote printing is not implemented (needs a printer driver); use file transfer + local printing.
- True privacy mode (fake desktop) needs a virtual display driver — NetDesk turns
the physical monitor off instead.
- Session-0 notes: input at the logon screen/UAC requires the service install
(agent as SYSTEM). Ctrl+Alt+Del itself is never injectable without a driver.
- No mobile native apps (the web viewer works in phone browsers).
## Files
```
netdesk/
├── server/netdesk_server.py # signaling + relay + web host (stateless)
├── server/web/ # viewer UI
├── host/netdesk_host.py # broker + desktop agent + service installer
├── tools/smoke_test.py # 23-check end-to-end suite
├── scripts/ # local demo, service install, VPS deploy
└── requirements.txt
```
## Troubleshooting
| Symptom | Fix |
|---|---|
| "host offline" | Broker not running: `schtasks /Run /TN NetDesk`, or start `--broker` manually; logs in the config folder's `host.log` |
| "bad 2FA code" | Host clock drift — resync Windows time, or re-set `--set-totp` |
| Black screen + "logon screen" banner | Nobody logged in — type credentials via keyboard, desktop switches automatically |
| Input dead on UAC prompt | Only in simple (non-service) mode — install the service for SYSTEM desktop access |
| Choppy | Auto quality preset, or direct mode on LAN |
| E2E badge missing | Old browser — needs WebCodecs + WebCrypto (Chrome/Edge 102+) |
## Get the source code
The full source is published on the project website (no GitHub account needed):
```bash
# Clone directly from netdesk.space
git clone https://netdesk.space/git/netdesk.git
# …or download a snapshot
# https://netdesk.space/source → .tar.gz / .zip
```
## Repository layout
```
netdesk/
├── server/ Python aiohttp signaling + relay + web client
├── host/ Python Windows host/agent + desktop GUI (pywebview)
├── native/ from-scratch native client (Rust core + Flutter UI)
├── docker/ Dockerfile + compose for the server
├── scripts/ tools/ helper + maintenance scripts
└── requirements.txt Python deps for the server/host
```
## License
Source-available — free to self-host and modify for your own use. See `LICENSE`.