ExtremeDullard

joined 2 years ago
MODERATOR OF
[–] ExtremeDullard@lemmy.sdf.org 1 points 2 hours ago* (last edited 1 hour ago)

And here's a version that uses pkexec instead of sudo, if you want to run the script without a terminal and enter your login in a login popup (using lxpolkit for example):

#!/bin/sh

# Are we running as a normal user?
if [ $(whoami) != root ]; then

  # Make sure we run in Wayland
  if [ ! "${WAYLAND_DISPLAY}" ]; then
    echo "$0 must be run in a Wayland environment"
    exit
  fi
  
  # Make sure we run in Sway
  if [ ! "${SWAYSOCK}" ]; then
    echo "$0 must be run in a Sway session"
    exit
  fi
  
  # Get the nested session's user as first argument
  if [ ! "$1" ]; then
    echo "Usage: $0 username"
    exit
  fi
  NUSER=$1
  
  # Make sure the nested session's user exists
  if ! grep -q "^${NUSER}:" /etc/passwd; then
    echo "User ${NUSER} doesn't exist"
    exit
  fi
  
  # Make sure filterway is installed
  if ! which -s filterway; then
    echo "filterway not found in the PATH."
    echo "Please install if from https://github.com/andrewbaxter/filterway"
    exit
  fi
  
  # Get a unique ID for this nested session
  UUID=$(uuidgen)
  
  # Figure out where our Wayland socket is and make sure it exists
  if echo ${WAYLAND_DISPLAY} | grep -q "^/"; then 
    RSOCKPATH=${WAYLAND_DISPLAY}
  else
    RSOCKPATH=${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}
  fi
  if ! [ -S ${RSOCKPATH} ]; then 
    echo "Socket file ${RSOCKPATH} for this Wayland display \"${WAYLAND_DISPLAY}\" doesn't exist!?"
    echo "Giving up..."
    exit
  fi
  
  # Unique nested session's Wayland display name
  NWDISPLAY=wayland-nested-${UUID}
  
  # Unique filespec for the nested session's Wayland socket
  NSOCKPATH=/tmp/${NWDISPLAY}
  
  # Unique filespec for the nested Sway socket
  NSWAYSOCK=/tmp/sway-nested-ipc.${NUSER}.${UUID}.sock
  
  # Run filterway in the background to expose our private Wayland socket in ${XDG_RUNTIME_DIR} (which is most likely a tmpfs-mounted directory that can't be shared outside without compromising the private $(XDG_RUNTIME_DIR}) and to rename the nested session's app ID
  rm -f ${NSOCKPATH}
  filterway --upstream ${RSOCKPATH} --downstream ${NSOCKPATH} --app-id "Nested Sway - ${NUSER} ($UUID)" &
  FILTERWAY_PID=$!
  
  # Wait until filterway has created the socket and associated lock files for the nested session
  RETRY=3
  while [ ${RETRY} -gt 0 ] && ! ( [ -S ${NSOCKPATH} ] && [ -f ${NSOCKPATH}.lock ] ); do
    sleep 1
    RETRY=$((RETRY-1))
  done
  
  # If filterway somehow didn't start, try to kill it and clean up its files for good measure
  if [ ${RETRY} = 0 ]; then
    kill ${FILTERWAY_PID}
    rm -f ${NSOCKPATH} ${NSOCKPATH}.lock
  fi
  
  # Fix up the permissions of the socket and associated lock files for the nested session so it's only accessible to the owner
  chmod 600 ${NSOCKPATH} ${NSOCKPATH}.lock
  
  # Re-run ourselves as root to perform the rest of the operations to spawn the nested session
  VARFILE=${XDG_RUNTIME_DIR}/$(echo $UUID | cut -d- -f1).nested_sway_vars

  echo "NUSER=${NUSER}" > ${VARFILE}
  echo "NWDISPLAY=${NWDISPLAY}" >> ${VARFILE}
  echo "UUID=${UUID}" >> ${VARFILE}
  echo "NSOCKPATH=${NSOCKPATH}" >> ${VARFILE}
  echo "SWAYSOCK=${SWAYSOCK}" >> ${VARFILE}
  echo "NSWAYSOCK=${NSWAYSOCK}" >> ${VARFILE}
  echo "FILTERWAY_PID=${FILTERWAY_PID}" >> ${VARFILE}

  pkexec $0 ${VARFILE} || rm ${VARFILE}

# We run as root
else

  # Source the file containing the variables we need created by the non-root version of ourselves
  if [ ! "$1" ]; then
    echo "$0 (running as root): missing variable file needed"
    exit
  fi
  VARFILE=$1
  . ${VARFILE}

  # Check that we were passed all the variables we need and assign them
  if ! [ "$NUSER" ]; then
    echo "$0 (running as root): missing NUSER variable"
    exit
  fi
  if ! [ "$NWDISPLAY" ]; then
    echo "$0 (running as root): missing NWDISPLAY variable"
    exit
  fi
  if ! [ "$UUID" ]; then
    echo "$0 (running as root): missing UUID variable"
    exit
  fi
  if ! [ "$NSOCKPATH" ]; then
    echo "$0 (running as root): missing NSOCKPATH variable"
    exit
  fi
  if ! [ "$SWAYSOCK" ]; then
    echo "$0 (running as root): missing SWAYSOCK variable"
    exit
  fi
  if ! [ "$NSWAYSOCK" ]; then
    echo "$0 (running as root): missing NSWAYSOCK variable"
    exit
  fi
  if ! [ "$FILTERWAY_PID" ]; then
    echo "$0 (running as root): missing FILTERWAY_PID variable"
    exit
  fi

  # Remove the variables file
  rm ${VARFILE}

  # Give the socket and associated lock files to the nested session's user
  chown ${NUSER}: ${NSOCKPATH} ${NSOCKPATH}.lock
  
  # Remove stale symlinks then start Sway as that user in a new session in the background
  systemd-run --pipe --machine ${NUSER}@ --setenv=WAYLAND_DISPLAY=${NWDISPLAY} --setenv=NSOCKPATH=${NSOCKPATH} --setenv=SWAYSOCK=${NSWAYSOCK} --user /bin/sh -c '[ "${XDG_RUNTIME_DIR}" ] && (find ${XDG_RUNTIME_DIR} -maxdepth 1 -name "wayland-nested-*" -xtype l -exec rm -f {} \; || true) && rm -f ${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY} && ln -s ${NSOCKPATH} ${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY} && unset NSOCKPATH && sway' &

  # Wait for the Sway container to appear within 3 seconds after starting Sway, then wait for it to disappear for more than 5 seconds afterwards
  COUNTDOWN=3
  while [ ${COUNTDOWN} -gt 0 ]; do
    if SWAYSOCK=${SWAYSOCK} swaymsg -t get_tree | grep -q "app_id.*${UUID}"; then
      COUNTDOWN=5
    fi
    sleep 1
    COUNTDOWN=$((COUNTDOWN-1))
  done
  
  # Stop the nested Sway
  SWAYSOCK=${NSWAYSOCK} swaymsg exit

  # Kill filterway
  kill ${FILTERWAY_PID}

  # Remove the filterway socket and socket lock files
  rm -f ${NUSER}: ${NSOCKPATH} ${NSOCKPATH}.lock

fi

It's a bit more complicated because pkexec can't run a shell script directly, so the script has to re-run itself as root and pass itself the proper variables. But essentially it's the same thing.

With this version, you can define a desktop file to open the desktop of a particular user in your favorite application launcher without opening a terminal first.

For example, if you create /.local/share/applications/test-desktop.desktop with the following content (or similar):

[Desktop Entry]
Name=test desktop
Exec=nest_sway.sh test
Icon=gnome-remote-desktop
Type=Application
Keywords=sway;nest;nested;

then you'll be able to open the desktop of user test in a nested Sway from the application launcher

 

If you come from i3, you might be missing Xephyr or Xnest-like functionalities in Sway - that is, the ability to run another desktop session as another user inside your current desktop.

In i3, I log into my test desktops all the time without leaving my main desktop, and that's something I really miss in Sway / Wayland. So I spent some time putting a script together to do that seamlessly in Sway too. You may find it useful.

In fairness, Sway - or more precisely wlroots - can already run nested natively without any modification. You can test that by opening a terminal and typing sway in it: you'll get a second, identical desktop inside your current one.

The problems come when you want to run another user's desktop within yours, for the following reasons:

  1. Wayland makes the incredibly restrictive assumption that the Wayland compositor and clients always run as the same user, and therefore puts the Wayland socket in the user's XDG_RUNTIME_DIR (usually /run/user/<userid>/).

    That's a problem if you want a Wayland application running as another user to connect to that Wayland socket, because other users can't access your XDG_RUNTIME_DIR, and you really don't want to open it up to other users just to be able to access the socket because it's full of sensitive files pertaining to your running session.

    Moreover, since XDG_RUNTIME_DIR is usually a mounted tmpfs, you can't symlink the socket outside the directory either because sockets can't be symlinked across filesystems in Linux.

    In other words, again, Wayland makes it extra difficult to do something simple for no good reason.

  2. Sway requires a full login environment - and particularly XDG_RUNTIME_DIR - to be set in the environment, which usually implies that it should also be setup and mounted in /run/user.

    Unfortunately, you can't just sudo into the account you want to run your nested Sway desktop as and start Sway because PAM explicitely doesn't set XDG when su'ing or sudo'ing, and doing it manually is a recipe for problems.

To solve 1., we use a clever piece of software called filterway, which conveniently solves two problems:

  • It acts as a sort of gateway: it connects to a Wayland socket on one side, creates its own socket on the other side and links the two. This functionality is used to expose the primary Wayland socket securely without compromising XDG_RUNTIME_DIR.

  • It replaces the app ID of the top Wayland client that connects to it - which is really its primary party trick. In this use case, that's useful to track the state of the nested Sway session in the primary session's tree.

There is no package for filterway so you have to clone the Github repo, build the binary and install it somewhere in your PATH. Fortunately, it's just a small utility so building it is really simple.

To solve 2., we use systemd-run to setup the target user's environment as if it was a full login, then run Sway with the correct setup to connect to the primary Wayland display's socket.

The following script ties everything together: it starts filterway, starts Sway as the other user, then takes care of stopping Sway and filterway and cleaning things up when the session is closed. Alll you need is to add your name to the sudoers.

#!/bin/sh

# Make sure we run in Wayland
if [ ! "${WAYLAND_DISPLAY}" ]; then
  echo "$0 must be run in a Wayland environment"
  exit
fi

# Make sure we run in Sway
if [ ! "${SWAYSOCK}" ]; then
  echo "$0 must be run in a Sway session"
  exit
fi

# Pass the nested session's user as first argument
if [ ! "$1" ]; then
  echo "Usage: $0 username"
  exit
fi
NUSER=$1

# Make sure the nested session's user exists
if ! grep -q "^${NUSER}:" /etc/passwd; then
  echo "User ${NUSER} doesn't exist"
  exit
fi

# Make sure filterway is installed
if ! which -s filterway; then
  echo "filterway not found in the PATH."
  echo "Please install if from https://github.com/andrewbaxter/filterway"
  exit
fi

# Get a unique ID for this nested session
UUID=$(uuidgen)

# Figure out where our Wayland socket is and make sure it exists
if echo ${WAYLAND_DISPLAY} | grep -q "^/"; then 
  RSOCKPATH=${WAYLAND_DISPLAY}
else
  RSOCKPATH=${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}
fi
if ! [ -S ${RSOCKPATH} ]; then 
  echo "Socket file ${RSOCKPATH} for this Wayland display \"${WAYLAND_DISPLAY}\" doesn't exist!?"
  echo "Giving up..."
  exit
fi

# Unique nested session's Wayland display name
NWDISPLAY=wayland-nested-${UUID}

# Unique filespec for the nested session's Wayland socket
NSOCKPATH=/tmp/${NWDISPLAY}

# Unique filespec for the nested Sway socket
NSWAYSOCK=/tmp/sway-nested-ipc.${NUSER}.${UUID}.sock

# Run filterway in the background to expose our private Wayland socket in ${XDG_RUNTIME_DIR} (which is most likely a tmpfs-mounted directory that can't be shared outside without compromising the private $(XDG_RUNTIME_DIR}) and to rename the nested session's app ID
rm -f ${NSOCKPATH}
filterway --upstream ${RSOCKPATH} --downstream ${NSOCKPATH} --app-id "Nested Sway - ${NUSER} ($UUID)" &
FILTERWAY_PID=$!

# Wait until filterway has created the socket and associated lock files for the nested session
RETRY=3
while [ ${RETRY} -gt 0 ] && ! ( [ -S ${NSOCKPATH} ] && [ -f ${NSOCKPATH}.lock ] ); do
  sleep 1
  RETRY=$((RETRY-1))
done

# If filterway somehow didn't start, try to kill it and clean up its files for good measure
if [ ${RETRY} = 0 ]; then
  kill ${FILTERWAY_PID}
  rm -f ${NSOCKPATH} ${NSOCKPATH}.lock
fi

# Fix up the permissions of the socket and associated lock files for the nested session so it's only accessible to the owner
chmod 600 ${NSOCKPATH} ${NSOCKPATH}.lock

# Become root
sudo -s -- << EOF

  # Give the socket and associated lock files to the nested session's user
  chown ${NUSER}: ${NSOCKPATH} ${NSOCKPATH}.lock

  # Remove stale symlinks then start Sway as that user in a new session in the background
  systemd-run --pipe --machine ${NUSER}@ --setenv=WAYLAND_DISPLAY=${NWDISPLAY} --setenv=SWAYSOCK=${NSWAYSOCK} --user /bin/sh -c '[ "\${XDG_RUNTIME_DIR}" ] && (find \${XDG_RUNTIME_DIR} -maxdepth 1 -name "wayland-nested-*" -xtype l -exec rm -f {} \; || true) && rm -f \${XDG_RUNTIME_DIR}/${NWDISPLAY} && ln -s ${NSOCKPATH} \${XDG_RUNTIME_DIR}/${NWDISPLAY} && sway' &

  # Wait for the Sway container to appear within 3 seconds after starting Sway, then wait for it to disappear for more than 5 seconds afterwards
  export SWAYSOCK=${SWAYSOCK}
  COUNTDOWN=3
  while [ \${COUNTDOWN} -gt 0 ]; do
    if swaymsg -t get_tree | grep -q 'app_id.*${UUID}'; then
      COUNTDOWN=5
    fi
    sleep 1
    COUNTDOWN=\$((COUNTDOWN-1))
  done

  # Stop the nested Sway
  SWAYSOCK=${NSWAYSOCK} swaymsg exit

  # Kill filterway
  kill ${FILTERWAY_PID}

  # Remove the filterway socket and socket lock files
  rm -f ${NUSER}: ${NSOCKPATH} ${NSOCKPATH}.lock

EOF

I called it nest_sway.sh and it lives in my ~/scripts directory, which is in my PATH. Whenever I want to start a desktop as another user within my desktop, I simply type

$ nest_sway.sh <username>

and hey-presto, the desktop appears. Just like with Xephy.

[–] ExtremeDullard@lemmy.sdf.org 2 points 20 hours ago (2 children)

I think what they were all aiming for was to be left alone by the US as much as possible.

[–] ExtremeDullard@lemmy.sdf.org 2 points 21 hours ago* (last edited 21 hours ago) (4 children)

To dodge Trump’s tariffs and wrath, five African presidents played the role of loyal colonial subject, and left their dignity behind.

They didn't. They indulged the difficult child for the good of their respective countries, but nobody other than Trump believes for one second they have anything but contempt for the child.

In short: they did what was best for their countries since the only price was a little pathetic theater at the White House. Their dignity and reputation is quite safe.

[–] ExtremeDullard@lemmy.sdf.org 2 points 21 hours ago* (last edited 21 hours ago)

The real question is: why is the US involved in any of this - or indeed any war anywhere, beyond applying international sanctions against rogue countries along with other nations at the behest of the UN.

Fuck the US's self-assigned role as the world's police. Just like the real police, it's doing more harm than good.

[–] ExtremeDullard@lemmy.sdf.org 1 points 21 hours ago

Small instances probably aren't for you

I'm sorry but... no.

Look, I'm a child of the 70's, I know what shite internet feels like and I'm a patient man. Hell, half of the reason why I stick to SDF is exactly because I'm patient (the other half being because SDF defederates almost no other instances and I appreciate that).

But I'm running a BBS with 32 lines and quite a few users (yes, old-stylee, with modems) and also a few Echolink repeaters for hams, and I provide better service and better uptime than SDF most of the time. And it's just me, myself and I with little time to spare after work.

I'm glad you're satisfied with SDF. My bar is a bit higher than yours apparently, yet goodness knows I'm not demanding...

[–] ExtremeDullard@lemmy.sdf.org 2 points 21 hours ago* (last edited 21 hours ago)

The millionaires I'm talking about are the millionaires from the eighties who partied with Epstein and all knew who he was and what he was doing. Hell, his fucking private jet was nicknamed the Lolita Express...

A million in the eighties was a lot of money. It got you 4k of snow tops.

Does this public-private partnership truly benefit the public?

It never does: whenever public services are delegated to private companies on the promise that they'll run them better for cheaper, it holds true for 2 or 3 years, and then the service degrades and becomes more expensive because the shareholders are greedy and they know they've captured the market.

Case in point: private highways in France that cost you a fortune, railway services in the UK that are always late or cancelled, healthcare in Finland which is even worse than the UK's despite being a Scandinavian country, and of course almost everything in the US.

[–] ExtremeDullard@lemmy.sdf.org 15 points 1 day ago (2 children)

Yeah, I really feel for those poor innocent millionaires who associated with a known pedo totally in good faith.

People who voted for this shit, knowing full well who Trump was and what he did, lost the right to open their trap about the consequences the minute they cast their ballots.

Fuck you funny man.

[–] ExtremeDullard@lemmy.sdf.org 1 points 1 day ago* (last edited 1 day ago) (2 children)

I made a donation once, with the idea of making one every year, because I believe in paying for the things I use, and particularly small-time, old-style services like SDF.

But the plain and sad reality is, most of the things I DON'T pay for work much better than SDF services.

So yes, it truly was money poorly spent. It wasn't much money and it didn't make a dent in my quality of life in any way, but that's just what it was - money poorly spent.

My one donation will remain a single donation until SDF services improve to the point when I can convince myself that the occasional slowness and downtime are reasonable for a small gig like SDF. Sadly, it's not even up to that standard, and has never been in the 2 years since I've joined: it's more slowness and downtime than it is working normally.

[–] ExtremeDullard@lemmy.sdf.org 2 points 1 day ago* (last edited 1 day ago) (4 children)

SDF had been nothing short of terrible for me for the 2 years I've been using it. It's easily in the top spot for worst money I've ever spent on anything. And I'm not talking about just Lemmy...

The only reason I'm still here is inertia. But I have a shadow account on Sopuli and I'm getting awfully close to switching for good.

[–] ExtremeDullard@lemmy.sdf.org 123 points 1 day ago (37 children)

It's different this time around.

The previous attempts were about freeing themselves from an abusive unprincipled data-hungry big data monopoly,

This attempt is about freeing themselves from an abusive unprincipled data-hungry big data monopoly operating in a fascist country and in cahoots with the regime.

I reckon it's serious this time.

 

Because of course it did...

 

Great news for those of us who would rather keep their shoes on for practical or social reasons.

 

What to expect if you want to proudly display your fascist lifestyle choices on your cellphone screen.

Or perhaps go through airport security faster? Because surely, nothing tells the TSA goons to leave you alone like your confiscated phone showing "Trump 5G" in the status bar.

 

That's how our Dear Leader's economic nonsense translates in people's actual lives. If you watch Ian Davis' videos, you can tell he's furious under his usual friendly and polite demeanor. I would be too.

Liberation Day indeed...

5
submitted 1 week ago* (last edited 1 week ago) by ExtremeDullard@lemmy.sdf.org to c/swaywm@lemmy.ml
 

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 a screen-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.

 

Don´t forget to shout "Tiki!", not "Help!", or the turtle won´t come.

view more: next ›