Skip to content

Remote Desktop

Velle Sinclair edited this page Sep 4, 2026 · 6 revisions

Remote Desktop

syn-remote puts this desktop on a VNC viewer somewhere else — including when nobody is sitting at it.

syn-remote on                # start it now, and at every login
syn-remote address           # how to connect to it
syn-remote password          # the password a viewer is asked for
syn-remote status            # what it is doing
syn-remote off               # stop it, and stop it starting at login

Settings ▸ Remote Desktop is the same thing in a window.


It is a wrapper, and wayvnc is the server

wayvnc is the wlroots-native VNC server. It captures the screen through zwlr_screencopy_manager_v1 and drives the seat through zwp_virtual_pointer_manager_v1 and zwp_virtual_keyboard_manager_v1. synui implements all three and hands them to any native client, so nothing here goes through a desktop portal and nothing prompts.

"Wayland can't do remote desktop" does not apply here. All three reasons that is said are about other stacks:

  • GNOME and KDE gate capture behind a portal that asks a human, per session. That is a policy, and it makes unattended access impossible by design.
  • xdg-desktop-portal-wlr implements ScreenCast but not RemoteDesktop, so there is no input injection through the portal. That is why portal-based tools can watch a wlroots desktop and cannot touch it — going native sidesteps it.
  • Nothing exists to connect to before somebody logs in. That one is true here, on any Wayland system, and syn-remote status says so rather than failing with an error that reads like a bug.

Waking a screen that has gone dark

A blanked output cannot be captured at all. Once synui's idle blank stage has fired, screencopy answers failed to copy output — a viewer gets nothing, and there is no frame to click on to get out of it. power_blank_timeout defaults to 600 seconds, so an unattended machine would go dark to a viewer ten minutes after the last keypress and stay dark.

That is what the wrapper is for. When somebody connects it turns the outputs back on and holds a real idle inhibitor; when the last viewer leaves it releases it, so the machine goes back to sleeping normally. Two viewers is one screen: the wake happens once, and the release waits for the last one.


Where it listens

This machine only (default) Bound to 127.0.0.1. Reach it from elsewhere over an SSH tunnel.
The network syn-remote listen lan — every device on the LAN can reach it.

⛔ The firewall does not stand behind this. synnet's base policy is default-drop on input and accepts everything from 10/8, 172.16/12 and 192.168/16. A port bound to 0.0.0.0 is therefore not "open but firewalled" — it is reachable by every device on the network, and there is no second door to unlock afterwards. The certificate and the password are what stand in the way.

From another machine, with the default loopback binding:

ssh -N -L 5900:localhost:5900 you@your-machine

then point a VNC viewer at localhost:5900. syn-remote address prints that line with the right names in it.


Reaching it from outside the LAN

Two separate things stand in the way, and both have to be dealt with. Neither of them is syn-remote listen lan, which only decides what the server binds to.

1. The firewall drops it. synnet's input chain accepts loopback, established/related, ICMP, and sources in 10/8, 172.16/12, 192.168/16 (plus IPv6 ULA and link-local). Everything else hits the drop policy, so an unsolicited connection from a public address never arrives however the server is bound.

Warning

synnet --allow <ip> will not open it. Despite the name it only removes an address from the block set — it undoes a previous --block and opens nothing. --trust-if is DHCP and DNS on a gateway bridge, also not this. The verb that opens a port is --open:

sudo synnet --open tcp/5900 100.64.0.0/10   # e.g. a Tailscale mesh
synnet --status                             # shows what is open

With no CIDR the source is any, which means the internet if this machine is reachable from it — so it says so when you do that.

2. The certificate does not carry the address you would dial. It is built from the addresses this machine holds, so a public IP in front of a port forward — or the dynamic-DNS name that resolves to it — is not in it and cannot be. A viewer validates against what it dialled, so it fails with IP address mismatch or Hostname mismatch. Name it:

syn-remote names add myhouse.duckdns.org
syn-remote names                            # what it vouches for

That re-issues the certificate, so every client that already trusted this machine has to syn-remote trust <name> --renew.

Which VPN

WireGuard on a private range (10.x, 192.168.x) Works as shipped. Inbound packets carry a private source, so synnet already accepts them, and the tunnel address is picked up by the certificate — run syn-remote trust <name> --renew on the client once the interface exists.
Tailscale Needs one rule. Its 100.64.0.0/10 is not a private range, so the tunnel establishes outbound and then every packet inside it is dropped, with nothing in any log mentioning the firewall. sudo synnet --open tcp/5900 100.64.0.0/10.
An SSH tunnel from outside Same problem one layer down — inbound SSH from a public address is dropped too. It only helps from on-LAN, or over a VPN that already works.

Who may connect

The connection always carries TLS: wayvnc's enable_auth requires a certificate, a key and a password together, so there is no password-without-encryption — which is the right way round, given VNC's own authentication is DES with an eight-character key. The certificate is self-signed, made once, and lives in ~/.config/syn-remote/.

A generated password (default) Twenty characters from /dev/urandom. syn-remote password prints it, syn-remote password new rolls it.
Your account password syn-remote auth pam — the same three-try lockout as any other login on the machine.

Reaching another machine

The other half of the package: syn-remote-gui, or the same thing from a terminal. A connection is saved once and opened by name.

syn-remote add desktop 192.168.1.50:5900 <user>
syn-remote trust desktop     # check the certificate — once, before the first connection
syn-remote saved desktop set # remember the password (optional)
syn-remote connect desktop

Important

The certificate has to be checked before the first connection, and nothing else will tell you so. wayvnc offers exactly one security type this viewer speaks — VeNCrypt X509Plain — so the server's certificate is the first thing in the exchange. Until it has been trusted, the TLS session comes up and is dropped, and there is no error on the machine you are sitting at. The only trace is on the server:

ERROR: ../neatvnc/src/server.c: 2374: Client handshake timed out

which reads like a firewall and is not one. syn-remote trust <name> shows the fingerprint and waits for a yes; compare it against syn-remote fingerprint on the machine you are dialling before answering.

The window's Check the certificate button does the same thing in a terminal, because the fingerprint is a question for a person. A connection that has not been checked says so in the list rather than failing quietly.

A re-issued certificate — which happens by itself when the server's address moves — is correctly refused by everything that trusted the old one. Accept the new one with syn-remote trust <name> --renew.


Waking the machine itself

Three different problems wear the same word:

  1. The screen is asleep. Handled above — the wrapper wakes it when somebody connects.
  2. The machine is suspended. It has no server, no port and nothing listening, so nothing can be woken by connecting to it. That needs a magic packet, and both ends are below.
  3. Nobody has logged in. There is no compositor, so there is nothing to capture. A machine meant to be reached this way wants autologin.

On the machine that sleeps

syn-remote wakeable          # what it is now
syn-remote wakeable on       # arm the wired card for a magic packet

wakeable reports the interface, its hardware address, whether the card can be woken at all, whether it is armed right now, and whether it will still be armed after the next reboot. Those last two are separate questions on purpose: arming the card and remembering to arm it again are two different things, and a machine that is armed today and forgotten at the next boot reads as working right up until the reboot nobody connects to it after.

So wakeable on writes both. NetworkManager remembers the setting and re-applies it every time the connection is activated — a reboot, a replugged cable, a driver that clears the flag on link-down. A small helper applies it immediately, without activating anything, because activating the connection you are reaching the machine over drops the link underneath you.

Note

Reading the flag needs privilege, not just writing it: the same kernel call can return a card's SecureOn password, so it is guarded like a write. At the machine's own keyboard this is granted without a password; over SSH it is not, which is deliberate — reaching in from the network to change whether a machine can be woken from the network asks for an administrator.

On the machine you are sitting at

syn-remote wake desktop      # send the packet and wait for it
syn-remote connect desktop   # does that by itself if it is not answering

The hardware address is read off the network when the connection is saved, so syn-remote add while the other machine is still awake needs nothing else. --mac gives it explicitly for a machine that was already asleep when it was saved. Two places on that machine print the address to use: syn-remote wakeable, and Settings ▸ Network, which lists a hardware address for every interface beside the addresses it holds — see The Network pane.

Nothing acknowledges a magic packet — there is no reply, and no error — so wake watches the port instead and reports what actually happened. connect does the same before it opens anything, rather than handing a viewer a machine that is not there.

Important

A magic packet is a broadcast, and a broadcast does not cross a router. The machine sending it has to be on the same network as the machine being woken. Reaching a sleeping machine from outside needs something on that network to send the packet — the VPN endpoint above, or a router that can be asked to send one. And a machine that was shut down rather than suspended needs Wake-on-LAN enabled in its own firmware setup as well; the operating system is not running to arm anything.

syn-remote on starts the server at every login, and it waits for the desktop rather than racing it — the unit is started before the compositor exists, so its first seconds are spent waiting for a session that is still coming up. syn-remote status says Server stopped while it waits, and the journal says what it is waiting for.


What it is not

syn-remote owns no part of the VNC protocol, the encryption or the credentials — wayvnc does all of it. What the wrapper adds is the screen wake, the idle inhibitor, the loopback default, the generated certificate and password, and one place to read the state from.

See also: The-Desktop, Settings, Commands.

Clone this wiki locally