waypipe(1)

๐Ÿ’… waypipe(1) โ€” the girlies' guide to the waypipe manual ๐Ÿฆ‹

okay so real talk, this is waypipe(1) from the General Commands Manual section, and it's genuinely one of my fave little utilities so buckle up bestie ๐Ÿ’–


โœจ NAME โœจ

waypipe โ€” a transparent proxy for Wayland applications ๐Ÿซถ

like, it's giving "ssh -X but make it Wayland" and honestly? iconic.


๐ŸŒธ SYNOPSIS ๐ŸŒธ

waypipe [options...] ssh [ssh options] destination command...

waypipe [options...] client
waypipe [options...] server -- command...
waypipe bench
waypipe [--version] [-h, --help]

[options...] = [-c, --compress C] [-d, --debug] [-n, --no-gpu] [-o,
--oneshot] [-s, --socket S] [--display D] [--drm-node R] [--remote-node
R] [--ssh-bin R] [--remote-bin R] [--remote-socket S] [--login-shell]
[--threads T] [--title-prefix P] [--unlink-socket] [--video V] [--vsock]
[--secctx S] [--xwls]

no cap, that last bit is literally just the full option bundle spelled out so you don't have to go hunting ๐Ÿ‘‘


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so waypipe is a proxy for Wayland clients, and the whole goal is to support behavior like ssh -X. that's the vibe. that's the mission. ๐ŸŒˆ

if you take an ssh ... command and prefix it so it becomes waypipe ssh ..., it will automatically run waypipe both locally and remotely, and it'll modify the ssh command to set up forwarding between the two instances of waypipe. the remote instance acts like a Wayland compositor, so Wayland applications that are run remotely get displayed locally. literally magic, but make it networking โœจ

when you run it as waypipe client, it opens a socket (by default at /tmp/waypipe-client.sock) and connects to the local Wayland compositor, then forwards all the Wayland applications which were linked to it over the socket by a matching waypipe server instance. teamwork fr fr ๐Ÿซถ

when you run it as waypipe server, it runs the command that follows in its command line invocation, sets up its own Wayland compositor socket, and tries to connect to its matching waypipe client socket (by default /tmp/waypipe-server.sock), then tries to forward all the Wayland clients that connect to the fake compositor socket over to the matching waypipe client. it's giving matchmaker energy ๐Ÿ’…

and the waypipe bench mode? that one can be used to estimate which compression options produce the lowest latency, for a given connection bandwidth and number of threads. it tests two synthetic images โ€” one made to be roughly as compressible as images containing text, and one made to be roughly as compressible as images containing pictures. science but cute ๐Ÿงš


โญ OPTIONS โญ

  • -c C, --compress C โ€” selects the compression method applied to data transfers. options are none (for high-bandwidth networks), lz4 (intermediate), and zstd (slow connection). the default compression is lz4.โ€  you can pick the compression level by appending = followed by a number. so like, if C is zstd=7, waypipe will use level 7 Zstd compression. obsesssed ๐ŸŽ€
โ€  unless waypipe is built without LZ4 support, in which case the default compression will be none. yeah. gotta read the fine print bestie ๐Ÿ˜ญ
  • -d, --debug โ€” prints debug log messages. for when you're in your detective era ๐Ÿ”
  • -h, --help โ€” shows the help message and quits. the classic "wait what does this do again" move ๐Ÿ’€
  • -n, --no-gpu โ€” blocks protocols like wayland-drm and linux-dmabuf which require access to e.g. render nodes. no gpu shenanigans, we're keeping it simple ๐Ÿ™ˆ
  • -o, --oneshot โ€” only permits a single connection, and exits when it is closed. one and done, no strings attached ๐ŸŒธ
  • -s S, --socket S โ€” uses S as the path for the Unix socket. the default socket path for server mode is /tmp/waypipe-server.sock; for client mode it's /tmp/waypipe-client.sock; and in ssh mode, S gives the prefix used by both the client and the server for their socket paths. (the actual socket paths in ssh mode add a randomized suffix to S.) the default prefix in ssh mode is /tmp/waypipe. ๐Ÿฆ‹

when vsock is enabled, use S to specify a CID and a port number.

  • --version โ€” briefly describes Waypipe's version and the features it was built with, then quits. possible features: LZ4 compression support, ZSTD compression support, ability to transfer DMABUFs, video compression support. it's giving "tell me about yourself" interview question ๐Ÿ‘‘
  • --display D โ€” for server or ssh mode, provides WAYLAND_DISPLAY and lets waypipe configure its Wayland display socket to have a matching path. (if D is not an absolute path, the socket will be created in the folder given by the environment variable XDG_RUNTIME_DIR.) ๐Ÿ–ฅ๏ธ
  • --drm-node R โ€” specifies the path R to the drm device that this instance of waypipe should use and (in server mode) notify connecting applications about. ๐Ÿ’œ
  • --remote-node R โ€” in ssh mode, specifies the path R to the drm device that the remote instance of waypipe (running in server mode) should use. remote vibes only โœจ
  • --ssh-bin R โ€” in ssh mode, specifies the path R to the ssh binary, or its name if it is available in PATH. it defaults to ssh if this option isn't passed. the default is doing the work for you, as always ๐Ÿ’…
  • --remote-bin R โ€” in ssh mode, specifies the path R to the waypipe binary on the remote computer, or its name if it is available in PATH. it defaults to waypipe if this option isn't passed. ๐ŸŽ€
  • --remote-socket R โ€” in ssh mode, specifies the prefix used by the remote waypipe server for its socket path. this overrides the --socket option, on the server side only. read that twice bestie, server side only ๐Ÿ˜ค
  • --login-shell โ€” only for server mode; if no command is being run, open a login shell. cozy little fallback ๐Ÿš
  • --threads T โ€” sets the number of total threads (including the main thread) which a waypipe instance will create. these threads get used to parallelize compression operations. this flag is passed on to waypipe server when given to waypipe ssh. the flag also controls the thread count for waypipe bench. the default behavior (choosable by setting T to 0) is to use half as many threads as the computer has hardware threads available. parallelize slay ๐Ÿ”ฅ
  • --title-prefix P โ€” prepends P to any window titles specified using the XDG shell protocol. in ssh mode, the prefix is applied only on the client side. cute little nametag for your windows ๐Ÿท๏ธ
  • --unlink-socket โ€” only for server mode; on shutdown, unlink the Unix socket that waypipe connects to. cleaning up after yourself is main character behavior, periodt โœจ
  • --video V โ€” compresses specific DMABUF formats using a lossy video codec. opaque, 10-bit, and multiplanar formats, among others, are not supported. V is a comma separated list of options to control the video encoding. (for example: --video av1,hw.) later options supersede earlier ones. last one wins, sorry not sorry ๐Ÿ’…
    • none โ€” do not use video encoding.
    • h264 โ€” use H.264 encoded video.
    • vp9 โ€” use VP9 encoded video.
    • av1 โ€” use AV1 encoded video.
    • sw, swenc, swdec โ€” use software encoding or decoding, when available.
    • hw, hwenc, hwdec โ€” use hardware encoding or decoding, when available.
    • bpf=B โ€” set the target bit rate of the video encoder, in units of bits per frame. B can be written as an integer or with exponential notation; thus --video=bpf=7.5e5 is equivalent to --video=bpf=750000. math girlies rise ๐Ÿงฎ
  • --vsock โ€” use vsock instead of unix sockets. this is used when waypipe is running in virtual machines. with this option enabled, specify a CID and a port number in S. CID is only used in the server mode and can be omitted when connecting from a guest virtual machine to host. vm girlies, this one's for you ๐Ÿซถ
  • --secctx S โ€” enables the Wayland security context protocol (client or ssh modes). specify an application ID S that will be attached to the security context. security but make it labeled ๐ŸŽ€
  • --xwls โ€” use xwayland-satellite to run X clients under Wayland; for server or ssh modes. this binds X display sockets for the next available display number and sets the DISPLAY environment variable for the program run under waypipe server. this option will only work if xwayland-satellite is installed and in PATH. no satellite, no slay, that's the rule ๐Ÿ›ฐ๏ธ
  • --control C, --hwvideo, --allow-tiled โ€” options present in older versions of Waypipe that were removed. rip bozo, they're gone ๐Ÿ’€

๐ŸŒธ to be continued, bestieโ€ฆ ๐ŸŒธ

๐ŸŽ€ EXAMPLE ๐ŸŽ€

okay so the following waypipe ssh subcommand will attempt to run weston-flower on the server exserv, displaying the result on the local system. slay.

waypipe ssh user@exserv weston-flower

you can get basically the same behavior by explicitly running waypipe and ssh, like this:

waypipe --socket /tmp/socket-client client  &
ssh -R /tmp/socket-server:/tmp/socket-client user@exserv \
     waypipe --socket /tmp/socket-server server -- weston-flower
kill %1

waypipe may be run locally without an SSH connection by specifying matching socket paths. for example:

waypipe --socket /tmp/waypipe.sock client &
waypipe --socket /tmp/waypipe.sock server weston-simple-dmabuf-egl
kill %1
rm /tmp/waypipe.sock

using transports other than SSH is a bit more complicated. hereโ€™s a recipe with ncat to connect to remote from computer local:

$ waypipe --socket /tmp/waypipe-remote.sock client &
$ ncat --ssl -lk 12345 --sh-exec 'ncat -U /tmp/waypipe-remote.sock' &
$ ssh user@remote

> ncat -lkU /tmp/waypipe-local.sock --sh-exec 'ncat --ssl local 12345' &
> waypipe --display wayland-local \
            --socket /tmp/waypipe-local.sock server -- sleep inf &
> WAYLAND_DISPLAY=wayland-local application

given a certificate file, socat can also provide an encrypted connection (remove 'verify=0' to check certificates):

$ waypipe --socket /tmp/waypipe-remote.sock client &
$ socat openssl-listen:12345,reuseaddr,cert=certificate.pem,verify=0,fork \
    unix-connect:/tmp/waypipe-remote.sock
$ ssh user@remote

> socat unix-listen:/tmp/waypipe-local.sock,reuseaddr,fork \
    openssl-connect:local:12345,verify=0 &
> waypipe --socket /tmp/waypipe-local.sock server -- application

many applications require specific environment variables to use Wayland instead of X11. if ssh isn't configured to support loading ~/.ssh/environment, or to allow specific variables to be set with AcceptEnv/SetEnv, one can run waypipe ssh without a command (and thereby open a login shell), or use env to set the needed variables each time:

waypipe ssh user@host env XDG_SESSION_TYPE=wayland dolphin

in some cases, one may wish to set environment variables for the waypipe server process itself; the above trick with env will not do this, because the env process will be a child of waypipe server, not the other way around. instead, one can use ~/.ssh/environment, or use the --remote-bin option to change the remote Waypipe instance to a shell script that sets the environment before running the actual waypipe program. iykyk ๐Ÿ’…

๐Ÿงš Running waypipe in virtual machines ๐Ÿงš

when running waypipe in virtual machines on the same host it is possible to use vsock for efficient inter-vm communication. the following scenarios are supported:

  • running applications on host from guest.
host> waypipe --vsock -s 1234 client
guest> waypipe --vsock -s 1234 server weston-terminal
  • running applications in a guest virtual machine from host.
guest> waypipe --vsock -s 1234 client
host> waypipe --vsock -s 3:1234 server weston-terminal

in this example waypipe server connects to a virtual machine with CID 3 on port 1234.

  • running applications in a guest virtual machine from other guest virtual machines. when running both client and server in virtual machines it is possible to enable the VMADDR_FLAG_TO_HOST flag for sibling communication by prefixing the CID with an s:
guest> waypipe --vsock -s 1234 client
guest> waypipe --vsock -s s3:1234 server weston-terminal

in this case all packets will be routed to host where they can be forwarded to another virtual machine with a vhost-device-vsock device or some other utility. iconic โœจ


๐ŸŒˆ ENVIRONMENT ๐ŸŒˆ

when running as a server, by default WAYLAND_DISPLAY will be set for the invoked process.

if the --oneshot flag is set, waypipe will instead set WAYLAND_SOCKET and inherit an already connected socketpair file descriptor to the invoked (child) process. some programs open and close a Wayland connection repeatedly as part of their initialization, and will not work correctly with this flag. noted ๐Ÿซถ

โญ EXIT STATUS โญ

waypipe will exit with status code 1 if Waypipe has encountered an error; otherwise, it will return the exit status code of the command being run (or 128 plus the value of the terminating signal), if any.

๐Ÿ”ฅ SECURITY ๐Ÿ”ฅ

Waypipe does not provide any strong security guarantees, and connecting to untrusted servers is not recommended. it does not filter which Wayland protocols the compositor makes available to the client (with a few exceptions for protocols that require file descriptors which Waypipe cannot yet handle). for example, if a Wayland compositor gives all its clients access to a screenshot or lock-screen protocol, then proxied clients run under Waypipe can also make screenshots or lock the screen. lowkey important, bestie.

in general, applications are not well tested against malicious compositors, and compositors are not well tested against malicious clients. Waypipe can connect the two, and may blindly forward denial-of-service and other attacks.

Waypipe itself has plenty of unsafe Rust code and links to compression, graphics, and video libraries; both it and these libraries may have security bugs. some risk can be avoided by building Waypipe with DMABUF support turned off, or running Waypipe with the --no-gpu flag so that it does not expose graphics libraries.

waypipe ssh has no explicit protections against timing attacks; an observer to the resulting network traffic may, by studying the size and timing of packets, learn information about the user's interaction with a Wayland client proxied through waypipe ssh. for example: a lack of activity suggests the user is not currently using the application, while an intermittent stream of messages from the compositor to the client may indicate mouse movement (or maybe something else: the contents of the messages are protected by ssh.)

the memory used by Waypipe processes may, at a given time, include Wayland messages encoding user input, and the contents of current and recent frames drawn for application windows. swap should be encrypted to prevent this data from being leaked to disk. ๐Ÿ”’

๐Ÿ’€ BUGS ๐Ÿ’€

file bug reports at: https://gitlab.freedesktop.org/mstoeckl/waypipe/

๐Ÿ› Common issues ๐Ÿ›

some programs (gnome-terminal, firefox, kate, among others) have special mechanisms to ensure that only one process is running at a time. starting those programs under Waypipe while they are running under a different Wayland compositor may silently open a window or tab in the original instance of the program. such programs may have a command line argument to create a new instance.

the waypipe ssh command requires that the ssh executable supports Unix socket forwarding; this is only supported in OpenSSH since version 6.7 (from 2014), and may require specific configuration. other implementations of SSH may not be able to forward Unix sockets; see the EXAMPLE section above for how to use non-SSH transports.

๐Ÿ‘‘ SEE ALSO ๐Ÿ‘‘

weston(1), ssh(1), socat(1), ncat(1)


thatโ€™s the whole vibe check โ€” source/version is waypipe(1), dated 2026-10-22. bye bestie! ๐Ÿซถโœจ๐Ÿ’…

๐Ÿ“ฆ where this page comes from