The state of remote working with Wayland is, well, lackluster to put it kindly. And with Sway, it's quite abysmal.
Here is my solution to remote my Sway desktop at work and make it persistent so it survives network outages. This is not the perfect solution, probably, but it works for me.
A few prerequisites
-
You need a dedicated remote account. It's generally a good idea regardless of whether you use Wayland or X11 to have a main account and a secondary remote account if you don't want to work with the same desktop locally and remotely.
The reason is, your local desktop settings can differ significantly from the remote desktop settings (for instance, if you work with 2 high-res monitors locally but on a small laptop screen remotely) so a unique set of settings may not work well in both cases.
Also, unless you log out of the local and remote sessions religiously after you're done, you're likely to run both sessions at the same time at some point. If you do, you may run more than one instance of the same utilities, which tend to overwrite one another's temporary files, caches and such, and generally creating a mess.
So it's much cleaner to have a separate main account and remote account, with adequate permissions to access files in one from the other, and run two separate desktops.
-
To remote a Sway desktop, you'll use VNC. It's not great but that's the only option at the moment.
-
My solution below is reasonably secure if you're the only user on your machine, or if the other local users aren't adversarial.
If they are, you'll use a Unix socket or enable authentication in Wayvnc for extra security (see Final note below), which works fine, but is incompatible with Remmina. And I happen to like Remmina 🙂 So I didn't. I'm a low-risk target but do what works best for you.
-
If there are more than one user doing remote work on the machine, each one will need to be assigned their own VNC port. Again, it's not great, but Wayland makes doing anything else with the existing tools exceedingly painful.
Setup
The idea is to:
- SSH into the remote machine and create a tunnel from the remote machine's VNC port corresponding to the particular remote user (if you're the only one, 5900 most likely) to a local port on your local machine.
- Upon connection through SSH, start Sway headless in a persistent manner (meaning the Sway session doesn't get killed if the ssh connection dies).
- Make Sway start Wayvnc to expose the headless display through VNC.
- On the local machine, connect to the local end of the SSH tunnel to connect to the remote Wayvnc server.
Required software packages
On the remote machine:
tmux
: this is ascreen
-like terminal multiplexer that allows sessions to remain open even if the terminal underneath disappears.sway
obviously...wayvnc
: that's the Wayland VNC server
On the local machine:
ssh
: the SSH client- Any VNC viewer
Configuration of the remote machine
- Add a user called
<your_main_username>-remote
for example.
In the remote user's account, configure:
-
sway
: Put the following lines in.config/sway/config
:# Start the VNC server: set the resolution you want (fixed) output HEADLESS-1 mode 1920x1080 # Start the VNC server exec cd $HOME/.config/wayvnc && /usr/bin/wayvnc -C $HOME/.config/wayvnc/config
-
wayvnc
: Put the following lines in.config/wayvnc/config
address=localhost port=5900
If you have more than one user, allocate a unique port per remote user
-
Create a
~/scripts
directory in your home directory (that's where I put my scripts. If you want to do something else, it's up to you, but the following assumes the relevant scripts are located in~/scripts
) -
Create
~/scripts/sway_headless.sh
with the following content, to start Sway headless:#!/bin/sh export WLR_BACKENDS=headless export WLR_LIBINPUT_NO_DEVICES=1 /usr/bin/sway
-
Create a
start_persistent_sway_headless.sh
script to start Sway and Wayvnc in a background tmux session if it doesn't exist already, and only exit when the Wayvnc server is ready to accept connections:#!/bin/sh # Pass the -w argument to this script to wait until the VNC server stops before exiting (for interactive SSH sessions, to keep the tunnel open) # If not already running, start Sway headless in a tmux session and immediately detach from it tmux has-session -t sway 2> /dev/null || tmux new-session -d -s sway $HOME/scripts/sway_headless.sh # Source the wayvnc config file to get the address and port it's listening on . $HOME/.config/wayvnc/config # Wait until the VNC server is up retry=5 while [ ${retry} -gt 0 ] && ! nc -z ${address} ${port} 2> /dev/null; do sleep 1 retry=$((retry-1)) done # Wait until the VNC server goes back down if requested if [ "$1" = "-w" ]; then while nc -z ${address} ${port} 2> /dev/null; do sleep 1 done fi
-
Optionally, create a
stop_persistent_sway_headless.sh
script to stop the background tmux session running Sway and Wayvnc. It's not strictly needed but you might find it useful if you want to stop Sway manually:#!/bin/sh tmux kill-session -t sway 2> /dev/null
Connecting from the local machine
Manually:
-
To start Sway and Wayvnc on the remote machine, and create the VNC tunnel manually with SSH, do this in one terminal (the local end of the tunnel is port 35900 here):
$ ssh -L35900:localhost:5900 <your_main_username>-remote@<remote_machine> "~/scripts/start_persistent_sway_headless.sh -w"
-
Then to connect to the remote machine through the SSH tunnel manually, do this in another terminal:
$ vncviewer localhost:35900
With Remmina:
Final note
This setup is acceptable if you're the only user on the machine, or the other users are friendly folks, and your machine is secured!
The reason for this is, when Wayvnc is running without authentication, malevolent local users can freely connect to your session and take over your remote desktop.
There are two ways around that, but neither is compatible with Remmina.
-
Use a Unix socket instead of a TCP port to serve up VNC on the remote machine. To do this:
-
Remove
~/.config/wayvnc
and replace the Wayvnc startup line in the remote user's Sway config file with:exec /usr/bin/wayvnc -u $XDG_RUNTIME_DIR/wayvnc
-
Replace the content of
~/scripts/start_persistent_sway_headless.sh
with:#!/bin/sh # Pass the -w argument to this script to wait until the VNC server stops before exiting (for interactive SSH sessions, to keep the tunnel open) # If not already running, start Sway headless in a tmux session and immediately detach from it tmux has-session -t sway 2> /dev/null || tmux new-session -d -s sway $HOME/scripts/sway_headless.sh # Wait until the VNC server is up retry=5 while [ ${retry} -gt 0 ] && ! [ -S ${XDG_RUNTIME_DIR}/wayvnc ] 2> /dev/null; do sleep 1 retry=$((retry-1)) done # Wait until the VNC server goes back down if requested if [ "$1" = "-w" ]; then while [ -S ${XDG_RUNTIME_DIR}/wayvnc ] 2> /dev/null; do sleep 1 done fi
-
Then to start the SSH tunnel manually to tunnel the remote Unix socket to the local TCP port, do this:
$ ssh -L35900:/run/user/<remote user ID>/wayvnc <your_main_username>-remote@<remote_machine> "~/scripts/start_persistent_sway_headless.sh -w"
This is more secure because the socket file is only visible to your remote user on the remote machine, and not to other local users on the remote machine. Unfortunately Remmina doesn't know how to forward Unix sockets.
-
-
Enable TLS or AES authentication in
.config/wayvnc/config
as described here.Unfortunately, when authentication is enabled in Wayvnc, it's not possible to use just a username and password (which would be secure enough in a local context) and Remmina can't work with either forms of authentication offered by Wayvnc. Other VNC viewers like Tigervnc have no problem however.
Also, it means you have to enter your password again to log into VNC, so it's not great for automation.
