Remote X connection to Wayland on port 6000

I have an instrument with and embedded client that connects to an X server on port 6000 to display a screen.

I can get this to work with Xorg (with a hack) on Fedora 41.


$ sudo netstat -plnt |grep 6000
tcp        0      0 0.0.0.0:6000            0.0.0.0:*               LISTEN      2264/Xorg           
tcp6       0      0 :::6000                 :::*                    LISTEN      2264/Xorg

If I restart gdm with Wayland, there is nothing listening on port 6000.

Is it possible to have the wayland server listen on port 6000 for x clients (and if so how)?

Michael

If you have a client that only supports X Windows, it won’t be able to understand Wayland. You’re best option would be to have a separate system that only has Xorg installed for that use. XWayland allows X apps to run on Wayland, but I don’t know if it can act as a standalone X server.

No, Wayland has a compatibility layer with X (Xwayland), so X clients will work.

I made a connection between the port and the Xwayland socket and this does provide the equivalent functionality. I think Xwayland can probably do this by itself (I just cant seem to find the right option).

$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CONNECT:/tmp/.X11-unix/X0 &

Xorg has a command line option to listen to tcp port.
I am not sure where you need to configure the Xorg command line, but that would be the fix.

Just beware is a security risk and you would not want to do this where a host is on the public internet.

I know Xorg works (by editing the command line in /usr/bin/Xorg) but I was asking about the same functionality with Xwayland.

Did you try running /usr/bin/Xwayland -help?

Edit: It doesn’t look promising to me. You might have to stick with your workaround.

-listenfd fd           add given fd as a listen socket
-listen fd             deprecated, use "-listenfd" instead

Well -listenfd fd only listens on a socket, not the traditional IP port (6000).
I think the only way on Xwayland is using the socat solution.

It’s a little ironic that in disabling port 6000 for remote TCP connections (for vague security reasons) one must use a work around that ends up ignoring xhost protections (since the connection now appears to come from the local user).

1 Like

Oh boy, I think it’s possible but you need to do some tweaks by adding an override to gdm.

My notes are a little spread out so, so if you give me some time I can piece it together but i can’t test it at the moment.


in /etc/gdm/custom.conf set :

[daemon]
# Uncomment the line below to force the login screen to use Xorg
#WaylandEnable=True

Set the XWAYLAND environment variable export XWAYLAND_SOCKET=tcp

Then restart gdm sudo systemctl restart gdm

Add an override to /usr/lib/systemd/user/gnome-shell-wayland.service.d/override.conf :
note: You have to create the directory /usr/lib/systemd/user/gnome-shell-wayland.service.d/ then add the override file there. I have other notes here, but from a different implementation. These are old notes. . .

[Service]
Environment="XWAYLAND_ARGS=-listen tcp"

The restart the user service: systemctl --user restart gnome-shell-wayland.service

Check the connection sudo netstat -plnt | grep 6000

1 Like

I get an error when I try to restart that service …

# mkdir /usr/lib/systemd/user/gnome-shell-wayland.service.d/
# vi /usr/lib/systemd/user/gnome-shell-wayland.service.d/override.conf
# systemctl --user restart gnome-shell-wayland.service
Failed to restart gnome-shell-wayland.service: Unit gnome-shell-wayland.service not found.

In any case I can brute force Xwayland to use the -listen tcp option (using a script in place of /usr/bin/Xwayland) but it still doesn’t seem to open port 6000.

# pgrep -af Xwayland
53307 /usr/bin/Xwayland.bin -listen tcp +byteswappedclients :0 -rootless -noreset -accessx -core -auth /run/user/1000/.mutter-Xwaylandauth.DV5Y12 -listenfd 4 -listenfd 5 -displayfd 6 -initfd 7 +byteswappedclients -enable-ei-portal
# sudo netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:27500           0.0.0.0:*               LISTEN      3530/passimd        
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1292/sshd: /usr/sbi 
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      1295/dnsmasq        
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1287/cupsd          
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      781/systemd-resolve 
tcp6       0      0 ::1:631                 :::*                    LISTEN      1287/cupsd          
tcp6       0      0 :::22                   :::*                    LISTEN      1292/sshd: /usr/sbi 
tcp6       0      0 :::53                   :::*                    LISTEN      1295/dnsmasq        
tcp6       0      0 :::5355                 :::*                    LISTEN      781/systemd-resolve 
1 Like

Yup, Let me try to piece this together. I mentioned earlier, this was from an old implementation and it looks like I missed some parts here. So sorry for that.

sudo mkdir -p /etc/systemd/system/gdm.service.d/
sudo vi /etc/systemd/system/gdm.service.d/override.conf

Add this to the override.conf

[Service]
Environment="XWAYLAND_ARGS=-listen tcp"

Then go ahead and reload and restart :

sudo systemctl daemon-reload
sudo systemctl restart gdm

sudo netstat -plnt | grep 6000

Hope that helps.

Unfortunately not … same result no listen on port 6000

BTW: I don’t think gdm starts Xwayland. I think it’s the desktop (gnome-shell) that does this.

The security concerns are very real and bad for you if exploited.

Perhaps, but yes, you can remove the vulnerability by removing the functionality or keep the functionality available (off by default) and give the user the ability to decide if they can live with the risk in their specific environment. I think the latter is the more reasonable approach.

Just need to ask, have you tried to restart the machine and try it again? Outside of this could be to look into xhost ?

xhost will not change whether the process is listening on port 6000, just if the connection will succeed. (and I did open it up xhost +)

This note from Xwayland ignores -listen tcp (#817) · Issues · xorg / xserver · GitLab is a little discouraging …

In other words, “-listen” with a file descriptor is mutually exclusive with “-listen tcp” (for example), so this fix will not help with Wayland compositors that spawn Xwayland with a listen on a socket (like gnome-shell/mutter, weston or wlroots based compositors) - Adding “-listen tcp” to the Xwayland command line from those Wayland compositors will have no effect.

Hi Michael,

Give this a try:

  1. Copy /usr/bin/Xorg to ~.xserverc
  2. add “-listen tcp” to the end of each line containing “$@”

Example:

#!/usr/bin/sh
#
# Execute Xorg.wrap if it exists otherwise execute Xorg directly.
# This allows distros to put the suid wrapper in a separate package.

basedir="/usr/libexec"
if [ -x "$basedir"/Xorg.wrap ]; then
        exec "$basedir"/Xorg.wrap "$@" -listen tcp
else
        exec "$basedir"/Xorg "$@" -listen tcp
fi
  1. sudo set-default multi-user
  2. reboot and login
  3. startx

That’s the only way I got it to work as you described :slight_smile:

Yes that works for Xorg but doesn’t help with wayland

I’ve never attempted this, but the man page (man weston.ini) appears to indicate that you can create a ~/config/weston.ini file containing the following lines to direct Wayland to launch a custom wrapper script instead of Xwayland directly.

[xwayland]
path=/usr/local/bin/Xwayland

I think your custom wrapper could then, conditionally, replace -listenfd <fd> with -listen tcp (you would only do it if the app being launched is your instrument). It is still a hack, but since it avoids modifying /usr/bin/Xwayland directly, I think it will at least survive system updates.

Edit: Reading the paragraph above the earlier quoted one:

Just a final note, when using “-listenfd” (the new option) or “-listen” with a file descriptor (the newly deprecated old way), Xwayland will receive its sockets from the parent process and cannot create its own socket …

So even swapping the -listenfd <fd> with -listen tcp may not work (IIUC, the fd was created before Xwayland is called). If so, you’ll have to go back to your socat workaround. The wrapper script should still be able to scan the parameters to find what fd socat needs to forward to port 6000.

Are you saying replace wayland with weston ? (or can you have both at the same time?)

I’m not sure how this would work with normal X programs. Also, if I disable the socket in favor of the IP port will it break other things?

No, I might be misunderstanding the man pages, but it looks like that ~/.config/weston.ini file is a default for all wayland compositors unless the WESTON_CONFIG_FILE env is set.

Also, it looks like Xwayland will listen on multiple file descriptors, so I think you should be able to add another one and forward your port 6000 to that. For example, your /usr/local/bin/Xwayland wrapper might contain the following (untested):

#!/usr/bin/bash

fd=""
if [[ -n $XDG_RUNTIME_DIR ]]; then
	MYPORT=6000
	MYPIPE="$XDG_RUNTIME_DIR/xwayland-$MYPORT"
	socat PIPE:$MYPIPE TCP-LISTEN:$MYPORT,reuseaddr &
	sleep 1
	if [[ -p $MYPIPE ]]; then
		exec {fd}<>"$MYPIPE"
		flock -n "$fd" || fd=""
	fi
fi

/usr/bin/Ywayland "$@" ${fd:+-listenfd $fd}

Again, untested, but I think something along those lines might work.

Edit: I just tried to test this a bit, but I couldn’t get Wayland to read that ~/.config/weston.ini. Additionally, gnome-shell doesn’t have access to create /run/xwayland-6000. So I moved /usr/bin/Xwayland to /usr/bin/Ywayland and then put the above script at /usr/bin/Xwayland. It seems like it might be working now. It is, at least, listening on the port.

$ ss -anlp | grep ':6000'
tcp   LISTEN 0      5                                                    *:6000                   *:*    users:(("socat",pid=4752,fd=11))       

It might need additional logic to handle multiple instances. I’m not sure how that works.

HTH, and good luck! :slightly_smiling_face: