Open-source project
zibo-chen/SubnetDesk avatar
zibo-chen/SubnetDesk

SubnetDesk: a LAN-only RustDesk fork that drops the rendezvous server

LAN-only remote desktop based on RustDesk

622 stars64 forksRustAGPL-3.0

At a glance

What is it?
SubnetDesk strips the public device-ID, relay and cloud-account paths out of RustDesk and connects endpoints directly by IP or mDNS name. It fits homelabs and VPN-linked private networks, and it is the wrong tool the moment one side is behind NAT with no route to the other.
Who is it for?
Adopt SubnetDesk if every machine you control already sits on one routable private network and you want no coordination server in the path. Do not adopt it for internet-wide support or cross-NAT access, because the README states plainly that it provides no rendezvous or relay service.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem SubnetDesk removes rather than solves

Standard RustDesk assumes the two machines cannot see each other. That assumption is why it ships a device ID, a rendezvous server to translate that ID into an address, and an optional relay for when a direct path fails. If your machines are already on the same subnet, or joined by WireGuard, Tailscale or OpenVPN, every one of those components is overhead. SubnetDesk is an independently maintained RustDesk fork that deletes them: the README describes removing the public device-ID, rendezvous, relay, cloud account, proxy and automatic public-update paths, and replacing them with direct endpoint connections plus local discovery.

The intended user is narrow and clearly stated. Home labs, offices, classrooms, on-site support, and private networks connected by a VPN. If you administer a handful of machines on one flat network and find the idea of a third-party ID server distasteful, this is aimed at you. If you support relatives over the internet, it is not, and the README says so in a callout: SubnetDesk does not provide Internet rendezvous or relay services.

How a connection is actually established

Two mechanisms replace the rendezvous server. The first is mDNS: the controlled device advertises itself on the local segment, and the controller lists it automatically. The second is manual entry, where the controller types hostname:port or IP:port. Discovery is a convenience, not a requirement. The README notes that direct address entry still works without mDNS, which matters on networks that filter multicast.

The transport is a single configurable TCP port, 21118 by default. Access control sits at two layers. Passwords are stored as Argon2id hashes rather than plaintext, and the controlled device can restrict incoming connections to selected CIDR networks. On top of that, endpoint fingerprints are verified and remembered, described in the README as trust-on-first-use, which gives you a way to notice when an endpoint's identity changes unexpectedly.

The project layout reflects the fork's origin rather than a rewrite. Cargo.toml still names the package rustdesk and the library librustdesk, with SubnetDesk appearing in the description and authors fields. That is worth knowing before you file a bug: the crate name, the binary name and much of the surrounding code follow upstream conventions, so error messages and paths may not say SubnetDesk anywhere.

Installing SubnetDesk and making a first connection

The README points to GitHub Releases for stable packages and to the nightly tag or GitHub Actions artifacts for the newest changes, with a note that nightly packages are development builds and stable releases are preferred for daily use. Packages cover Windows (.msi installer or a portable .exe), macOS (.dmg for Intel and Apple Silicon), Linux (.deb, .rpm, .AppImage, .flatpak, plus an Arch package on x86_64), and Android (.apk). No package-manager command is documented for any of these, so installation means downloading the artifact for your platform and running the installer.

Building from source is possible and the repository ships a Dockerfile for it, based on debian:bullseye-slim, which installs the GTK, XCB, ALSA, PulseAudio and GStreamer development headers, builds CMake 3.30.6, bootstraps vcpkg at tag 2023.04.15 to install libvpx, libyuv, opus and aom, then installs Rust through rustup. The README says to clone the repository with its submodules, which matches the presence of .gitmodules in the tree. The Dockerfile ends with an entrypoint script, so the container is a build environment rather than a runtime image.

Once installed on both machines, the quick start is four steps. On the controlled device, open LAN settings, set a username and password, and enable LAN discovery. The default port is 21118. On the controller, select a discovered device or enter the address manually.

text
hostname:port
IP:port

Then verify the device fingerprint on first connection and connect. Before blaming the software for a failed attempt, the README's network checklist is the place to look: both devices must route to each other, TCP port 21118 (or your configured port) must be allowed by the host firewall, mDNS must be available if you want automatic discovery, and the controlled device's CIDR allowlist must include the controller's network. Linux hosts have a separate document, docs/linux-host-readiness.md, covering SELinux, Wayland and login-screen behaviour, which is a hint that those three are where Linux users get stuck.

Where SubnetDesk stops being the right tool

The hard boundary is reachability. SubnetDesk has no rendezvous and no relay, so if the two endpoints cannot route packets to each other, nothing in the application will fix that. A machine behind carrier-grade NAT, a client on a hotel network, or a laptop that roams between networks without a VPN will simply not connect. That is a design decision, not a bug, and the README states it before anything else.

The second limitation is operational. Removing the cloud account and the automatic public-update path means updates are your problem. The README points at GitHub Releases and the nightly tag; it does not describe any in-application update channel, and the Cargo.toml feature list contains a software-update feature gated behind reqwest and ring, which suggests the machinery exists in the codebase but the documentation does not describe it as a supported path. Treat upgrades as a manual reinstall until you have confirmed otherwise.

Third, the project is a fork, and forks carry a merge cost. It tracks an upstream that moves, and the divergence here is deliberate and structural: removing the ID and relay layers touches the parts of RustDesk that most other changes depend on. The repository has no homepage, and the README does not document rollback, downgrade or migration between versions. If you need a documented support contract, this is not it.

RustDesk with a self-hosted relay, and what changes

The honest alternative is upstream RustDesk with a self-hosted rendezvous and relay server. It solves the same privacy complaint from the other direction: instead of removing the coordination layer, you run it yourself, so device IDs and relay traffic never touch a third party. The difference in approach is what each one assumes about the network. Self-hosted RustDesk keeps working across NAT and over the open internet, at the cost of a server you must deploy, secure and keep running. SubnetDesk assumes the network already connects the machines and removes the server entirely.

If your devices are all on one LAN or one VPN, SubnetDesk is less infrastructure for the same result. If even one endpoint is outside that perimeter, the self-hosted relay is the only one of the two that will connect at all. There is no middle setting here: SubnetDesk does not fall back to a relay when a direct path fails, because the README says the relay path was removed.

Licence, maintenance and what an upgrade costs

SubnetDesk is licensed under AGPL-3.0, the same family of licence as upstream RustDesk. The practical consequence for most readers is the network clause: if you modify the software and let users interact with it over a network, the AGPL requires you to offer those users the corresponding source. Running it unmodified on your own machines does not trigger that. This is a description of the licence text, not legal advice, and anyone embedding SubnetDesk in a product should read the full LICENCE file in the repository.

On maintenance, the last push to the master branch was on 2026-09-12, and releases are frequent: v1.3.0 on 2026-08-27, v1.2.3 on 2026-08-17, and a nightly build on 2026-07-17. The repository is not archived. What the README does not show is a contributor base, a support channel, or a compatibility statement about which upstream RustDesk version this fork currently tracks. Cargo.toml pins version 1.3.0 and a minimum Rust of 1.75, so a source build needs at least that toolchain. Upgrade cost is therefore mostly re-testing: the fingerprint store, the CIDR allowlist and the LAN settings all need to survive the jump, and the README does not say whether they do.

Editorial conclusion

Adopt SubnetDesk if every machine you control already sits on one routable private network and you want no coordination server in the path. Do not adopt it for internet-wide support or cross-NAT access, because the README states plainly that it provides no rendezvous or relay service. Before rolling it out, verify three things on the controlled host: that TCP port 21118 is open in the firewall, that the CIDR allowlist includes the controller's network, and that the fingerprint shown on first connection matches the endpoint you expect.

Frequently asked questions

Does SubnetDesk need a server or a RustDesk account?

No. The README states that the public device-ID, rendezvous, relay and cloud-account paths were removed from RustDesk, and that no coordination server is required. Two devices connect directly by IP address or hostname on the configured TCP port.

What port does SubnetDesk use by default?

The quick start gives 21118 as the default port, and the network checklist says TCP port 21118, or your configured port, must be allowed by the host firewall. The port is configurable in LAN settings.

Can SubnetDesk connect to a machine over the internet?

Not by itself. The README carries a callout saying SubnetDesk does not provide Internet rendezvous or relay services, and that both devices must be reachable through the same LAN, a routed private network, or a VPN.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. README
  4. Releases
  5. zibo-chen/SubnetDesk on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zibo-chen-subnetdesk.svg)](https://hysenlabs.com/projects/zibo-chen-subnetdesk)